历史上的今天
今天是:2024年12月25日(星期三)
2019年12月25日 | 分时复用程序范本51单片机程序框架
2019-12-25 来源:51hei
由于经常涉及到单片机开发,所以需要一个能够跑多任务的程序框架,用操作系统有点儿浪费资源,用普通线程方式又不能执行多任务,所以采取分时复用的方式,来跑多任务。
写一个范本为以后开发服务。
单片机源程序如下:
#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; //键抬起后按键值一次有效 //---------------------------------------------------------------------------------- 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
史海拾趣
|
中国的汽车产业在今年很有可能触及或跨越年产销一千万辆这个门槛,事实上在实现这个目标以前,中国就已经成为仅次于美国的全球第二大汽车市场。在当前的汽车中,汽车电子系统所占的比重越来越大,很多特色化的功能都是依赖汽车电子技术来实现的,如 ...… 查看全部问答> |
|
三、伺服系统调试 接通伺服驱动器的电源, 先进入测试调整模式,测试调整模式可以执行伺服驱动器的测试操作,报警复位和参数编辑等等.其数字操作器的按键说明如表1: 键 出现的情况 MOD 在不同模式 ...… 查看全部问答> |
|
【低功耗】Altera发售带有6.375+Gbps收发器的低功耗FPGA nm Arria II系列是目前发售的功耗最低的6 Gbps收发器解决方案。在支持PCI Express(PCIe)Gen2、SATA III、CPRI一6G、Interlaken和RXAUI等主流协议标准需求的推动下,通常在FPGA 中实现的很多应用都需要高速收发器。而且,系统功耗对设计的限制越来越 ...… 查看全部问答> |
|
求c2000f28027 SCI的例程,官方给的例程都是用.lib的库写的,而且使能了中断却没有给出中断函数,求用操作寄存器的方式的SCI例程。 另外问一下,FIFO不用可以吗,就像51单片机那样 往SBUF里写一个字节,发送一个字节, 谢谢啦… 查看全部问答> |
|
一.正弦波逆变器给负载设备供电的优点 a.无雷电损坏电脑及其它使用交流电的信息设备的顾虑。 b.与使用直流电的信息设备共用-48V机房直流供电,长期工作不间断,无需另配大容量的蓄电池组。   ...… 查看全部问答> |
|
AltiumDesigner14安装破解教程, 最新版的哦,附件有网盘下载地址,,, 是我亲自写的教程哦,欢迎大家下载哈 [ 本帖最后由 High哥 于 2013-11-10 11:37 编辑 ]… 查看全部问答> |




