完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
程序设计
伺服电机的速度控制模式代码讲解 main.c #include "delay.h" #include "key.h" #include "timer.h" extern u8 dir; int main(void) { u8 Key_Value=0; gpio_init(); //有一个定时器通道3 delay_init(); //延时函数初始化 KEY_Init(); //按键初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); TIM2_PWM_Init(72000000/2000-1,0); TIM3_Int_Init(359,1000); TIM_Cmd(TIM2,DISABLE); //定时器2和定时器3默认不开启 TIM_Cmd(TIM3,DISABLE); while(1) { . . . . . . } } 1、TIM2_PWM_Init TIM2_PWM_Init(72000000/2000-1,0); //72000000/2000=36000 //不分频,PWM启动频率=72000000/36000=2000Hz 1 2 3 TIM2_PWM_Init(72000000/2000-1,0) 参数1:72000000/2000-1,溢出值(从0开始) 参数2:0,分频值(从0开始) 通过该段代码使TIM2产生一个PWM方波。 2、TIM3_Int_Init TIM3_Int_Init(359,1000); //(72000000/1000)/360=200Hz //5ms改变一次频率 //定时器3的溢出中断去调节定时器2产生的方波的频率 TIM3_Int_Init(359,1000) 参数1:4999,溢出值(从0开始) 参数2:7199,分频值(从0开始) 72MHz÷1000=72KHz,计数到360为5ms,即每5ms进一次中断。 通过该段代码使TIM3每5ms进入一次中断判断是加速减速还是匀速。 3、while while(1) { Key_Value|=KEY_Scan(); if((Key_Value&0x01) ==1) { if(Key_Value>>7==0) //按下独立按键,开始发脉冲,电机加速至最高转速 { dir=1;//每次溢出中断,另脉冲频率开始升高 Key_Value =1<<7;//Key_Value最高位 0代表电机未开启 1代表电机已开启 TIM_Cmd(TIM3,ENABLE); //开启定时器2和定时器3,PA.2管脚开始输出脉冲 TIM_Cmd(TIM2,ENABLE); } else if(Key_Value>>7==1)//第二次按下独立按键,电机减速至停止 //最高位如果等于1 { Key_Value =0; //按键值清零 dir=0; //每次溢出中断,另脉冲频率开始降低 TIM_Cmd(TIM3,ENABLE); //重新打开定时器3,开始改变频率 } } } 第一个段代码Key_Value|=KEY_Scan(),用于改变Key_Value的值,我们对KEY_Scan go to definition。 //按键处理函数 //返回按键值 //0,KEY0松开 //1,KEY0按下 u8 KEY_Scan(void) { //按一下,从0到高速 //再按一下,从高速变为0 static u8 key_up=1;//按键按松开标志 if(key_up && KEY0==0)//按键松开并且KEY0被按下 { delay_ms(10);//去抖动 key_up=0; if(KEY0==0) return 1; } else if(KEY0==1)key_up=1; return 0;// 无按键按下 } 代码解释: key_up作为子程序KEY_Scan的局部静态变量,当没有键按下时,图中第10行的if条件不成立,key_up仍然为1,KEY_Scan直接return 0,KEY_Scan结束执行;当有按键按下时,第10行的if成立,执行if语句(由于程序执行周期远远小于人按键松开时间,所以认为执行1个周期期间key_up一直为1),延迟消抖后,key_up变为0,同时执行嵌套的if语句来再次判断是哪个键被按下,并且return对应的键值。尽管main高速调用KEY_Scan,但由于key_up是static类型的变量,会继承上一次调用的值,也即是说key_up=0,不执行第10行if,KEY_Scan的return为0。直到按键完全松开,执行第16行程序,key_up重新为1。做到了按下按键只返回一次对应值。 回到while,当第一次按下按键,则执行语句Key_Value | = KEY_Scan(),Key_Value = 1。此时Key_Value的最高位为0,所以Key_Value >> 7 = = 0成立,加速标志dir = 1,表示加速,同时另Key_Value的为高位为1,最后开启定时器2和定时器3来产生PWM方波和控制加减速。 if(Key_Value>>7==0) //按下独立按键,开始发脉冲,电机加速至最高转速 { dir=1;//每次溢出中断,另脉冲频率开始升高 Key_Value =1<<7;//Key_Value最高位 0代表电机未开启 1代表电机已开启 //把最高位至1 TIM_Cmd(TIM3,ENABLE); //开启定时器2和定时器3,PA.2管脚开始输出脉冲 TIM_Cmd(TIM2,ENABLE); } 第二次按下按键,由于Key_Value的为高位为1,所以Key_Value>>7 = = 1成立,另Key_Value = 0,则加速标志dir = 0,表示减速,重新打开定时器3,开始改变速度。 else if(Key_Value>>7==1)//第二次按下独立按键,电机减速至停止 //最高位如果等于1 { Key_Value = 0; //按键值清零 dir = 0; //每次溢出中断,另脉冲频率开始降低 TIM_Cmd(TIM3,ENABLE);//重新打开定时器3 } timer.c TIM3_IRQHandler void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); if(dir==1) //加速标志 if(freq1<62000) //最高频率62KMz { freq1+=100; PWM_Change(freq1); } if(dir==0) //减速标志 if(freq1>2000) //最低频率2KMz { freq1 -=100; PWM_Change(freq1); } if(dir==1&&freq1>=62000) //如果加速达到最高频率,则关闭定时器3,定时器2输出最高频率的脉冲,电机匀速运行 TIM_Cmd(TIM3,DISABLE); if(dir==0&&freq1<=2000) //如果减速至2000Hz以下,则关闭定时器2和定时器3,停止输出脉冲,电机停止运行 { TIM_Cmd(TIM2,DISABLE); TIM_Cmd(TIM3,DISABLE); } } } 由于main.c中初始化了TIM3_Int_Init(359,1000),所以每5ms发生一次溢出中断,判断一次加速标志dir,再修改或保持一次频率。 通过定时器3溢出中断发现,函数PWM_Change修改了频率,所以对PWM_Change go to definition //改变频率 void PWM_Change(u32 freq) { u16 arr,psc; arr=72000000/freq-1; psc=0;//不分频 TIM2_PWM_Init(arr,psc); //使用新的参数配置定时器,改变定时器的周期 TIM_Cmd(TIM2,ENABLE); //开启定时器2 } 由函数可知,最终是调整了定时器2输出PWM的溢出周期arr的值来改变转速。 void TIM2_PWM_Init(u16 arr,u16 psc) { . . . . . . TIM_SetCompare3(TIM2,arr/2); } TIM2_PWM_Init多了这一句话,在初始化里面改变了比较点。 伺服电机的位置控制模式代码讲解 main.c while(1) { num_plus_setting=100; //脉冲个数设定值 if(KEY_Scan()) running_motor=1; //电机启动 if(running_motor) TIM_Cmd(TIM2,ENABLE);//定时器2使能 else num_plus_now=0;//当前脉冲个数清零 } 如果有按键按下,则第5行的if判断成立,另running_motor=1;同时第7行的if判断也成立,则开启定时器2。如果没有按键按下,则running_motor=0,当前脉冲个数清0。 timer.c TIM2_IRQHandler 定义了三个变量: 按键按下时的标志位,u8 running_motor; 当前的脉冲个数:u32 num_plus_now; 设定的脉冲个数:num_plus_setting。 当有按键按下时, running_motor=1,第2行的if判断成立,则定时器2每溢出一次,当前的脉冲个数num_plus_now自加1。 接着根据当前的脉冲个数num_plus_now的大小,判断伺服电机是应该加速还是应该减速,生成相应的加速标志dir=1或者减速标志dir=0。 最后根据标志来进行加速或减速。 编译仿真 伺服电机的速度控制模式 打开仿真 点击示波器: 弹出如下示波器页面: 点击set up增加变量 点击左边的方框,添加PORTA.2,同时把Display Type改为改为Bit。 点击运行 第一次点击PE.3,伺服电机加速,看到频率由低到高,后达到稳定。 第二次点击PE.3,伺服电机减速,看到频率由高变低,最后变为低电平。 伺服电机的位置控制模式 打开仿真 点击示波器: 弹出如下示波器页面: 点击set up增加变量 点击左边的方框,添加PORTA.2,同时把Display Type改为改为Bit。 点击运行 点击PE.3,伺服电机先加速后减速,看到频率由低到高在变低。 遇到的错误 遇到的错误:把TIM_SetCompare3注释,仿真还是会出现波形。 TIM_SetCompare3(TIM2,arr/2)注释后,比较点就不会再变化了;由于每次溢出中断都会调用PWM_Change函数来改变arr的值,导致溢出周期却还在一直变化,所以波形频率才会变化。 解决错误: 取消对TIM_SetCompare3(TIM2,arr/2)的注释。 成功运行 总结 |
|
|
|
只有小组成员才能发言,加入小组>>
2386 浏览 0 评论
8910 浏览 4 评论
36486 浏览 19 评论
4981 浏览 0 评论
24307 浏览 34 评论
1375浏览 2评论
1627浏览 1评论
2017浏览 1评论
1441浏览 0评论
386浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 03:12 , Processed in 1.205569 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号