使用单片机STM32F103RCT6,利用定时器比较输出模式PWM方式。写了一个马达控制程序,需要计步,然后采用了在中断里计步方式,进入一步加一步。为了测量计步的准确性,另外编写了一个外部中断方式测量脉冲数办法。只是使用了上升沿进入中断,进入一次加一步。但是计出来的步数刚好比定时器中断多一倍。不知道原因是什么。哪位大侠有时间指点一下。谢谢了。附初始化程序以及中断处理程序。
定时器方面:
void TIM3Compare_output_PWM(u16 arr,u16 psc) //比较输出PB5 TIM3->CH2
{
arr = arr ;
psc = psc ;
RCC->APB1ENR|=1<<1; //TIM3时钟使能
RCC->APB2ENR|= 0x01 ; // 辅助功能IO时钟使能
RCC->APB2ENR|=1<<3; //PORTB时钟使能
AFIO->MAPR &= 0xFFFFF3FF ; //部分映像(CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1);
AFIO->MAPR |= 0x00000800 ; //TIM3_REMAP[1:0]:定时器3的重映像 (TIM3 remapping)
GPIOB->CRL&=0xFF0FFFFF; //PORTB5推挽输出 输出最大频率50M
GPIOB->CRL|=0x00B00000; //PORTB5复用功能推挽输出
TIM3->ARR = arr ; // 重载值改变输出频率
TIM3->PSC = psc ; //预分频器
TIM3->CR1 = 0x00 ; //计数器分频比为0 ,向上计数
TIM3->EGR = 0x01 ; //立即重装模式
TIM3->CCER &= 0xFFEF ;
TIM3->CCER |= 0x0010 ; //TIM3 OC2CH 相应信号输出 输出电平高
// TIM3->CR2 // 采取默认值即可
TIM3->CCMR1 &= ~0x7300 ; //禁止了输出寄存器的预装载使能
TIM3->CCMR1 |= 0x7080 ; //使能预装载寄存器 //选择定时器模式:TIM脉冲宽度调制模式2
TIM3->DIER |= 0x0004; //1234位分别对应1234通道,值分别为2 4 8 16 允许捕获比较中断
//TIM3->CCR2 = 200 ;
NVIC_Init(0,0,TIM3_IRQn,2);//组2,最低优先级
//TIM3->CR1 |= 0x01 ; //使能计数器
}
void TIM3_IRQHandler(void) //TIM3中断
{
if ((0x04==(TIM3->SR & 0x04))&&(0x04 == (TIM3->DIER & 0x04))) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM3->SR&= 0xFFFB; //清除TIMx的中断待处理位:TIM 中断源
g_pulse2_num++;
#if 0
TIM3->ARR=Motor2_frequency; //设置重装载值 改变这个可以改变频率
TIMx->CCR2 = Compare2;
#endif
}
}
中断方式:
void PB11_Interrupt_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRH &= 0xFFFF0FFF ; //GPIOB 11设置为输入上下拉模式
GPIOB->CRH |= 0x00008000 ; //GPIOB 11设置为输入上下拉模式
GPIOE->ODR|=1<<11; //GPIOB 1设置为上拉
RCC->APB2ENR|=0x01;//使能io复用时钟
AFIO->EXTICR[2] &= 0xFFFF0FFF ;//清除原来设置!!!
AFIO->EXTICR[2]|= 0x00001000;//EXTI.BITx 映射到GPIOx.BITx
//自动设置
EXTI->IMR|=1<<11;// 开启line BITx 11位上的中断
//EXTI->EMR|=1<<BITx;//不屏蔽line BITx上的事件 (如果不屏蔽这句,在硬件上是可以的,但是在软件仿真的时候无法进入中断!)
//if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx上事件下降沿触发
EXTI->RTSR|=1<<11 ;//line BITx 11位上事件上升降沿触发
NVIC_Init(0,0,EXTI15_10_IRQn,2) ;
}
void EXTI15_10_IRQHandler(void)
{
g_pulse2_num++ ;
if(g_pulse2_num>=TOTAL_STEP)
{
g_pulse2_num = 0 ;
}
EXTI->PR=1<<11; //清除LINE11上的中断标志位
}
|