简单实现 汇编及C语言混合 keil9.0工程源码

发布者:Jikai最新更新时间:2020-04-27 来源: eefocus关键字:汇编及  语言  混合  keil9 手机看文章 扫描二维码
随时随地手机看文章

系统设计核心意图:使用定时器,在延时过程中运行其它的任务。


工程源码:链接: https://pan.baidu.com/s/1LEV9qYmUn6SdemGz7TH6dw 提取码: iua5 

切换任务并记录位置,保证在时间到后能切换回来。(在任务中切换出去,在定时器中切换回来。)(时间片轮转)


可以支持同时8个任务。


工程就两个文件:汇编操作系统rtos_c.asm 及 C语言示例 Test.c


Test.c


/*

开发工具:keil c51 V9.0 及注册机

芯片:标准C8051

晶振:12M

源码任务数:加主任务共4个

2019-05-07

*/

 

//------------------------------------------- 包含文件

#include

//#include

//#include

//----------------------------------------------------多任务处理  以rtos_开头

extern unsigned char rtos_wait(unsigned char time);  //返回实际优先级 ,当所有高优先级都被占用时返回 0FFH,任务将被忽略。time为延时时间

extern rtos_init(unsigned int count); //依据时间片轮转时间后,确定设置定时器count

void task0()

{

P0=0x0FF;

rtos_wait(100);

P0=0x0;

}

void task1()

{

while(1)

{

P1=~P1; //按位取反

rtos_wait(100);

}

}

void task2()

{

while(1)

{

P2=0x0FF;

rtos_wait(200); 

P2=0x0;

rtos_wait(200);

}

}

void main()

{

P0=0; //初始化端口

P1=0;

P2=0;

rtos_init(0xD8F0); //操作系统初始化,根据单片机晶振,设置定时参数,比如10ms

task0(); //第一个任务。没有循环,任务结束就销毁。相当于200*10即2000ms即2s,在延时过程中运行其它的任务。

task1();  //第二个任务 在循环中任务就一直存在。不要以为这是死循环,进入这里后会自动切换到其它任务,时间到后又回来继续执行后面的。

task2();  //第三个任务,类似第二个任务

while(1); //主任务

}

 


rtos_c.asm


;********************************************

;RTOS 用定时器0的多任务处理程序

;项目增加方式使用。

;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务,

;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。

;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。

;占用24H个内存单元。

;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。

;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出

;18.432MHz,单时钟周期模式。不用任务单取反,输出频率 1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。

;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。

;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。

;*********************************************

;------------------------------------------------------------- 示例程序

;extern RTOS(unsigned char priority,time,unsigned int *add);

;extern RTOS_INI(unsigned int count);

;extern RTOS();

;sbit P1_0=P1^0;

;void deng(void)

;{

; P1_0=!P1_0;

; JMP(0,100,deng);

;}

;void main()

;{

; JMP(0,100,deng);

; while(1)

; {

; RTOS();

; }

;}

;***********************************************

NAME RTOS_C

?PR?RTOS?RTOS_C SEGMENT CODE

?DT?RTOS?RTOS_C SEGMENT DATA

?ID?RTOS?RTOS_C SEGMENT IDATA

PUBLIC RTOS

PUBLIC _RTOS_WAIT

PUBLIC _RTOS_INIT

;---------------------------------------------

;BANBH EQU 0A3H ;版本号 101221

;定义数据地址

;----------------------------------------------

RSEG ?DT?RTOS?RTOS_C

;RWZT EQU 29H ;任务状态,0为停止,1为正在执行

TL: DS 1 ;EQU 30H ;RTOS定时器值,C=FFFFH-ft

TH: DS 1 ;EQU 31H ;18.432MHz(12周期)=C400H

RWB: DS 1 ;EQU 33H ;任务表



RSEG ?ID?RTOS?RTOS_C

RWDZ: DS 16

; EQU 80H ;任务地址

; EQU 8FH

RWS: DS 8

; EQU 90H ;任务定时数

; EQU 97H

;*********************************************

        CSEG  AT   0BH         ;TO入口

        JMP     RTOS

;*********************************************

RSEG ?PR?RTOS?RTOS_C


_RTOS_INIT: ;任务初始化 1.定时器启动,2.RWB任务表置0

;-------------------------------------------- 在 R6 R7 中,设置定时值

;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H

;定时器0定时程序,18.432MHz,10MS,方式1

  ORL    TMOD,#01H   ;定时10MS  

          MOV    TL0,R7

          MOV TL,R7

          MOV    TH0,R6

          MOV TH,R6

          MOV RWB,#0

          SETB   TR0

          SETB   ET0

          SETB   EA

          RET                ;等待中断

;********************************************** 等待函数,优先级为最低 0 级,等待时间放入 R7 中

; 目前函数不能传递参数

_RTOS_WAIT: MOV A,R7

MOV R5,A

MOV R7,#0

CALL YXJSZ ;优先级设置

CJNE R7,#8,RWSZ   ;任务设置

MOV R7,#0FFH

RET

;---------------------------------------------任务设置

RWSZ: MOV A,R7 ;送任务数

ADD A,#RWS

MOV R0,A

MOV A,R5

MOV @R0,A

MOV A,R7 ;送地址

RL A

ADD A,#RWDZ

MOV R0,A

POP ACC ;跳转地址,在堆栈中

POP B

MOV @R0,B ;低地址在低字节

INC R0

MOV @R0,A

MOV B,R7 ;设置任务列表 

CLR A ; 当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。

INC B ;可以关中断来解决此问题。

SETB C

RWSZ2: RLC A

DJNZ B,RWSZ2

ORL RWB,A

RET

;--------------------------

YXJSZ: MOV B,R7

INC B

MOV A,RWB

CLR C

YXJ2: RRC A

DJNZ B,YXJ2

YXJ4: JNC YXJ3

RRC A

INC R7

JMP YXJ4

YXJ3: RET


;------------------------------- 中断程序

RTOS: MOV    TH0,TH

MOV    TL0,TL

JB PSW.3,RTOS1

JB PSW.4,RTOS2

PUSH 0

PUSH 1

PUSH 2

PUSH 3

PUSH 4

PUSH 5

PUSH 6

PUSH 7

JMP RTOS0

RTOS1: JB PSW.4,RTOS3

PUSH 8

PUSH 9

PUSH 10

PUSH 11

PUSH 12

PUSH 13

PUSH 14

PUSH 15

JMP RTOS0

RTOS2:

PUSH 10H

PUSH 11H

PUSH 12H

PUSH 13H

PUSH 14H

PUSH 15H

PUSH 16H

PUSH 17H

JMP RTOS0

RTOS3: PUSH 18H

PUSH 19H

PUSH 1AH

PUSH 1BH

PUSH 1CH

PUSH 1DH

PUSH 1EH

PUSH 1FH


RTOS0: PUSH PSW

PUSH ACC

PUSH B

PUSH DPL

PUSH DPH

CALL RWDD0

POP DPH

POP DPL

POP B

POP ACC

POP PSW

JB PSW.3,RTOS01

JB PSW.4,RTOS02

POP 7

POP 6

POP 5

POP 4

POP 3

POP 2

POP 1

POP 0

RETI

RTOS01: JB PSW.4,RTOS3

POP 15

POP 14

POP 13

POP 12

POP 11

POP 10

POP 9

POP 8

RETI

RTOS02:

POP 17H

POP 16H

POP 15H

POP 14H

POP 13H

POP 12H

POP 11H

POP 10H

RETI

RTOS03: POP 1FH

POP 1EH

POP 1DH

POP 1CH

POP 1BH

POP 1AH

POP 19H

POP 18H

RETI

;----------------------------- 中断任务调度

RWDD0: MOV B,#7 ;任务号

MOV R0,#RWS+7

MOV R1,#0FFH ;执行任务号

MOV A,RWB

JNZ RWDD3

RET

RWDD3: CLR C

RLC A

JNC RWDD6

CJNE @R0,#0,RWDD2

RWDD4: CJNE R1,#0FFH,RWDD6

MOV R1,B

RWDD6: DEC R0

DEC B

JNZ RWDD3

CJNE R1,#0FFH,RWCL

RET

RWDD2: DEC @R0

CJNE @R0,#0,RWDD6

JMP RWDD4

;---------------------------------

RWDD: MOV R1,#7

MOV R0,#RWS+7

MOV A,RWB

JNZ RWDD03

RET

RWDD03: CLR C

RLC A

JNC RWDD06

CJNE @R0,#0,RWDD06

JMP RWCL

RWDD06: DEC R0

DEC R1

JNZ RWDD03

RET

;--------------------------------------

RWCL: MOV DPTR,#RWDD

PUSH DPL

PUSH DPH

MOV A,R1

RL A

ADD A,#RWDZ

MOV R0,A

MOV A,@R0

PUSH ACC ;低地址在低字节

INC R0

MOV ACC,@R0

PUSH ACC


MOV A,#0FFH ;清除任务列表  当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,

INC R1 ;可以加入一个执行标志 RWZT 来解决此问题。

CLR C

RWCL22: RLC A

DJNZ R1,RWCL22

ANL RWB,A

RETI

;***********************************

END

 


C语言版切换示例


 


 


#include

 

#define MAX_TASKS 2 //任务槽个数.必须和实际任务数一至

#define MAX_TASK_DEP 12 //最大栈深.最低不得少于2 个,保守值为12.

unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任务堆栈.

unsigned char idata task_sp[MAX_TASKS];

unsigned char task_id; //当前活动任务号

 

//任务切换函数(任务调度器)

void task_switch(){

task_sp[task_id] = SP;

if(++task_id == MAX_TASKS)

task_id = 0;

SP = task_sp[task_id];

}

//任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任

//务,则原任务丢失,但系统本身不会发生错误.

void task_load(unsigned int fn, unsigned char tid){

task_sp[tid] = task_stack[tid] + 1;

task_stack[tid][0] = (unsigned int)fn & 0xff; //低字节

task_stack[tid][1] = (unsigned int)fn >> 8;      //高字节

}

//从指定的任务开始运行任务调度.调用该宏后,将永不返回.

#define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}

/*============================以下为测试代码==========================*/

void task1(){

static unsigned char i;

while(1){

i++;

task_switch();//编译后在这里打上断点

}

}

void task2(){

static unsigned char j;

while(1){

j+=2;

task_switch();//编译后在这里打上断点

}

}

void main(){

//这里装载了两个任务,因此在定义MAX_TASKS 时也必须定义为2

task_load(task1, 0);//将task1 函数装入0 号槽

task_load(task2, 1);//将task2 函数装入1 号槽

os_start(0);

}

关键字:汇编及  语言  混合  keil9 引用地址:简单实现 汇编及C语言混合 keil9.0工程源码

上一篇:51单片机实验17:LCD1602液晶
下一篇:多任务 多进程 51单片机C语言 完整版

推荐阅读最新更新时间:2024-11-06 12:19

单片机C语言程序举例(三)
14.音乐播放 //此程序在硬件上调试通过 //本程序的单片机晶振采用11.0592M #include reg51.h sbit speaker=P1^2; unsigned char timer0h,timer0l,time; //世上只有妈妈好数据表 code unsigned char sszymmh ={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1, 6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2
[单片机]
单片机c语言教程第十三章--C51循环语句
循环语句是几乎每个程序都会用到的,它的作用就是用来实现需要反复进行多次的操 作。如一个 12M 的 51 芯片应用电路中要求实现 1 毫秒的延时,那么就要执行 1000 次空语句 才能达到延时的目的(当然能使用定时器来做,这里就不讨论),如果是写 1000 条空语 句那是多么麻烦的事情,再者就是要占用很多的存储空间。我们能知道这 1000 条空语句, 无非就是一条空语句重复执行 1000 次,因此我们就能用循环语句去写,这样不但使程序 结构清晰明了,而且使其编译的效率大大的提高。在 C 语言中构成循环控制的语句有 while,do-while,for 和 goto 语句。同样都是起到循环作用,但具体的作用和使用方法又大不一 样
[单片机]
数模混合信号测试解决方案
简介 当前电子产品的复杂性正随着数字电路和串行总线越来越多而提高,确定最优测试设备的边界正变得模糊。工程师正在处理“混合信号”设计,其中包含模拟技术和数字技术的重要组合。 设计人员日益希望可以在一台仪器中实现模拟域和数字域时间相关的设备。传统上,混合信号分析使用独立式示 波器和逻辑分析仪完成,这种解决方案需要两台设备,因此并不实用,很难获得最佳效果。模拟波形和数字波形相关的需求导致了混合信号示波器的研制。 示波器、混合信号示波器和逻辑分析仪之间有许多类似之处和差别。为了更好地了解这些仪器怎样满足各自的应用需求,我们有必要更详细地考察一下其各自的功能。 数字示波器 数字示波器是世界各地电子工程师使用的首选工具。设计人员对其
[测试测量]
数模<font color='red'>混合</font>信号测试解决方案
Actel智能型混合信号FPGA现投入生产
爱特公司(Actel Corporation)宣布推出世界首个智能型混合信号FPGA器件SmartFusion™,该产品现正投入批量生产。SmartFusion器件带有Actel经过验证的FPGA架构,该架构包括基于ARM® Cortex™-M3硬核处理器的完整微控制器子系统,以及可编程Flash模拟模块。SmartFusion器件能让嵌入式产品设计人员使用单芯片便能轻易构建所需要的系统,获得全部所需功能,而且无需牺牲产品性能。 Smartgrid Technologies首席技术官David Brain称:“SmartFusion不但为我们提供了构建高度灵活的smartgrid传感器所需的资源,而且还具有更大的灵活
[嵌入式]
电动汽车、混合动力汽车和燃料电池
WP.29为移动电动化做出贡献 WP.29为评估电动汽车(EV)、混合动力电动汽车(HEV)和燃料电池汽车(FCV)的安全和环境性能制定了具有技术要求的法规。这些法规鼓励行业销售这些技术,要求的协调为制造商提供了稳定性和可见性,并且由于规模经济,这些技术以较低的价格提供。- WP.29解决了这些特定技术固有的安全风险,例如电击或火灾或爆炸,例如在发生碰撞时,电动汽车电池或储存在燃料电池汽车中的氢气。 为此,以下是一些相关法规: 联合国第94号条例(正面碰撞保护) 联合国第95号条例(横向碰撞保护) 联合国第100号法规(电气安全) 联合国GTR第20号(电动汽车安全(EVS)) 联合国第136号法规(电动2和3轮车) 联合
[嵌入式]
基于VB语言的机器人足球仿真比赛与对策研究
⒈ 引言   目前,有关机器人足球比赛的国际组织有两个:RoboCup联合会和FIRA组织。比赛项有三个:(1)、小型机器人比赛(Ф≤15cm);(2)、中型机器人比赛(15cm Ф≤50cm);(3)、电脑模拟比赛。在仿真设计中涉及到很多关键性问题,如智能体的体系结构、智能体团队的合作、自学习功能等。采用一种基于行为模式的体系结构,使球员能根据环境和自己的状态来决定当前的行为模式,然后根据该行为模式来决定当前要采取的动作。而团队合作则主要是通过队伍的组建(阵形)实现的。每个阵形是一组角色的集合,不同的角色通过预定的协议来实现合作。本文通过对小型机器人足球比赛仿真组比赛(五对五)的对策进行研究,提出了四步决策推理模型,利用大赛组
[工业控制]
基于VB<font color='red'>语言</font>的机器人足球仿真比赛与对策研究
【东京车展】丰田公开小型HEV“Aqua”的混合动力系统
  丰田2011年11月30日在第42届“东京车展2011”(2011年12月3~11日面向公众开放,东京有明国际会展中心)上,全球首次公开了小型车级别的混合动力车(HEV)“Aqua”以及该车配备的混合动力系统(图1)。该车实现了全球最高燃效,10·15模式下可达到40.0km/L,JC08模式下可达到35.4km/L。丰田此次开发出了比现行HEV“普锐斯”更小的混合动力系统,并将其配备在了小型车级别的车身上。   Aqua的混合动力系统继承了现行普锐斯所配备的“THSII”的设计思想,专门面向Aqua开发而成(图2)。小型车级别的Aqua的底盘无法容纳现行普锐斯的混合动力系统。因此,小型化是开发时的最优先课题。   A
[汽车电子]
单片机C语言程序设计:8X8LED 点阵显示数字
/* 名称:按键控制 8X8LED 点阵屏显 示图形 说明:每次按下 K1 时,会使 8X8LED 点阵屏循环显示不同图形。 本例同时使用外部中断和定 时中断。 */ #include reg51.h #include intrins.h #define uchar unsigned char #define uint unsigned int //待显示图形编码 uchar code M = { {0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00}, //图 1 {0x00,0x38,0x44,0x54,0x44,0x38,0x00,0x00}, //图 2 {0x
[单片机]
单片机C<font color='red'>语言</font>程序设计:8X8LED 点阵显示数字
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved