由于经常涉及到单片机开发,所以需要一个能够跑多任务的程序框架,用操作系统有点儿浪费资源,用普通线程方式又不能执行多任务,所以采取分时复用的方式,来跑多任务。
写一个范本为以后开发服务。
单片机源程序如下:
#include "common.h"
/**************************************************************************************
* Variable definition
**************************************************************************************/
static TASK_COMPONENTS TaskComps[] =
{
{0, 60, 60, TaskDisplay}, // 显示时钟
{0, 20, 20, TaskKeySan}, // 按键扫描
{0, 500, 500, TaskDispStatus}, // 显示工作状态
{0, 0, 0, TaskKeyProcess}, // 按键处理任务
// 这里添加你的任务。。。。
};
void main(void)
{
WDT_Config(); //初始化看门狗
TaskInit(); //任务端口资源初始化
Timer0Init(); //系统时间片管理器初始化
while(1)
{
WDT_CLR(); //喂狗
TaskProcess(); //任务处理函数
if(keyup_data!=0) //有按键按下需要进行处理
TaskComps[3].Run = 1;
}
}
void Timer0Init(void) //1毫秒@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初值
TH0 = 0xF8; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //开启定时器0中断
EA = 1;
}
/**************************************************************************************
* FunctionName : TimerInterrupt()
* Description : 定时中断服务函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void Timer0_Interrupt() interrupt 1
{
uint8 i;
for (i=0; i
{
if (TaskComps[i].Timer) // 时间不为0
{
TaskComps[i].Timer--; // 减去一个节拍
if (TaskComps[i].Timer == 0) // 时间减完了
{
TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次
TaskComps[i].Run = 1; // 任务可以运行
}
}
}
}
/**************************************************************************************
* FunctionName : WDT_Config()
* Description : 看门狗配置
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void WDT_Config(void)
{
WDT_CONTR = 0x04; //看门狗定时器溢出时间计算公式: (12 * 32768 * PS) / FOSC (秒)
//设置看门狗定时器分频数为32,溢出时间如下:
//11.0592M : 1.14s
//18.432M : 0.68s
//20M : 0.63s
//24M : 0.52s
WDT_CONTR |= 0x20; //启动看门狗
}
/**************************************************************************************
* FunctionName : TaskProcess()
* Description : 任务处理
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskProcess(void)
{
uint8 i;
for (i=0; i
{
if (TaskComps[i].Run) // 时间不为0
{
TaskComps[i].TaskHook(); // 运行任务
TaskComps[i].Run = 0; // 标志清0
}
}
}
复制代码
#include "common.h"
//按键扫描变量
uint8 keydown_data=0x00; //按键按下后就返回的值
uint8 keyup_data=0x00; //按键抬起返回值
uint16 key_time=0x00; //按键按下之后的时间计数,该值乘以扫描一次按键函数的时间就等于按键按下的时间
uint8 key_tem=0x00; //长按的按键值与按键扫描程序过渡变量
uint8 key_bak=0x00; //按键扫描程序过渡变量
/**************************************************************************************
* FunctionName : TaskInit()
* Description : 任务配置
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskInit(void)
{
TaskDispStatusInit();
TaskKeySanInit();
}
/**************************************************************************************
* FunctionName : TaskDisplay()
* Description : 显示任务
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskDisplay(void)
{
}
/**************************************************************************************
* FunctionName : TaskKeySanInit()
* Description : 扫描任务初始化
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskKeySanInit(void)
{
P0M0 = 0;
P0M1 = 0;
P0 |= 0x0f;
}
/**************************************************************************************
* FunctionName : TaskKeySan()
* Description : 扫描任务
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskKeySan(void)
{
uint8 mode=0;
keyup_data=0; //键抬起后按键值一次有效
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』