历史上的今天
今天是:2024年10月14日(星期一)
2019年10月14日 | STM32 PWM实现精确输出脉冲数控制电机
2019-10-14 来源:eefocus
精确输出脉冲数控制电机,使用stm32单片机的pwm功能实现,精确控制脉冲个数
单片机源程序如下:
#include #include "sys.h" #include "usart.h" #include "delay.h" #include "led.h" #include "exti.h" #include "key.h" #define MOTOR_DIR PBout(11)// PB11 #define MOTOR_EN PEout(15)// PE15 u16 i; u16 fre; u16 TIM5CH1_CAPTURE_VAL; //输入捕获值 u16 PUL_CNT; void Motor_Set() { RCC->APB2ENR|=1<<3; //使能PORTB时钟 GPIOB->CRH&=0XFFFF0FFF; GPIOB->CRH|=0X00003000; //PB11 推挽输出 GPIOB->ODR|=(1<<11); //PB11 输出高 RCC->APB2ENR|=1<<6; //使能PORTE时钟 GPIOE->CRH&=0X0FFFFFFF; GPIOE->CRH|=0X30000000; //PE15 推挽输出 GPIOE->ODR|=(1<<15); //PE15 输出高 MOTOR_EN=0; //不使能 } void Timer3_Init(u16 arr,u16 psc) { RCC->APB2ENR|=1<<2; //使能PORTA时钟 RCC->APB2ENR|=1<<3; //使能PORTB时钟 RCC->APB2ENR|=1<<5; //使能PORTD时钟 GPIOB->CRL&=0XFF0FFFFF; //PB5输出 GPIOB->CRL|=0X00B00000; //复用功能输出 GPIOA->CRL&=0x00ffffff; GPIOA->CRL|=0xBB000000; GPIOA->ODR|=3<<6; GPIOB->CRL&=0xffffff00; GPIOB->CRL|=0x000000BB; GPIOB->ODR|=3; RCC->APB1ENR|=1<<1;//TIM3时钟使能 TIM3->CR1|=1<<4;//向下计数 TIM3->CCMR1=0x6868;//通道1、2PWM模式1,预装载使能 TIM3->CCMR2=0x6868;//通道3、4PWM模式1,预装载使能 TIM3->CCR1=100; TIM3->CCR2=200; TIM3->CCR3=200; TIM3->CCR4=100; //4k->250 TIM3->ARR=arr; //设定计数器自动重装值//刚好0.1ms TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟 // TIM3->ARR=1000; //设定计数器自动重装值 1000=1ms 10000=10ms(1~10ms对应1000~100hz) // TIM3->PSC=72; //预分频器72,得到1Mhz的计数时钟 TIM3->CCER=0X1111;//打开四个通道,允许输出,有效电平为高 TIM3->CR1|=1<<7; TIM3->EGR|=1; //这两个东东要同时设置才可以使用中断 TIM3->DIER|=1<<0; //允许更新中断 TIM3->DIER|=1<<6; //允许触发中断 TIM3->CR1|=0x01; //使能定时器3 } void Timer4_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<2;//TIM4时钟使能 TIM4->ARR=arr; //设定计数器自动重装值//刚好1ms TIM4->PSC=psc; //预分频器7200,得到10Khz的计数时钟 //这两个东东要同时设置才可以使用中断 TIM4->DIER|=1<<0; //允许更新中断 TIM4->DIER|=1<<6; //允许触发中断 TIM4->CR1|=0x01; //使能定时器4 MY_NVIC_Init(1,3,TIM4_IRQChannel,2);//抢占1,子优先级3,组2 } void TIM4_IRQHandler(void) { if(TIM4->SR&0X0001)//溢出中断 { LED2=!LED2; } TIM4->SR&=~(1<<0);//清除中断标志位 } void Timer2_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<0;//TIM4时钟使能 TIM2->ARR=arr; //设定计数器自动重装值//刚好1ms TIM2->PSC=psc; //预分频器7200,得到10Khz的计数时钟 //这两个东东要同时设置才可以使用中断 TIM2->DIER|=1<<0; //允许更新中断 TIM2->DIER|=1<<6; //允许触发中断 TIM2->CR1&=0xfe; //不使能定时器2 // TIM2->CR1|=0x01; //使能定时器2 MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//抢占1,子优先级3,组2 } void TIM2_IRQHandler(void) //1s到 { if(TIM2->SR&0X0001)//溢出中断 { EXTI->IMR &=~(1<<0); //关闭外部中断 TIM2->CR1&=0xfe; //不使能定时器2 fre=TIM5CH1_CAPTURE_VAL/2; //计算出频率 printf("%d rn",fre); TIM5CH1_CAPTURE_VAL=0; LED1=!LED1; EXTI->IMR |= (1<<0); //打开外部中断 } TIM2->SR&=~(1<<0);//清除中断标志位 } //定时器3中断服务程序 void TIM3_IRQHandler(void) { if(TIM3->SR&0X0001)//溢出中断 { } TIM3->SR&=~(1<<0);//清除中断标志位 } //外部中断0服务程序 void EXTI0_IRQHandler(void) { TIM2->CR1|=0x01; //使能定时器2 TIM5CH1_CAPTURE_VAL ++; PUL_CNT ++; if(TIM5CH1_CAPTURE_VAL%500==0) LED3 = !LED3; EXTI->PR=1<<0; //清除LINE0上的中断标志位 } int main(void) { u16 Motor_cnt; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,115200); //串口初始化 LED_Init(); //初始化与LED连接的硬件接口 KEY_Init(); //按键 Timer3_Init(1000-1,72-1); //1MHZ 周期1MS 定时器3产生PWM EXTIX_Init(); //外部中断 Motor_Set(); //电机参数设置 Timer4_Init(2000,7200); Timer2_Init(10000-1,7200-1); LED1=0;TIM3->CR1&=0xfe; while(1) { //delay_ms(100);
史海拾趣
|
用双面板做的,采用单片机+锁相环控制+C2053功率管输出,频率非常稳定。 可以用按键调节发射频率,电子音量等 频率设置步进0.1MHZ 或1MHZ可以工作在88-108MHZ 调频段,升级软件可以在70-120MHZ工作 输出能驱动小灯泡发光,功率最大1W 该 ...… 查看全部问答> |
|
在网上看到关于USB总线的资料: USB是“Universal Serial Bus”的缩写,意思是“通用串行总线”。 但请注意,这不是一种新的总线标准,而是电脑系统接驳外围设备(如键盘、鼠标、打印机等)的输入/输出接口标准。现在电脑系统接驳外围设备的接口并 ...… 查看全部问答> |
|
这两天在捣鼓stm32的TIMx,不是TIM1,看了很多的文章,自己也尝试了很多程序,貌似还是没有看到效果,比如led灯被点亮,或者输出波形,感觉市面上的材料大多都有问题,或者只适合作者自己,没有通用性,求懂TIM的人留言,可以直接贴代码,加些注释 ...… 查看全部问答> |
|
我刚本科毕业半年,在一间小公司做硬件开发,做着做着觉得自己手比较笨,对于焊接那些小东西感到很吃力,而且也不喜欢做这些,但是对编写相关的硬件代码却有很浓厚的兴趣,特别是跟linux系统相关的代码。但是自己却没多少linux基础,我想知道有没有 ...… 查看全部问答> |
|
Error[e12]: Unable to open file \'C:\\Program Files\\IAR Systems\\Embedded Workbench 6.0 Evaluation_3\\8051\\config\\ devices\\derivatives\\lnk51ew_.xcl\'… 查看全部问答> |




