简介:
1、芯片是F0C8的,通过ULN2803驱动24BYJ48,5V减速步进电机,定时器是TIM1和TIM3,TIM1是高级的,TIM3是通用的,通道都是用的CH1、2、3、4。
2、要求是输出4路占空比一定37.5%,相位差90°的波形。
3、方法是定时器输出翻转,使能OC中断,在中断中不停的改变CCR的值,达到占空比一定的要求;4个通道的CCR初始值相差1/4的ARR值。
4、TIM1已经搞定,可以实现正转、反转,速度控制,开始、停止。
问题:
1、TIM3可以转动,不能停止,在定时器初始化TIM3->CR1 |=0x01;后加打印信息,不能打印;单步调试时执行到串口里边就死掉了。
while (USART_GetFlagStatus(UART_USED, USART_FLAG_TXE) == RESET)
{}
代码:
1、定时器初始化
void Motor_LR_TIM3_Init(uint8_t direct,uint16_t speed)
{
TIM3->ARR=32*speed/10-1; //É趨¼ÆÊýÆ÷×Ô¶¯ÖØ×°Öµ arr=48000000/(psc+1)/(1000000/(8*speed))
TIM3->PSC=120-1;
//MOTOR_LR TIM3 Configuration
TIM3->CCMR1|=3<<4; //CH1 Æ¥Åäʱ·×ª
TIM3->CCMR1|=3<<12; //CH2 Æ¥Åäʱ·×ª
TIM3->CCMR2|=3<<4; //CH3 Æ¥Åäʱ·×ª
TIM3->CCMR2|=3<<12; //CH4 Æ¥Åäʱ·×ª
TIM3->CCER|=1<<0; //OC1 Êä³öʹÄÜ
TIM3->CCER|=1<<4; //OC2 Êä³öʹÄÜ
TIM3->CCER|=1<<8; //OC3 Êä³öʹÄÜ
TIM3->CCER|=1<<12; //OC4 Êä³öʹÄÜ
TIM3->CR1 |=1<<7; //ARPEʹÄÜ
TIM3->DIER |=0x1F; //ʹÄÜTIM²¶»ñ/±È½Ï1 2 3 4ÖжÏ
UART_send_byte(0xA); //可以打印
if(direct==MOTOR_DIR_LEFT)
{
TIM3->CCR1=MOTOR_LEFT_BLUE_VALUE;
TIM3->CCR2=MOTOR_LEFT_BROWN_VALUE;
TIM3->CCR3=MOTOR_LEFT_YELLOW_VALUE;
TIM3->CCR4=MOTOR_LEFT_BLACK_VALUE;
UART_send_byte(0xB); //可以打印
}
else if(direct==MOTOR_DIR_RIGHT)
{
TIM3->CCR1=MOTOR_RIGHT_BLUE_VALUE;
TIM3->CCR2=MOTOR_RIGHT_BROWN_VALUE;
TIM3->CCR3=MOTOR_RIGHT_YELLOW_VALUE;
TIM3->CCR4=MOTOR_RIGHT_BLACK_VALUE;
}
UART_send_byte(0xC); //可以打印
TIM3->CR1 |=0x01; //使能定时器3
UART_send_byte(0xC); //不能打印
}
2、失能定时器,停止电机
void Motor_LR_Stop(void)
{
TIM3->CR1 &=~(0x01); //¹Ø±Õ¶¨Ê±Æ÷3
}
3、开始程序,方向改变时定时器重新初始化,改变方向全局变量motor_dir
void Motor_LR_Start(uint8_t direct,uint16_t speed)
{
motor_dir=direct; //全局变量,在中断里判断方向
//TIM_DeInit(TIM3);
Motor_LR_TIM3_Init(direct,speed);
UART_send_byte(0x0D); //不能打印
}
4、中断程序
void TIM3_IRQHandler(void)
{
uint16_t LR_capture1;
uint16_t LR_capture2;
uint16_t LR_capture3;
uint16_t LR_capture4;
if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET)
{
LR_capture1=TIM_GetCapture1(TIM3);
switch(motor_dir)
{
case MOTOR_DIR_LEFT :
{
if(LR_capture1==MOTOR_LEFT_BLUE_VALUE)
TIM_SetCompare1(TIM3,MOTOR_LEFT_BLUE_VALUE+HIGH_DUTY_CYCLE);
else if(LR_capture1==MOTOR_LEFT_BLUE_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare1(TIM3,MOTOR_LEFT_BLUE_VALUE);
}break;
case MOTOR_DIR_RIGHT :
{
if(LR_capture1==MOTOR_RIGHT_BLUE_VALUE)
TIM_SetCompare1(TIM3,MOTOR_RIGHT_BLUE_VALUE+HIGH_DUTY_CYCLE);
else if(LR_capture1==MOTOR_RIGHT_BLUE_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare1(TIM3,MOTOR_RIGHT_BLUE_VALUE);
}break;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);
}
else if(TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET)
{
LR_capture2=TIM_GetCapture2(TIM3);
switch(motor_dir)
{
case MOTOR_DIR_LEFT :
{
if(LR_capture2==MOTOR_LEFT_BROWN_VALUE)
TIM_SetCompare2(TIM3,MOTOR_LEFT_BROWN_VALUE+HIGH_DUTY_CYCLE);
else if (LR_capture2==MOTOR_LEFT_BROWN_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare2(TIM3,MOTOR_LEFT_BROWN_VALUE);
}break;
case MOTOR_DIR_RIGHT :
{
if(LR_capture2==MOTOR_RIGHT_BROWN_VALUE)
TIM_SetCompare2(TIM3,MOTOR_RIGHT_BROWN_VALUE+HIGH_DUTY_CYCLE);
else if(LR_capture2==MOTOR_RIGHT_BROWN_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare2(TIM3,MOTOR_RIGHT_BROWN_VALUE);
}break;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_CC2);
}
else if(TIM_GetITStatus(TIM3,TIM_IT_CC3)!=RESET)
{
LR_capture3=TIM_GetCapture3(TIM3);
switch(motor_dir)
{
case MOTOR_DIR_LEFT :
{
if(LR_capture3==MOTOR_LEFT_YELLOW_VALUE)
TIM_SetCompare3(TIM3,MOTOR_LEFT_YELLOW_VALUE+HIGH_DUTY_CYCLE);
else if(LR_capture3==MOTOR_LEFT_YELLOW_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare3(TIM3,MOTOR_LEFT_YELLOW_VALUE);
}break;
case MOTOR_DIR_RIGHT :
{
if(LR_capture3==MOTOR_RIGHT_YELLOW_VALUE)
TIM_SetCompare3(TIM3,MOTOR_RIGHT_YELLOW_VALUE+HIGH_DUTY_CYCLE);
else if(LR_capture3==MOTOR_RIGHT_YELLOW_VALUE+HIGH_DUTY_CYCLE)
TIM_SetCompare3(TIM3,MOTOR_RIGHT_YELLOW_VALUE);
}break;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_CC3); //¼Ó´òÓ¡ÓÐÎÊÌâ
}
else if(TIM_GetITStatus(TIM3,TIM_IT_CC4)!=RESET)
{
LR_capture4=TIM_GetCapture4(TIM3);
switch(motor_dir)
{
case MOTOR_DIR_LEFT :
{
if(LR_capture4==MOTOR_LEFT_BLACK_VALUE)
TIM_SetCompare4(TIM3,MOTOR_LEFT_BLACK_VALUE+HIGH_DUTY_CYCLE-8*BEAT);
else if(LR_capture4==MOTOR_LEFT_BLACK_VALUE+HIGH_DUTY_CYCLE-8*BEAT)
TIM_SetCompare4(TIM3,MOTOR_LEFT_BLACK_VALUE);
}break;
case MOTOR_DIR_RIGHT :
{
if(LR_capture4==MOTOR_RIGHT_BLACK_VALUE)
TIM_SetCompare4(TIM3,MOTOR_RIGHT_BLACK_VALUE+2*BEAT);
else if(LR_capture4==MOTOR_RIGHT_BLACK_VALUE+2*BEAT)
TIM_SetCompare4(TIM3,MOTOR_RIGHT_BLACK_VALUE+7*BEAT);
else if(LR_capture4==MOTOR_RIGHT_BLACK_VALUE+7*BEAT)
TIM_SetCompare4(TIM3,MOTOR_RIGHT_BLACK_VALUE+2*BEAT);
}break;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_CC4);
}
}
5、测试程序
void test2(void)
{
Motor_LR_Start(MOTOR_DIR_LEFT,SPEED);
//以下不能执行
UART_send_byte(0x0D);
delayms(800);
printf("\r\r\n motor_dir=%d \r\r\n",motor_dir);
Motor_LR_Stop();
delayms(1000);
printf("\r\r\n motor_dir=%d \r\r\n",motor_dir);
Motor_LR_Start(MOTOR_DIR_RIGHT,SPEED);
delayms(8000);
printf("\r\r\n end \r\r\n");
Motor_LR_Stop();
delayms(1000);
}
|