一.题目要求:
在STM32开发板上实现AT命令。PC可通过串口,发送AT命令控制STM32 只可以采用STM32系列,不允许上嵌入式系统
1:设置时间命令
PC发送 AT+TIME = 2022-04-01 12:00:00.
响应:TIME:2022-04-01 12:00:00.
OK
2:查询时间命令
PC发送 AT+TIME?
响应:TIME:2022-04-01 12:00:00.
OK
3: 设定闹钟
PC发送 AT+ALARM=12:00:00
响应:ALTER:12:00:00.
OK
4:读取闹钟
PC发送 AT+ALARM?
响应:ALTER:12:00:00.
OK
5:控制功能
闹钟时间到,打开继电器或LED,并且30秒后关闭。
程序中不允许超过30ms以上的delay延时
二.需求分析:
1. AT指令
是一种用于控制和配置调制解调器的指令语言。它由Hayes公司在20世纪80年代初期开发,并随着调制解调器的普及而成为了一种行业标准。AT代表“Attention”,意思是“注意”,用于指示设备关注后续的命令。AT指令通常通过串行端口发送给调制解调器,用于执行各种操作,如拨号、挂断电话、配置网络设置、查询状态等。尽管最初设计用于模拟调制解调器,但AT指令也被用于控制数字调制解调器和其它类型的通信设备,如GSM模块、3G/4G模块等。
2. 综合考量:
通过五点要求,可以得出我们需要用到的硬件外设资源以及控制逻辑
外设资源:
串口资源:用于PC与单片机通信
RTC外设:Real-Time Clock,在计算机或电子设备中提供准确日期和时间的硬件模块。
定时器外设:用于实现非阻塞延时
GPIO外设资源:用于闹钟响铃后控制继电器等拓展资源执行相应任务
控制逻辑:
串口通信配置:通过串口与PC进行通信。
AT命令解析:编写代码来解析从PC接收到的AT命令。
命令执行:根据解析出的命令执行相应的操作。
响应发送:将执行结果或确认响应回传给PC
三.功能实现:
1.串口通信:
cubeMX中创建工程->选择调试接口(不配置会导致锁死需要串口刷新固件才可重新下载程序)->配置时钟主频为72MHZ->配置usart1外设->记得打开usart中断
编写串口接收中断服务函数回调函数->重定向printf函数
2:设置时间命令
cubeMx中设置RTC模块->勾选前两个,第三个是闹钟功能才会用到的->勾选NVICRTC中断->Config可以保持默认,因后续会封装函数进行更改->Clock模块设置RTC时钟源
代码编写->创建时钟类型结构体,用于存储年月日时分秒信息->顶层封装一个解析命令的函数如下->AT命令解析我所使用的可能太过简单求大佬
编写Set_Time模块->遇到挺大的问题是RTC模块年份设置,年份存储只能是0-99的数值,需要通过基础2000与偏移量得到年份值>本人采用年份大于2000和小于2000分别设置标志位,分别进行处理,将处理的偏移量存储在RTC年份寄存器中->读取时间和存入时间分别处理根据标志位来确定年份
cubeMX生成代码中HAL库给了RTC年月日和时分秒的结构体->将AT_Parse中解析的时间数据通过自定义结构体更新进cubeMX生成的结构体中(或许不需要转存到cubeMX生成的结构体中,直接传入RTC时间设置库函数也可)->记得调用设置RTC时间的函数,不然更新数据只是改变了结构体值,寄存器中的值不会改变->直接将响应指令返回给PC->与PC端联合调试找BUG
3:查询时间命令
同上->类比1指令,并封装Get_Time函数->1功能在设置完时间后会有相应的标志位和与2000的偏移量,通过简单处理即可通过存储的标志位,偏移量信息获取时间信息->通过串口将响应指令传回给PC->与PC联调找BUG
4: 设定闹钟
cubeMX中设置RTC外设->编写代码
同样解析指令->编写Set_Alarm函数->只需处理时分秒信息即可->主要用到的HAL库函数如下,分别为设置闹钟和打开中断的函数->sAlarm中可包含很多闹钟设置的信息,可以自行查询->打印响应指令给PC->与PC联调找BUG
5:读取闹钟
解析指令->编写Get_Alarm函数->主要用到函数如下->PC联调找BUG
6:控制功能
cubeMX->GPIO配置(根据硬件要求设置)->TIM配置(计算72M主频,PSC为72,ARR为1000,计数器溢出一次即为1ms)->NVIC设置各中端优先级->编写代码
RCC闹钟和TIM中断回调函数->因为做的事情比较简单所以直接在中断中执行,也可采用标志位主函数轮询方式执行
到这里进行综合测试->成功完成这一小项目
四.总结:
通过这次项目收获很多,对RTC外设有了较为深入的理解,了解到AT指令的广泛应用,进一步巩固了学习的知识
功能视频:https://b23.tv/RCbaOV5