单片机开发的三种框架:
1、裸机:一个大的while循环,所有逻辑处理全部放在里面运行。
2、时间片轮询:开启一个定时器轮询为每个任务计时,然后置标识位,实际执行在while循环中
2、实时操作系统:FreeRros、RTthread
实战项目时间片轮询:
1、建立任务结构
#define SYSTEM_TASK_MAX_NUM 6 //任务数量
typedef struct system_task
{
unsigned char taskStatus; //任务状态(运行/未运行)
unsigned char taskPriority; //优先级(预留字段)
unsigned int taskCount; //计数
unsigned int taskInterva1; //任务运行时间间隔(单位:ms)
void (* task_function)(void); //回调函数
}system_task_t;
2、使用定制器1,开启1ms中断轮询各任务,为各任务计时,到时间后给对应的任务置位
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1) //1ms
{
for(int i = 0; i < SYSTEM_TASK_MAX_NUM; i++)
{
task_array[i].taskCount++;
if(task_array[i].taskCount == task_array[i].taskInterva1)
{
task_array[i].taskStatus = 1;
}
}
}
}
3、while循环中跟具个任务标志位,执行对应的函数
//注册这些任务
system_task_t task_array[SYSTEM_TASK_MAX_NUM] = {
{0,0,0,50,uart_lcd_task},
{0,0,0,20,encoder_task},
{0,0,0,1,uart_485_task},
{0,0,0,500,board_task},
{0,0,0,50,led_task},
{0,0,0,100,eeprom_24c64_task}
};
int main(void)
{
HAL_Init();
SystemClock_Config();
while (1)
{
for(int i = 0; i < SYSTEM_TASK_MAX_NUM; i++) //任务状态判断执行
{
if(task_array[i].taskStatus == 1)
{
task_array[i].task_function();
task_array[i].taskCount = 0;
task_array[i].taskStatus = 0;
}
}
}
}
配套上面这种架构使用的,把产品的每块功能分成不同的任务,就比如更新串口屏幕显示:
uart_lcd.h
#ifndef __UART_LCD_H
#define __UART_LCD_H
#include "main.h"
#include "log.h"
#include "usart.h"
#include "eeprom.h"
#include "led.h"
#include
//定义该模块的结构体
typedef struct uart_lcd_status
{
unsigned short ledPage;
unsigned short ldPage;
unsigned short ledMode;
unsigned short temp;
unsigned short runTime;
unsigned short linkStatus;
unsigned int lifeTime;
}uart_lcd_status_t;
extern uart_lcd_status_t uartlcd_data;
void uart_lcd_init(void);
void uart_lcd_task(void);
#endif
uart_lcd.c
#include "uart_lcd.h"
uart_lcd_status_t uartlcd_data = {0,0,0,0,0};
uart_lcd_status_t uartlcd_data_old = {0,0,0,0,0};
void uart_lcd_init(void)
{
uart_lcd_version();
memcpy(&uartlcd_data_old,&uartlcd_data,sizeof(uartlcd_data));//同步两结构体
}
void uart_lcd_task(void)
{
if(memcmp(&uartlcd_data,&uartlcd_data_old,sizeof(uartlcd_data)) != 0)//比较结构体是否更新
{
if(uartlcd_data.ldPage != uartlcd_data_old.ldPage)
{
uart_lcd_ld_page(uartlcd_data.ldPage);
}
memcpy(&uartlcd_data_old,&uartlcd_data,sizeof(uartlcd_data));//同步两结构体
}
}