完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
这次边做边写,基本上把做proj的整个步骤记录下来,包括中间的思考过程,也挺有意思的
小车主控板思路 主控板需要完成的功能: 1.接受传输过来的数据 2.根据数据控制电机PWM 3.根据数据控制舵机PWM 控制电机的PWM实现: 1.一个函数,两个参数:move(dir,speed) 2.dir控制前后,speed控制pwm. 3.如果方向改变需要延迟一定时间 控制舵机的pwm实现: 1.一个函数,两个参数:turn(dir,value) 2.dir控制左右,value是设定值控制pwm 3.value需要配合PID算法写好 两个电机控制需要两个tim的pwm,需要四个管脚输出控制正反转. PID算法实现的时候,舵机有反馈线反馈现在所在的角度.反馈用ADC采样读取 PS: 未测试NRF24L01通信模块前自己留一个串口,使用蓝牙调PID 程序步骤 开启时钟(GPIO,TIM, ADC,USART,AFIO) 写move函数 写PID算法 写turn函数 配置蓝牙串口 调试PID 开启时钟 ABP1和APB2对应的外设见下表 使用TIM生成PWM波 这里使用TIM生成的PWM是为了让PWM更加稳定可靠 原理解释 通用定时器可以利用GPIO引脚进行脉冲输出,在配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。 这里直接举例说明定时器的PWM输出工作过程:若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。 而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。 如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为 A/(N+1) 。 TIM3复用引脚 如下图 感觉没有引脚冲突的情况下,可以默认没有重映像,TIM3_CH1~4的管脚对应的就是PA6、PA7、PB0、PB1. 输出模式也好确定,查手册可以看到:输出采用推挽复用输出 Mode值放这方便查看: void tim3() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //初始化计数配置 TIM_OCInitTypeDef TIM_OCInitStructure;//初始化TIM3的外设 TIM_TimeBaseStructure. TIM_Period =999; //计数上限为1000 TIM_TimeBaseStructure.TIM_Prescaler =71; //计时器预分频为72/(71+1)=1MHZ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM脉冲宽度调制模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10;//设置了待装入捕获比较寄存器的脉冲值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //TIM输出比较极性高 TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的预装载寄存器 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR2上的预装载寄存器 TIM_Cmd(TIM3,ENABLE); } 注意TIM_OCPolarity的选择和OCMode的PWM两种模式的区别: OCPolarity为高则高电平有效 若TIM_OCInitTypeDef.TIM_OCMode = TIM_OCMode_PWM1时: 当计时器值小于比较器设定值时则TIMX输出脚此时输出有效 当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出无效 若TIM_OCInitTypeDef.TIM_OCMode = TIM_OCMode_PWM2时: 当计时器值小于比较器设定值时则TIMX输出脚此时输出无效 当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出有效 修改比较寄存器值的函数TIM_SetComparex(TIM_TypeDef* TIMx, u16 Comparex) 把TIMx的比较寄存器x的值设成Comparex u16 TIMCompare1 = 0x7FFF; TIM_SetCompare1(TIM3, TIMCompare1); 试用驱动后的第一次修订 因为采用的大电机的mos驱动很窒息,有一个刹车功能,所以是采用的双路PWM驱动正反转。因此修改之前的TIM生成的PWM配置,采用多个定时器输出多路PWM波. 新的PWM安排如下: TIM2的CH3和TIM3的CH1分别对应PA2和PA6给大电机的两路PWM. TIM4的CH1对应着PB6给舵机的PWM. 新的引脚安排: MOS驱动使能采用PB9. 大坑出现 尝试着正转和反转,但是遇到了大坑.想通过关闭TIM来关闭PWM输出,结果是关闭了TIM之后PWM输出端口就自动高电平无法拉低!. 原因:复用推挽输出下IO口无法控制高低电平,因此拉低只能使用配置占空比的方法. 所以之前配多路TIM是没太大意义的。。关闭PWM只要把占空比调成零就好了!坑啊! 假装调了PID 舵机反馈线就是一个电位器的中间接线引出来的,左右接3.3V,中间接出来一根线连上ADC采样,读取现有值然后写一个PID反馈调节即可。舵机给一个正的PWM或者一个负的PWM即可完成正转和反转,PWM值的高低决定了转向的快慢,如果PWM占空比过小,那么舵机可能无法转动。不能超调过多,也不能调节量太小转动太慢,于是需要控制参数慢慢调节。PID调节经验看了半天,最后发现这个舵机根本就不灵敏,用不着调节I和D,调好P就行了,就是完成了一个负反馈。过程有一点点艰辛,因为用L298N的驱动时,之前没发现驱动不灵敏,导致最小占空比的PWM也是一直处于超调状态。换了MOS驱动很快就调好了,PID调节的内容就不写在这里了,只要看懂了算法很快就能自己写一个,毕竟这里甚至只用写一个P对吧… NRF24L01通信模块 这一块内容是交给女票做的,第一部分是完成SPI的配置。这个有一大堆教程,如果IO口模式配置正确了,SPI的配置内容没有问题,应该很快就能工作。使用SPI往NRF24L01寄存器里写一个值,然后读出来,如果写进去的和读出来的是一样的,那么SPI就配置完毕了。最后是玄学的通信模块调试。NRF24L01是最便宜的2.4GHz的无线通信模块,由于寄存器太多,女票读了好久文档然后自己写了通信要用的函数,接收发送等等。然后总是GG..调了很久才完成。代码在Git上,现在有一个随时可用的配置了,如果之后要做遥控类的东西通信要调的话就方便很多了。 数据发送接收调节方向,速度,关机开机 遥控器使用两个摇杆电位器做的,用ADC不停采样然后用NRF24L01给车上的主控板不停歇的发送数据,一个控制方向PWM,一个控制驱动电机PWM.前进和后退需要有一定延迟,因为反应太 快而电机又有电感会出现不可逆转的损害。最后是为了防止因为线断了等导致方向或者电机突然失灵,做了一个按钮控制开机关机,就是紧急制动。这些都很好写,源码里直接可以看到。 总结 小车主控板的大坑遇到不多,一个是MOS驱动问题,一开始双PWM控制不太会用,要拉低就是把占空比调到0. 第二个是由于端口太多,ADC,TIM的PWM输出,SPI等引脚可能按默认配置有重复,所以得使用IO口的重映射. 比较大的坑在通信模块,这是和女票一起调了很久才完成的,感觉有点玄学。看看基础配置,通信速率,传输地址,模式等等是不是都配对了。最后的无线通信调试是没有很好的DEBUG方法的,一步一步慢慢来。 小车做出来了还是挺好玩的,比较有成就感. 缺点就是线可能不太稳,如果撞车了有一定概率失去控制。。这个可以再改进一下。 这个小车电机极其强大,可以跑的巨快。。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 22:39 , Processed in 0.964768 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号