首先是系统的初始化,没什么好说的,无非是关闭Led和蜂鸣器,对照自己的板子上的原理图即可,有锁存器的记得开关锁存器
void system_init(void)
{
//清除GPIO的高八位
GPIOC->ODR &= 0x00ff;
//将GPIO的高八位置为高电平
GPIOC->ODR |= ~(0X00<<8);
//置位GPIO的第二位
GPIOC->BSRR = 0x01<<2;
//复位GPIO的第二位
GPIOC->BRR = 0x01<<2;
}
然后来到这一块的重点,任务调度器。所谓任务调度器是什么,任务调度器就是像你对日常生活时间的安排,如八点起床,九点写作业,十二点吃饭等等,但是有人可能会疑惑,我在51里面将延时变量放到中断里面不也可以做到变量到一定的值就去做任务吗,但是51里面这个思路其实是有点问题的,因为这个思路其实还是一条线做到底,如果中途有一个复杂的函数影响到了我的进程,那么所有的函数都会被滞后,而任务调度器则不会存在这个问题,而是像操作系统一样可以统筹好各个任务,对于任务调度器的实现,代码如下
typedef struct{
void (*task_func)(void); //函数指针
uint32_t rate_ms; //函数运行所需要的时间
uint32_t last_run; //函数上次运行的时间
}task_t;
void led_proc(void)
{
}
//静态任务数组,每个任务包含任务函数、执行周期(毫秒)和上次运行时间(毫秒)
static task_t scheduler_task[]={
{led_proc,1,0}
};
uint8_t task_num; //计数数组
//调度器初始化函数,用来计算静态任务数组中有多少个元素
void scheduler_init(void)
{
task_num = sizeof(scheduler_task)/ sizeof(task_t);
}
//调度器运行函数
void scheduler_run(void)
{
//遍历静态任务数组中的每一个函数
for(uint8_t i=0;i<task_num;i++)
{
//获取我的运行时间
uint32_t now_time = HAL_GetTick();
//如果我的运行时间大于等于函数运行时间与上次运行时间之和,那么就该运行了
if(now_time>=scheduler_task[i].last_run+scheduler_task[i].rate_ms)
{
//上次运行时间更新为现在的时间
scheduler_task[i].last_run = now_time;
//调用函数运行
scheduler_task[i].task_func();
}
}
}
其中对于调度器运行函数有一个点要特别注意就是在if判断那里,我使用的是大于等于,按理来讲等于等于不就可以了吗,这是因为由于函数复杂性的不同,我的运行周期可能并不能如我所期愿的那样,比如100ms的我可能会延迟到102ms,所以使用大于等于