OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2772|回复: 3

PWM输出如何做到只输出有限个脉冲

[复制链接]

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
480
金钱
480
注册时间
2016-4-5
在线时间
148 小时
发表于 2016-4-20 00:36:30 | 显示全部楼层 |阅读模式
36金钱
刚开始学到PWM输出,请教一下,如何做到只输出有限个脉冲比如使用TIM2,设置向上计数模式从0至899,初始化k=0

                if(TIM2->CNT==899)  k++;
                if(k==100) {关闭TIM2使能;}




这样写行吗?应该怎么做呢?

最佳答案

查看完整内容[请看2#楼]

如果只是输出一路 PWM波, 且脉冲宽度在50% 我个人建义你不要使用定时器的 PWM的输出功能, 直接使用定时中断比较好控制 只用一个全全局变量 计录要输出的脉冲个数就行了 比如 #define BIT_ADM(addr,bitnum) MEM_ADDR(BITBAND(((u32)&(addr)),(bitnum))) //在原子哥的操作寄存器SYS.H中增加这个宏, 好按位操作各和寄存器 #define MOD_TIM_BUF BIT_ADM(TIM2->CR1,0) //电机驱动定 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-20 00:36:31 | 显示全部楼层
本帖最后由 likunxue 于 2016-4-20 08:31 编辑

如果只是输出一路 PWM波, 且脉冲宽度在50%  我个人建义你不要使用定时器的 PWM的输出功能, 直接使用定时中断比较好控制
只用一个全全局变量 计录要输出的脉冲个数就行了
比如
#define BIT_ADM(addr,bitnum)      MEM_ADDR(BITBAND(((u32)&(addr)),(bitnum)))    //在原子哥的操作寄存器SYS.H中增加这个宏, 好按位操作各和寄存器
#define MOD_TIM_BUF                    BIT_ADM(TIM2->CR1,0)                  //电机驱动定时器开关
#define MOTOR_CLK                       BIT_ADM(GPIOA->ODR, 5)    //输出脉冲线  PA5
u16  GeShu =    1000;                     //输出1000个脉冲
/********************************************************************************************
函 数 名: 定时器2中断函数
调    用: 无
参    数: 无
返 回 值: 无        
********************************************************************************************/
void TIM2_IRQHandler(void)
      {
      if(BIT_ADM(TIM2->SR,0) == 1)                 //检查是否是溢出中断以经发生过               
        {              
        BIT_ADM(TIM2->SR,0) = 0;                   //清除中断标志   
        if( GeShu == 0) MOD_TIM_BUF  = 0;       //指定的脉冲个数输出完成,关定时器
        else{
             MOTOR_CLK  = ~ MOTOR_CLK;        //输出脉冲
             if(MOTOR_CLK == 1) GeShu  --;       //输出脉冲个数减1
             }
        }  
      }
如果使能了定时器的PWM功能, 需要再增加一个输出判断变量就行了, 注意是两次中断输出一个完整的脉冲波
比如
u8  BCLK = 0xff;  //注意, 初始化一定要置为0XFF,这样取反一次, 要不是0要不就是 0XFF  ,好判断

void TIM2_IRQHandler(void)
      {
      if(BIT_ADM(TIM2->SR,0) == 1)                 //检查是否是溢出中断以经发生过               
        {              
        BIT_ADM(TIM2->SR,0) = 0;                   //清除中断标志   
        if( GeShu == 0) MOD_TIM_BUF  = 0;       //关定时器
        else{
             BCLK  = ~ BCLK;                //取反输出标志位
             if(BCLK != 0) GeShu  --;       //输出脉冲数减1
             }
        }  
      }
用定时器中断输出脉冲的方式比较适合用于步进电机或伺服电机驱动
比如, 你做一个加减速速度表,不断查表就可以输出不同速度的脉冲了
输出的脉冲个数就是电机要走的步数

Motor_DriveTiminG[];   //电机速度表
int  Leve = 0;              //速度指针      

void TIM2_IRQHandler(void)
      {
      if(BIT_ADM(TIM2->SR,0) == 1)                 //检查是否是溢出中断以经发生过               
        {   
       TIM2->CNT = Motor_DriveTiminG[Leve];   //查表得到电机速度,重装定时常数     
        BIT_ADM(TIM2->SR,0) = 0;                   //清除中断标志   
        if( GeShu == 0) MOD_TIM_BUF  = 0;       //关定时器
        else{
             MOTOR_CLK  = ~ MOTOR_CLK;        //输出脉冲
             if(MOTOR_CLK == 1)
               {
               GeShu  --;       //输出脉冲数减1
               Leve ++;       //改变输出速度
               }
             }
        }  
      }





回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-20 01:37:18 | 显示全部楼层
明天再帮你搞了,洒搞多了, 搞不下去了
回复

使用道具 举报

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
480
金钱
480
注册时间
2016-4-5
在线时间
148 小时
 楼主| 发表于 2016-4-21 11:30:16 | 显示全部楼层
likunxue 发表于 2016-4-20 01:37
明天再帮你搞了,洒搞多了, 搞不下去了

太感谢了!!!!!!确实,不一定用定时器的PWM功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 04:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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