论坛元老
 
- 积分
- 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 ++; //改变输出速度
}
}
}
}
|
|