ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[STM32F1] 麻烦大佬帮忙看下,十万火急

[复制链接]
499|13
 楼主 | 2018-5-6 18:17 | 显示全部楼层 |阅读模式
我想从stm32f103c8t6TIM3的通道2输出两个频率一样,占空比不同的PWM波,字符0代表的是1/4的波形,1代表3/4的波形,问题出现了这么几个:1、这个频率应该是800khz吧,我把占空比调到1/5的时候,他的频率变成80khz 2.从通道2里本来应该输出的波形是01010101这样的,就是一个1/4一个3/4,但是实际出来的是乱的,麻烦各位大神帮忙看下,是不是代码哪里错了,还是我的理解错了,刚开始搞单片机可能很多理解错误,急急急急急急
//函数声明
void TIM3_Config(u16 arr,u16 psc,u16 ccr2);
void TIM4_Interrupt_Init(u16 arr,u16 psc);


//=============================================================================
//文件名称:main
//功能概要:主函数
//参数说明:无
//函数返回:int
//=============================================================================
int main(void)
{
         // char buf[30] = {"01010101"};
         // u32 i = 0;
          //u32 num = 0;
          SystemInit();
          TIM3_Config(89,0,18);
          TIM4_Interrupt_Init(89,0);
   // TIM3_Config(89,0,18);
        //        NVIC_Configuration();
               

     while (1);
               
}



void TIM3_Config(u16 arr,u16 psc,u16 ccr2)
{
       
        //u16 ccr2 = 18;
        //结构体定义
        GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定义时钟初始化结构体
        TIM_OCInitTypeDef  TIM_OCInitStructure;//定义结构体
       
       
        //使能相关的东西
        //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
       
  //GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //全映射
  //GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //选择Timer3部分重映像   
        GPIO_InitStructure.GPIO_Pin = /*GPIO_Pin_6 |*/ GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    // 复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
       
        //初始化TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载寄存器的值,溢出大小,每1000个数产生一个更新事件
        TIM_TimeBaseStructure.TIM_Prescaler = psc; //TIMX预分频时钟的值 72 / (psc + 1) = 72M
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;        //时钟分割  时钟分频因子   0表示滤波器的频率和定时器的频率是一样的
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据以上功能对定时器进行初始化
       
        /*新加的中断的两句话*/
        TIM_ClearFlag(TIM3,TIM_FLAG_Update);          //中断标志位清零
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);       //允许更新中断
        //TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志函数
       
       
        //TIM1_OC2(设置2通道占空比)
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//选择定时器模式,TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
        TIM_OCInitStructure.TIM_Pulse = ccr2;  //设置跳变值,当计数器计数到这个值时,电平发生跳变  
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出比较极性高
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);//根据结构体信息进行初始化,使能通道2
        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能定时器TIM1在CCR2上的预装载值       
               
               
               
        //OC1(设置通道1占空比)       
        /*TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//选择定时器模式,TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
        //TIM_OCInitStructure.TIM_Pulse = CCR1;  //设置跳变值,当计数器计数到这个值时,电平发生跳变  
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性高
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);//根据结构体信息进行初始化,使能通道2
        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能定时器TIM1在CCR2上的预装载值               
        //TIM_CtrlPWMOutputs(TIM3,ENABLE);*/   
       

        TIM_ARRPreloadConfig(TIM3, ENABLE);  //这两句是可频率不变,改变占空比       
  TIM_Cmd(TIM3, ENABLE);  //使能定时器TIM3
}




void TIM4_Interrupt_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
       
        TIM_TimeBaseStructure.TIM_Period = arr;
        TIM_TimeBaseStructure.TIM_Prescaler = psc;
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;       
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
       
        TIM_ITConfig(TIM4,TIM_IT_Update | TIM_IT_Trigger,ENABLE);
        //TIM_ITConfig(TIM4,TIM_IT_Update ,ENABLE);
                /* Enable the TIM3 gloabal Interrupt*/
        NVIC_InitStructure.NVIC_IRQChannel =  TIM4_IRQn; //更新事件
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //相应优先级1级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
       
        TIM_Cmd(TIM4,ENABLE);

}

void TIM4_IRQHandler(void)
{  
    u32 i = 0;
                //u32 count = 0;
                u32 num = 0;
          char buf[30] = {"0101010101"};  
                //u32 pwmval;                       
               
    if (TIM_GetITStatus(TIM4,TIM_IT_Update | TIM_IT_Trigger) != RESET)
    {   
                        //TIM_ClearITPendingBit(TIM3, TIM_IT_CC2|TIM_IT_Update);
                       
            //capture = TIM_GetCapture2(TIM3);       
                             
                       
                        for(i = 0;buf[i] != '\0';i++)
                        {
                                  num = (int)(buf[i] - '0');
                                       
                                        switch(num)
                                        {
                                                case 0:
                                                  TIM3_Config(89,0,18);

                                                    //TIM_SetAutoreload(TIM3,89);//设置频率的函数
                                                        //        TIM_SetCompare2(TIM3,18);
                                                 break;
                                                         
                                                case 1:
                                                  TIM3_Config(89,0,23);
                                          //        TIM_SetAutoreload(TIM3,89);//设置频率的函数
             // TIM_SetCompare2(TIM3,68);
              break;
                                               
            default:
              break;                                               
                                        }       
                                       
                                        //count ++;
                 }               
                                TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
                        //TIM_SetCompare2(TIM3,68);
                }
               
               
}
| 2018-5-6 19:28 | 显示全部楼层
楼主参照ST官方演示代码修改一下就好了:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主 | 2018-5-7 09:02 | 显示全部楼层
sky.sun.zz 发表于 2018-5-6 19:28
楼主参照ST官方演示代码修改一下就好了:

好的,谢谢啦,我看下
| 2018-5-7 09:50 | 显示全部楼层
为什么要用Tim4
 楼主 | 2018-5-7 10:00 | 显示全部楼层
sdggg 发表于 2018-5-7 09:50
为什么要用Tim4

TIM4有什么问题吗,我是随便用的一个。stm32我也是才开始学习不久
| 2018-5-7 12:46 | 显示全部楼层
你如果只修改占空比的代码是不会动频率的。没遇到这种。
| 2018-5-8 00:31 | 显示全部楼层
zly1993 发表于 2018-5-7 10:00
TIM4有什么问题吗,我是随便用的一个。stm32我也是才开始学习不久

Tim4中断程序那里,每次中断(即单个pwm周期内)进行了buf的字符数的次数来配置占空比,Tim4跟Tim3这样的方式计时不同步,导致Tim4不能准确配置Tim3的占空比。我猜测你是想通过输出不同占空比来表示0和1,直接使用Tim3就可以了,开启Tim3中断,单个周期结束后中断,中断程序里直接装入0或1代表的占空比,增加字符串指针指向下一位,若到末尾将占空比设为0,退出中断,主程序只需要改变buf内容即可
| 2018-5-9 22:04 | 显示全部楼层
嗯,我也去试试怎么实现这个功能
 楼主 | 2018-5-10 09:14 | 显示全部楼层
sdggg 发表于 2018-5-8 00:31
Tim4中断程序那里,每次中断(即单个pwm周期内)进行了buf的字符数的次数来配置占空比,Tim4跟Tim3这样的方 ...

感谢啦
| 2018-5-12 09:14 | 显示全部楼层
问题解决了?
 楼主 | 2018-5-16 14:04 | 显示全部楼层

没有解决了,发现满足不了需求
| 2018-5-17 00:08 | 显示全部楼层
zly1993 发表于 2018-5-16 14:04
没有解决了,发现满足不了需求

用定时器IO模拟一下试试,如果要求的频率不是很高的话。
 楼主 | 2018-5-17 14:37 | 显示全部楼层
734774645 发表于 2018-5-17 00:08
用定时器IO模拟一下试试,如果要求的频率不是很高的话。

800KHZ的波形
| 2018-5-18 11:27 | 显示全部楼层
stm32我也是才开始学习不久   共勉
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

快速回复 返回顶部 返回列表