单片机程序结构
时间片轮询法架构
4. 应用——编写各个任务函数 void TaskDisplayClock() { }
void TaskKeySan()
{ } void TaskLedScan() { }
时间片轮询法架构
4. 应用——编写主函数 v态
//按键释放的状态
按键扫描程序
case key_state_0: // 按键初始态 if (!key_press) key_state = key_state_1;// 键被按下,状态转换到键确认态 break; case key_state_1: // 按键确认态 if (!key_press) { key_return = 1; // 按键仍按下,按键确认输出为“1” key_state = key_state_2;// 状态转换到键释放态 } else key_state = key_state_0; // 按键已抬起,转换到按键初始态 break; case key_state_2: if (key_press) key_state = key_state_0;//按键已释放,转换到按键初始 break; }
灭。 作 者: 创建时间:2014年12月14日 修改时间: 备 注: ***********************************************************************/ #include<reg52.h> //头文件 #include"Key_State.h" //按键扫描头文件
按键扫描程序
/************************************************************************************** 函数名称:按键扫描程序 功
能:检测按键,并返回按键值 返 回 值:key_press 时 间:2014-12-14 备 注: ***************************************************************************************/ unsigned char read_key(void) { static char key_state = 0; //按键的状态 unsigned char key_press; //按键是否被按下 unsigned char key_return = 0; //按键返回值 key_press = key_sr1; // 读按键I/O电? switch (key_state) { ………… } return key_return; //返回按键值 }
//逐个任务时间处理
// 时间不为0 // 运行任务 // 标志清0
时间片轮询法架构
4. 应用——建立任务 static TASK_COMPONENTS TaskComps[] = {
};
{0, 1000, 1000, TaskDisplayClock}, // 显示时钟 {0, 10, 10, TaskKeyScan}, // 按键扫描 {0, 5, 5, TaskLedScan}, // 动态刷新LED // 可以继续添加任务。。。。
2. 任务运行标志出来,此函数就相当于中断服务函数,需要在定时器的中
断服务函数中调用此函数,这里独立出来,并于移植和理解。 voidTaskRemarks(void) { uint8 i; for (i=0; i<Task_Max;i++)//逐个任务时间处理 { if (TaskComps[i].Timer) // 时间不为0 { TaskComps[i].Timer--; // 减去一个节拍 if (TaskComps[i].Timer == 0) // 时间减完了 { TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值 TaskComps[i].Run = 1; // 任务可以运行 } } } }
//LED灯输出
unsigned char Key_Number = 0; //按键值
按键扫描程序
/************************************************************************************ 函数名称:主程序 功
状态机——按键扫描程序
I/O口高电平 I/O口低电平 按键初 始状态 I/O口高电平 I/O口低电平 I/O口高电平 按键释 放状态 执行按键 动作 按键按 下状态
I/O口低电平
按键扫描程序
/*********************************************************************** 名 称:状态机按键扫描 功 能:运用状态机思想,实现按下按键LED点亮,再按一下LED灯熄 sbit Led = P0^7;
{
uint8 Run; // 程序运行标记:0-不运行,1运行 uint8 Timer; // 计时器 uint8 ItvTime; // 任务运行间隔时间 void (*TaskHook)(void); // 要运行的任务函数 } TASK_COMPONENTS;
时间片轮询法架构
按键扫描程序
Key_State.c #include<reg52.h> sbit key_sr1 = P1^6; // 按键输入口 #define key_state_0 #define key_state_1 #define key_state_2
0 //按键的初始状态 1 //按键按下的状态 2 //按键释放的状态
时间片轮询法架构
3. 任务处理,主程序中调用 voidTaskProcess(void) { uint8 i; for (i=0; i<TASKS_MAX; i++) { if (TaskComps[i].Run) { TaskComps[i].TaskHook(); TaskComps[i].Run = 0; } } }
}
InitSys(); while (1) { TaskProcess(); }
// 初始化
// 任务处理
按键扫描程序
unsigned char read_key(void) { }
unsigned char key_press; //按键是否被按下 unsigned char key_return = 0; //按键返回值 key_press = key_sr1; // 读按键I/O电? if(!key_press) { delay(10); key_press = key_sr1; // 读按键I/O电? if(!key_press) key_return = 1; }
按键扫描程序
switch (key_state) { case key_state_0: ………… break; case key_state_1: ………… break; case key_state_2: ………… break; }
// 按键初始态
单片机程序结构
void SysTick_Handler() { if(ADTimer) ADTimer--; if(KeyTimer) KeyTimer--; if(LEDTimer) LEDTimer--; }
时间片轮询法架构
1.设计一个结构体:
// 任务结构 typedef struct _TASK_COMPONENTS
单片机程序结构
单片机程序结构
void main() { sysinit(); moduleInit(); while(1){ if(!ADTimer) { ADTimer=500; 处理AD数据; } if(!KeyTimer) { KeyTimer=10; 扫描按键; }
if(!LEDTimer) { LEDTimer=2; 扫描LED; } if(hp!=rp) { 处理串行接口数据; } } }
能:程序执行的入口 返 回 值:无 时 间:2014-12-14 备 注: ***************************************************************************************/ void main() { while(1) { if(!Key_Timer) { Key_Timer=10; //在定时器内每1Ms增1 Key_Number = read_key(); //按键扫描函数,取得按键值,10MS调用一次 if(Key_Number == 1) //按键返回值是1 Led = ~Led; //LED灯取反 } } }