标题:
分时复用程序范本51单片机程序框架
[打印本页]
作者:
rvanji2010
时间:
2019-12-24 22:01
标题:
分时复用程序范本51单片机程序框架
由于经常涉及到单片机开发,所以需要一个能够跑多任务的程序框架,用操作系统有点儿浪费资源,用普通线程方式又不能执行多任务,所以采取分时复用的方式,来跑多任务。
写一个范本为以后开发服务。
单片机源程序如下:
#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<TASK_NUM; 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<TASK_MAX; 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; //键抬起后按键值一次有效
//----------------------------------------------------------------------------------
if(KEY2==0||KEY3==0) //有键正按下
{
if(KEY2==0) key_tem=1;
else if(KEY3==0) key_tem=2;
if (key_tem == key_bak) //有键按下后第一次扫描不处理,与else配合第二次扫描有效,这样实现了去抖动
{
key_time++; //有键按下后执行一次扫描函数,该变量加1
keydown_data=key_tem; //按键值赋予keydown_data
if( (mode==0)&&(key_time>1) )//key_time>1按键值无效,这就是单按,如果mode为1就为连按
keydown_data=0;
}
else //去抖动
{
key_time=0;
key_bak=key_tem;
}
}
else //键抬起
{
if(key_time>2) //按键抬起后返回一次按键值
{
keyup_data=key_tem; //键抬起后按键值赋予keydown_data
}
key_bak=0; //要清零,不然下次执行扫描程序时按键的值跟上次按的值一样,就没有去抖动处理了
key_time=0;
keydown_data=0;
}
//-----------------------------------------------------------------------------------
if(KEY0 == 0);
if(KEY1 == 0);
}
/**************************************************************************************
* FunctionName : TaskKeyProcess()
* Description : 扫描任务
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskKeyProcess(void)
{
switch(keyup_data)
{
case 1:break;
case 2:break;
}
}
/**************************************************************************************
* FunctionName : TaskDispStatusInit()
* Description : 工作状态显示初始化
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskDispStatusInit(void)
{
P5M0 |= 0x20;
P5M1 = 0;
DispStatusLed = 1;
}
/**************************************************************************************
* FunctionName : TaskDispStatus()
* Description : 工作状态显示
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskDispStatus(void)
{
DispStatusLed = ~DispStatusLed;
}
// 这里添加其他任务。。。。。。。。。
复制代码
所有资料51hei提供下载:
42 程序框架.rar
(168.62 KB, 下载次数: 72)
2019-12-24 22:00 上传
点击文件名下载附件
51分时复用程序框架
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1