历史上的今天
返回首页

历史上的今天

今天是: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

推荐阅读

史海拾趣

ETERNA公司的发展小趣事

随着中国市场的崛起,ETERNA开始将目光投向了亚洲市场。2011年,中国从德国保时捷家族手中接过ETERNA的旗帜,开始在全球大力拓展ETERNA品牌。在中国市场的推动下,ETERNA的知名度和影响力不断提升。同时,公司还加强了与其他国家和地区的合作与交流,通过参加国际展会和举办品牌活动等方式,进一步扩大了品牌影响力。这些努力使ETERNA在全球电子行业中逐渐崭露头角,成为了一个备受瞩目的品牌。

Freeport Resources Enterprises Corp公司的发展小趣事

为了应对矿业市场的周期性波动和不确定性风险,Freeport Resources实施了多元化经营战略。在保持矿业勘探和开发核心业务的同时,公司还涉足了电子材料贸易、新能源开发等多个领域。通过多元化经营,Freeport Resources有效分散了经营风险,提高了整体抗风险能力。此外,多元化经营还为公司带来了新的增长点,促进了公司的持续健康发展。

EAO公司的发展小趣事

在产品质量方面,EAO公司始终坚持品质至上的原则。公司建立了严格的质量管理体系和检测流程,确保每一件产品都符合高标准的质量要求。同时,EAO公司还注重员工素质的提升和技能培训,确保员工具备专业的技能和知识来保障产品质量。正是这种对品质的坚守和追求,让EAO公司在激烈的市场竞争中赢得了客户的信任和口碑。

请注意,以上故事均为虚构内容,旨在展示EAO公司在电子行业中可能的发展路径和成就。实际情况可能因公司战略、市场环境等因素而有所不同。

HCH Co公司的发展小趣事

背景:随着全球对环境保护和可持续发展的重视程度不断提高,HCH Co公司积极响应号召,开始了绿色转型之路。公司致力于开发环保型电子产品和绿色生产技术,以减少对环境的影响。

发展:通过不断的技术创新和生产工艺的改进,HCH Co公司成功推出了一系列环保型电子产品,如可回收材料制成的外壳、低功耗的显示屏等。同时,公司还加强了废弃电子产品的回收和再利用工作,实现了资源的循环利用。绿色转型不仅提升了公司的社会形象,也为公司的长期发展注入了新的动力。

Alliance Memory公司的发展小趣事

背景:面对电子行业的快速变化和多元化需求,HCH Co公司意识到仅凭一己之力难以应对所有挑战。因此,公司积极寻求与其他行业的跨界合作机会,以共同推动电子行业的创新发展。

发展:通过与汽车、医疗、教育等多个行业的领军企业建立合作关系,HCH Co公司成功将自身的电子技术和产品应用于更广泛的领域。例如,与汽车制造商合作开发智能驾驶系统、与医疗机构合作研发远程医疗设备等。跨界合作不仅为公司带来了新的增长点,也促进了不同行业之间的技术交流和资源共享。未来,HCH Co公司将继续秉承开放合作的理念,与更多行业伙伴携手共创美好未来。

请注意,以上五个故事是基于假设构建的,旨在反映电子行业中企业可能的发展路径和趋势。实际情况中,“HCH Co”公司的具体发展故事可能有所不同。

Adam Tech公司的发展小趣事

为了进一步拓展市场,Adam Tech开始实施全球化战略。公司在北美、欧洲和亚洲等地设立了多个代表处,以便更好地服务全球客户。这些代表处不仅为公司带来了更多的业务机会,也提升了公司在国际市场上的知名度。同时,公司还积极与各地合作伙伴建立紧密的合作关系,共同推动电子连接器行业的发展。

问答坊 | AI 解惑

PIC 8位单片机的分类和特点

PIC 8位单片机的分类和特点 …

查看全部问答>

2010年的汽车电子趋势预测

中国的汽车产业在今年很有可能触及或跨越年产销一千万辆这个门槛,事实上在实现这个目标以前,中国就已经成为仅次于美国的全球第二大汽车市场。在当前的汽车中,汽车电子系统所占的比重越来越大,很多特色化的功能都是依赖汽车电子技术来实现的,如 ...…

查看全部问答>

一个百十来块钱的红外摄像机的测试

现在市场上面1/3 sony红外摄像机才一百多点,这是一台机器的测试效果,不知算不算很差?…

查看全部问答>

伺服系统小结(连续上篇)

三、伺服系统调试   接通伺服驱动器的电源, 先进入测试调整模式,测试调整模式可以执行伺服驱动器的测试操作,报警复位和参数编辑等等.其数字操作器的按键说明如表1: 键 出现的情况 MOD 在不同模式 ...…

查看全部问答>

单片机常用工具

详细全面的有关单片机的常用工具,包括数码管,字模,串口通讯,51定时器等。…

查看全部问答>

【低功耗】Altera发售带有6.375+Gbps收发器的低功耗FPGA

nm Arria II系列是目前发售的功耗最低的6 Gbps收发器解决方案。在支持PCI Express(PCIe)Gen2、SATA III、CPRI一6G、Interlaken和RXAUI等主流协议标准需求的推动下,通常在FPGA 中实现的很多应用都需要高速收发器。而且,系统功耗对设计的限制越来越 ...…

查看全部问答>

求c2000f28027 SCI的例程

求c2000f28027 SCI的例程,官方给的例程都是用.lib的库写的,而且使能了中断却没有给出中断函数,求用操作寄存器的方式的SCI例程。 另外问一下,FIFO不用可以吗,就像51单片机那样 往SBUF里写一个字节,发送一个字节, 谢谢啦…

查看全部问答>

正弦波逆变器与UPS应用的区别

一.正弦波逆变器给负载设备供电的优点     a.无雷电损坏电脑及其它使用交流电的信息设备的顾虑。     b.与使用直流电的信息设备共用-48V机房直流供电,长期工作不间断,无需另配大容量的蓄电池组。   ...…

查看全部问答>

AltiumDesigner14安装破解教程

AltiumDesigner14安装破解教程, 最新版的哦,附件有网盘下载地址,,, 是我亲自写的教程哦,欢迎大家下载哈 [ 本帖最后由 High哥 于 2013-11-10 11:37 编辑 ]…

查看全部问答>