目录
前言
该系列使用STM32HAL库与MDK,芯片是STM32F103C8T6,所有基本环境搭建,与IO基本配置,本章都不详解。主要目的通过LED来区分。延迟性堵塞与非延迟性的区别。
一、延迟函数是什么?
延迟函数:独占性的延迟函数,其在运行时,整个系统都将处于停止等待状态。最常见的等待延迟函数。
代码如下(示例):
/************************************
函数名:Delay_DS
功 能:粗略的延迟函数
参 数:time
返回值:无
*************************************/
void Delay_DS(unsigned int time)
{
unsigned int i,j;
for(i=time ;i>0;i--)
for(j=124;j>0;j--);
}
但这种延迟函数不利于多任务并行,接下来对其进行改造,使其成为软件定时器,具有多任务并行的能力。
二、依靠循环次数的堵塞延迟与非堵塞延迟
1.堵塞延迟
代码如下(示例):已验证
while (1)
{
LED1_ON();
LED3_ON();
Delay_DS(50000);
LED1_Off();
LED3_Off();
Delay_DS(50000);
}
无法使两个小灯以不同的频率闪烁,因为必须等待延迟函数运行完,才会执行下一步。
2.非堵塞性延迟
代码如下(示例):已验证
/*******tim.c***********/
#define Led1_time 60000
#define Led3_time 20000
extern unsigned char LED1_Delay_Flag;
extern unsigned char LED3_Delay_Flag;
extern unsigned int Led1_cnt;
extern unsigned int Led3_cnt;
void Delay_DS(unsigned int time);
void Delay_FDS(void);
/*******tim.c***********/
unsigned int Led1_cnt=0,Led3_cnt=0;
unsigned char LED1_Delay_Flag=0,LED3_Delay_Flag=0;
/************************************
函数名:Delay_DS
功 能:粗略的延迟函数
参 数:time
返回值:无
*************************************/
void Delay_FDS(void)
{
if(Led1_cnt)
{
Led1_cnt--;
if(!Led1_cnt)
LED1_Delay_Flag=1;
}
if(Led3_cnt)
{
Led3_cnt--;
if(!Led3_cnt)
LED3_Delay_Flag=1;
}
}
/*******main.c***********/
int main(void)
{
unsigned char LED1_flag=1,LED3_flag=1;
while (1)
{
Led1_cnt=Led1_time;
Led3_cnt=Led3_time;
while(1)
{
if(LED1_Delay_Flag)
{
LED1_Delay_Flag=0;//清除延迟完成标志位
Led1_cnt=Led1_time;//重新赋值
if(LED1_flag)//亮灭标志位
{
LED1_ON();
LED1_flag=0;
}
else
{
LED1_Off();
LED1_flag=1;
}
}
if(LED3_Delay_Flag)
{
LED3_Delay_Flag=0;
Led3_cnt=Led3_time;
if(LED3_flag)
{
LED3_ON();
LED3_flag=0;
}
else
{
LED3_Off();
LED3_flag=1;
}
}
Delay_FDS();
}
}
}
这样便能实现两个LED以不同频率闪烁,但随着任务数变多,主循环的时基也会变长。接下来通过定时器确定稳定的时基。
三、依靠多路软件定时器非堵塞延迟
配置定时器的中断为1MS, 定义不同时间段的任务,来执行不同动作,即分时调度。
代码如下(示例):已验证
/***************tim.h*************/
#define Task_1MS 1
#define Task_10MS 10
#define Task_100MS 100
#define Task_250MS 250
#define Task_500MS 500
#define Task_1S 1000
#define Task_5S 5000
#define Task_10S 10000
extern unsigned int Task_1MS_cnt;
extern unsigned int Task_10MS_cnt;
extern unsigned int Task_100MS_cnt;
extern unsigned int Task_250MS_cnt;
extern unsigned int Task_500MS_cnt;
extern unsigned int Task_1S_cnt;
extern unsigned int Task_5S_cnt;
extern unsigned int Task_10S_cnt;
extern unsigned int Task_1MS_flag;
extern unsigned int Task_10MS_flag;
extern unsigned int Task_100MS_flag;
extern unsigned int Task_250MS_flag;
extern unsigned int Task_500MS_flag;
extern unsigned int Task_1S_flag;
extern unsigned int Task_5S_flag;
extern unsigned int Task_10S_flag;
/***************tim.c*************/
unsigned int Task_1MS_cnt=0;
unsigned int Task_10MS_cnt=0;
unsigned int Task_100MS_cnt=0;
unsigned int Task_250MS_cnt=0;
unsigned int Task_500MS_cnt=0;
unsigned int Task_1S_cnt=0;
unsigned int Task_5S_cnt=0;
unsigned int Task_10S_cnt=0;
unsigned int Task_1MS_flag=0;
unsigned int Task_10MS_flag=0;
unsigned int Task_100MS_flag=0;
unsigned int Task_250MS_flag=0;
unsigned int Task_500MS_flag=0;
unsigned int Task_1S_flag=0;
unsigned int Task_5S_flag=0;
unsigned int Task_10S_flag=0;
/************************************
函数名:HAL_TIM_PeriodElapsedCallback
功 能:1MS定时器中断回调函数
参 数:htim
返回值:无
*************************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim2.Instance)
{
//All_LED_ON();
Task_1MS_cnt--;
Task_10MS_cnt--;
Task_100MS_cnt--;
Task_250MS_cnt--;
Task_500MS_cnt--;
Task_1S_cnt--;
Task_5S_cnt--;
Task_10S_cnt--;
if(!Task_1MS_cnt)
{
Task_1MS_cnt=Task_1MS;
Task_1MS_flag=1;
}
if(!Task_10MS_cnt)
{
Task_10MS_cnt=Task_10MS;
Task_10MS_flag=1;
}
if(!Task_100MS_cnt)
{
Task_100MS_cnt=Task_100MS;
Task_100MS_flag=1;
}
if(!Task_250MS_cnt)
{
Task_250MS_cnt=Task_250MS;
Task_250MS_flag=1;
}
if(!Task_500MS_cnt)
{
Task_500MS_cnt=Task_500MS;
Task_500MS_flag=1;
}
if(!Task_1S_cnt)
{
Task_1S_cnt=Task_1S;
Task_1S_flag=1;
}
if(!Task_5S_cnt)
{
Task_5S_cnt=Task_5S;
Task_5S_flag=1;
}
if(!Task_10S_cnt)
{
Task_10S_cnt=Task_10S;
Task_10S_flag=1;
}
}
}
/***************main.c*************/
int mian (void)
{
unsigned char LED1_flag=1,LED3_flag=1,LED4_flag=1;
while (1)
{
Task_1MS_cnt = Task_1MS;
Task_10MS_cnt = Task_10MS;
Task_100MS_cnt = Task_100MS;
Task_250MS_cnt = Task_250MS;
Task_500MS_cnt = Task_500MS;
Task_1S_cnt = Task_1S;
Task_5S_cnt = Task_5S;
Task_10S_cnt = Task_10S;
while(1)
{
if(Task_1S_flag)
{
Task_1S_flag=0;
if(LED1_flag)
{
LED1_ON();
LED1_flag=0;
}
else
{
LED1_Off();
LED1_flag=1;
}
}
if(Task_5S_flag)
{
Task_5S_flag=0;
if(LED3_flag)
{
LED3_ON();
LED3_flag=0;
}
else
{
LED3_Off();
LED3_flag=1;
}
}
if(Task_10S_flag)
{
Task_10S_flag=0;
if(LED4_flag)
{
LED4_ON();
LED4_flag=0;
}
else
{
LED4_Off();
LED4_flag=1;
}
}
}
}
实物视频如下
总结
对延迟函数的理解,以及引出分时调度,小菜鸡刚上路,如有错误,请指教。