完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1. 关于延时效果除了HAL_Delay外常用的方法
在这个阶段中做了一个小项目——楼道灯。 因为还未接触到继电器,所以这个小项目是以代码实现的,配置好相应硬件后开始编写代码,其中要实现一个让灯亮的中断条件,这个问题定义几个变量并判断大于或小于某个值、或是处于某个状态就可解决。 此外,要实现楼道灯亮一定时间后自动熄灭的效果,在此考虑的问题较多。在这里的代码实现里,我们在点灯的时候记录当前时间,然后循环获取当前时间看有没有超时,如果超时则控制关灯。 Part1. 实现这一功能作为初学者的自己开始想到的是直接调用HAL_Delay函数进行直接延时,后边在老师指导下才知道,HAL_Delay函数的确可以在这个项目中达到效果,但其实它是低效的,因为用HAL_Delay函数直接延时的话,程序就不能再做其它的控制,其他操作无法进行了。 Part2. 在判断时间是否到没有,我们不能直接用类似 if( (HAL_GetTick() - start) > 3000 )这样的条件判断( 3000是3000ms的意思 ),因为变量的最大记值是有限制的( uint32_t 最大计数到2^32-1 ),而时间是无限的,这样会存在时间回绕的问题。 【PS: 但在如果给出的问题类似 “ 在 xx ms内实现XX操作” 时就可用 if((HAL_GetTick() - start) > 3000 )这样的条件判断,这时这样的判断语句是最常用的。】 Part3. 这里我们参考Linux内核里的jiffies , 回绕解决方案,使用了time_after()这个宏来判断是否超时。这个宏我们需要添加到main.h头文件中。 楼道灯部分代码: int main(void) { uint32_t lux, noisy; uint32_t start = 0; uint8_t light_status = 0; while (1) { if( OFF == light_status) { adc_sample_lux_noisy(&lux, &noisy); printf("Lux[%lu] Noisy[%lu]rn", lux, noisy); if( lux<30 && noisy>800) { turn_led(BlueLed, ON); //turn_relay(Relay2, ON); //继电器 light_status = ON; /* record current time and will turn off in 3 seconds */ start = HAL_GetTick(); } } else { if( time_after(HAL_GetTick(), start+3000) ) { turn_led(BlueLed, OFF); //turn_relay(Relay2, OFF); //继电器 /* must give delay for turn relay off got noisy , it will affect next sample */ HAL_Delay(200); /* set light status as OFF */ light_status = OFF; } } HAL_Delay( 10 ); //在这里可以进行别的希望进行的操作 } } 2.杂 (1)切换1、0对应状态可相应左右移动,后再进行位运算调整。 (2)datasheet对应用到的需更深研究地进行学习效果更好。 (3)不知道的函数之类的不必死扣,百度关键字搜索。 (4)中断向量表里每一个中断服务处理程序都是4个字节,因为32位cpu字长是4个字节(.word),且要按4个字节来补齐,一个中断4个地址存放,中断号不存在或者无用不能删掉,要补0。 (5)函数返回值类型为_weak 说明该函数是可以被重写的,但_weak一定不能不写。 (6)只需1个位控制的只需低16个管脚,而2个位的需32个管脚。 (7)GPIOx_IDR知道管脚当前是高/低电平(先读这个寄存器再获取这个管脚位的值,获取位值:右移当前要看的管脚位,然后做相应取反,看最后输出是1是0),GPIOx_ODR设置一个管脚输出高/低电平(如果设置高电平就用1 或上 1的左移当前管脚序号;低的话就先重复设置高电平的操作,然后再),GPIOx_BSRR控制某一个管脚。(其他寄存器去看datasheet) |
|
|
|
只有小组成员才能发言,加入小组>>
3284 浏览 9 评论
2960 浏览 16 评论
3464 浏览 1 评论
9008 浏览 16 评论
4054 浏览 18 评论
1124浏览 3评论
579浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
572浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2306浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1863浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 09:09 , Processed in 1.228728 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号