一。软件定时器概念及应用
1.软件定时器定义
就是软件实现定时器。
2.FreeRTOS软件定时器介绍
如上图所示,Times的左边为设置定时器时间,设置方式可以为任务设置或者中断设置;Times的右边为定时器的定时响应,使用CallBack响应。
3.FreeRTOS软件定时器工作原理
软件定时器可以参考一下手机的闹钟。单次响应与多次响应。
二。软件定时器函数应用
1.功能需求
- 使用软件定时器功能完成闹钟功能设计
- 当闹钟到达时,可根据执行动作,触发相关的led亮灭
2.API
(1)xTimerCreate()创建一个定时器
(2)xTimerStart()启动定时器
(3) xTimerReset()重启软件定时器
(4)pvTimerGetTimerID()获取软件定时器标识符值
(5)xTimerChangePeriod()修改软件定时器周期值
3.功能设计
如上图所示,需要三个部分,用户在串口端设置时钟参数,RTC作为定时器的核心,并驱动GPIO
(1)串口命令定义
1.设置实时时钟 参数头:年-月-日,小时:分钟:秒 realtime:2019-2-19,16:31:00
2.设置闹钟参数 参数头:小时:分钟:秒,是否重复,操作LED动作 alarmtime:16:32:40,0,0
(2)功能业务划分
1.实时时钟:RTC功能开发
2.命令参数配置:串口解析功能开发
3.软件定时功能:软件定时器
4.多任务消息同步:消息队列
4.功能实现分析
(1)Cubemx配置
1.配置RTC
2.配置串口
3.创建任务
4.创建消息队列
(2)实时时钟读写操作
1.设置实时时钟
2.读取实时时钟
(3)命令解析任务
1.使能串口接收中断
2.串口中断发送消息队列
3.解析命令字符串
4.解析实时时钟字符串
5.解析闹钟字符串
6.计算闹钟与实时时钟间隔
(3)软件定时器回调函数
1.定时器打印实时时钟
2.闹钟回调函数
(4)LED处理任务
LED处理任务
5.功能实现详细步骤
1.Cubemx创建工程
注意:是在物联网操作系统第5节消息队列的基础之上创建工程。
(1)使能RCC低速时钟(LSE)
注意:上述在核心板原理图上
具体解释:
软件实现定时器,需要连接实时时钟,上述图片的晶振是操作实时时钟的晶振,这个晶振连接在低速时钟上,所以我们需要配置低速时钟。
(2)配置RTC
(3)时钟配置为低速的外部时钟
2.FREERTOS配置
(1)软件定时器的配置
(2) 创建控制Led的消息队列
(3)RTC时钟的创建
有一个定时打印的实时功能,所以创建一个RTC的时钟
6.步骤:
1.RTC配置
(1)RTC.h的设置
typedef struct{RTC_TimeTypeDef RtcTime;RTC_DateTypeDef RtcDate;
}RTCTimeDates;void SetRTC(RTCTimeDates *pRTCTimeDate);
RTCTimeDates GetRTC(void);
(2)RTC.c的配置
void SetRTC(RTCTimeDates *pRTCTimeDate){if (HAL_RTC_SetTime(&hrtc, &pRTCTimeDate->RtcTime, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}if (HAL_RTC_SetDate(&hrtc, &pRTCTimeDate->RtcDate, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}
}RTCTimeDates GetRTC(void){RTCTimeDates RTCTimeDate;if (HAL_RTC_GetTime(&hrtc, &RTCTimeDate.RtcTime, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}if (HAL_RTC_GetDate(&hrtc, &RTCTimeDate.RtcDate, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}printf("Real Time:%d-%d-%d %d:%d:%d\n",RTCTimeDate.RtcDate.Year + 2000,RTCTimeDate.RtcDate.Month,RTCTimeDate.RtcDate.Date,RTCTimeDate.RtcTime.Hours,RTCTimeDate.RtcTime.Minutes,RTCTimeDate.RtcTime.Seconds);return RTCTimeDate;
}
2.FREERTOS配置
(1)配置宏
//Ԯࠚޓ˕buff
#define MESSAGE_BUFF_SIZE 50
//ledޓ˕buff
#define LED_MESSAGE_BUFF_SIZE 20
//ʵʱʱדؖػԮͷ
#define REALTIME "realtime"
//ŖדؖػԮͷ
#define ALARMTIME "alarmtime"
//msתۻ
#define ST0MS 1000ul
#define MT0MS (ST0MS*60)
#define HT0MS (MT0MS*60)
#define DT0MS (HT0MS*24)
(2)解析
for(;;){//每次读取消息之前,把索引初始化为0u8Index = 0;//1、一直等待接收消息,第一个消息应该放在消息缓冲区的第一个元素上if(xQueueReceive(CmdQueueHandle,&u8CmdBuff[u8Index++],portMAX_DELAY)==pdPASS){while(xQueueReceive(CmdQueueHandle,&u8CmdBuff[u8Index++],50)){}u8CmdBuff[u8Index] = '\0';//保证一包完整字符串信息vParseString(u8CmdBuff);//完成解析以后,要清空接收缓冲区,不然会出现问题memset(u8CmdBuff,0,20);}}
(3)
其余都在FREERTOS.c中,暂时没有解决