完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
目的:让单片机输出一段可调频率的脉冲,用于驱动步进电机。
方案:1、使用定时器溢出中断,定时中断一次,在中断通过判断来翻转IO口。 优点:实现比较简单,对硬件要求不高。 缺点:不适合高速脉冲输出,而且脉冲分辨率也很低。 2、使用PWM模式,通过改变ARR的值来改变脉冲周期,从而控制IO口反转。 优点:可以输出高速的脉冲。 缺点:一个定时器只能输出一路脉冲,脉冲数量不可设置。 3、使用定时器的输出比较模式,设置输出比较匹配时翻转IO口,并开启输出比较中断, 在中断中装载下一次比较值。 优点:可以输出高速脉冲,并且脉冲数量控制。 缺点:进入中断频繁,增加CPU负担。 4、使用定时器的输出比较模式,设置输出比较匹配时翻转IO口,不开启输出比较中断, 开启DMA模式。 优点:可以输出高速脉冲,并且脉冲数量控制。 缺点:需要预装载脉冲频率的值,占用空间多。 结论:由于本次需要多个步进电机同时工作,并且步进电机需要加减速启动,电机转动的圈数不多。决定使用方案4。 *我搞这个模式搞了三天,今天终于把这坑踩平了,把这点经验分享给大家,避免重复踩坑。 *网上百度找了好久,稀稀疏疏就一两篇文章有用到这个模式的,而且还不是HAL库的,这个模式对于高速脉冲的输出真的是好用。 好了,直接上配置和代码,以及需要避坑的地方。 1、CubeMX配置 1.1 基本设置 1、先开始进行时钟配置,如上图,一般选用外部晶振 2、配置下载方式,Serial Wire就是SWD下载 3、配置定时器,我现在只需要通道2的比较输出模式,如图配置,其他模式看简介。 1.2时钟配置 我是用的是STM32F103的芯片,系统时钟最高72MHZ,所以如图配置。 1.3 具体配置 1、用到定时器肯定要配置定时器,这里的配置是:72分频,向上计数,计数最大值65536,通道2的输出比较模式要反转IO口。 2、DMA配置如图所示,这里不用循环模式,用半字传输,因为定时器是十六位的,CR2寄存器也是十六位的,存储器的地址需要递增,而外设地址不需要地址。 3、最后配置NVIC,这个版本的CubeMX是强制配置DMA中断的,因为用DMA传输数据,所以定时器输出比较中断不需要配置。 2 代码 2.1使能 首先需要一个数组,然后往数组里面放数据,这个就是输出比较模式里CR2设置的值。第一个数为200, 第二个为400,第三个为800,第四个为1400,看出规律没有。 **第一个坑来了 程序运行完这些就使能定时器和DMA吧,刚开始我是这样写的 其实是可以的,后来点进去第一个函数HAL_TIM_OC_Start_DMA看看,发现里面有这么一段。 就知道第二个函数在第一个函数里面已经调用了,重复调用浪费时间。 2.2调试 既然开启了自动装载,那就仿真看看CR2的值是不是真的在改变吧。(当时我们公司没有示波器和逻辑分析仪这些东西) **第二个坑报道 然后发现,一开始全速运行,CR2的值就马上变成这样子。。。 我在想,应该能看到变化才对,我想,是不是频率太快了,然后就把数组增大,使用6400个数据,大致算了下也要几秒钟的时间,后来仿真一看还是直接变成最后那个值。 后来各种搞,各种不行。今天上班来问隔壁公司借个示波器测测,一看,波形很对。上波形。 第二张波形图可以看到,后面还有无数个波形,而且波形比较大,这个是因为定时器一直没有关闭,所以这个脉冲周期就是定时器溢出周期的两倍(不知道为什么是两倍的同学看看比较输出模式的IO口翻转功能)。 2.3中断回调函数 第三个坑,神坑 因为DMA中断已经开启了,在是stm32f1xx_it.c函数里面有这些中断函数,找到这个定时器CH2的DMA中断函数。 然后我小心翼翼地点了进去,然后找回调函数 当时我惊呆了,hdma->XferCpltCallback(hdma);这个是啥玩意,点进去看居然是这样的。 这个写的是DMA传输完成中断回调函数,但是这玩意咋用,学了C语言这么多年,没见过能在结构体里面定义函数的。。。 不知道就百度吧,百度出一筐,看得云里雾里,最后一个热心的群友解答了我的问题,说这是一个指针,不是函数 实体,我个人就认为这只是用来指向某个具体函数的(大佬来解答一下,这个东西真的是第一次见到)。 看完还是不会用,然后试一下直接使用,下载,仿真,DMA进入了中断,但是没有进入这个回调函数,放弃(我是说再百度试试,毕竟搞不出来老板会扣我工资的)。 又百度到说DMA中断调用的其实是和普通中断调用一样的函数,怎么理解,例如不用DMA而用中断,触发中断调用的是A函数,那么用DMA,DMA完成中断也是调用A函数,哇,ST设计的HAL真厉害(这对于小白很好用)。然后我马上在 void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim);这个函数失能定时器和DMA。发觉不好使,调试也进不去。 搞了一个多小时,想了想可以一步一步地仿真,看看程序到底进入了那个回调函数,发现TMD进入的是这个函数。如图。 好吧,那就用这个函数失能定时器和DMA,注意一下,这里的__weak是弱函数,也就是说你可以重新定义一个同名的函数,而不需要把他删除,程序就会执行你定义的函数。如图。 最终完成了,波形图。 最后说明一下,这个方式可以一个定时器输出4个频率可变的波形,而且数量可以控制,也不需要单片机频繁进入中断。但是会很耗内存,在波形不会因为其他因素而改变的情况下可以放在单片机的ROM,或者可以试试使用8位传输。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 16:02 , Processed in 0.911611 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号