历史上的今天
今天是:2025年04月27日(星期日)
2020年04月27日 | 多任务 多进程 51单片机C语言 完整版
2020-04-27 来源:eefocus
*/
/*
1.本程序不使用任何汇编指令
2.由定时器T0产生中断,切换进程
3.由于中断或调用子程序,要把PC堆栈,故可以以SP为基址的地方找到PC
4.中断或子程序返回,要把SP出栈给PC,故可以操作SP改变程序入口
5.本程序经调试运行 电路图已上传
6.程序编译是会有一个警告提示,为正常现象,因为保存R0-R7时,重新定义地址,
出现地址覆盖的警告提示。
7.用户以此模板写程序只需写用户的进程子程序和用户初始化子程序,并把各进程参数
放在规定地方,各程序放在规定地方就可以;所有的任务调度已处理好。
*/
//头文件
#include //#include //#include //宏定义 #define uchar unsigned char #define uint unsigned int #define TN 65436 //进程1,2,3执行时间之比为 T1:T2:T3 (时间单位us) #define TN1 55536 //1个进程循环周期内进程1执行的时间T1us TN1=(65536-T1) #define TN2 55536 //1个进程循环周期内进程2执行的时间T2us TN2=(65536-T1) #define TN3 55536 //1个进程循环周期内进程3执行的时间T3us TN3=(65536-T1) // #define N1 4 // 进程1的延时参数 邮箱:niewenli.2007@163.com #define N2 4 // 进程2的延时参数 联系方式:13572614184 #define N3 4 // 进程3的延时参数 QQ:723992349 idata uchar temp[8] _at_ 0x00; //R0--R7 uchar tempbf1[8]; //用于保存R0--R7 进程1 uchar tempbf2[8]; //用于保存R0--R7 进程2 uchar tempbf3[8]; //用于保存R0--R7 进程3 //定义全局变量 uint address1,address2,address3; uchar test1_1=0,test2_1=0,test3_1=0,PID=1; //各进程的标志位,是否为第一次执行,0第一次,非0非第一次;PID进程号; uint ac1,ac2,ac3; //, PC_Next; 各进程的初始地址寄存器. //test1 的参数 由于进程切换时 没有保存普通变量, //所以各进程的普通参数需要定义成全局变量. uint m1,i1,j1,k1; uchar table1[4]; //在此加入 用户进程1参数 //test2 的参数 邮箱:niewenli.2007@163.com int m2,i2,j2,k2; uchar table2[4]; //在此加入 用户进程2参数 //test3 的参数 联系方式:13572614184 int m3,i3,j3,k3; // QQ:723992349 uchar table3[4]; //在此加入 用户进程1参数 //声明 //unsigned int Get_Next_PC(void);//调用子程序,获取PC void chushihua(void); //初始化函数 void yonghuchushihua(void); //用户初始化函数 void test1(void); //进程一 void test2(void); void test3(void); //main函数 void main(void) { // PC_Next=Get_Next_PC(); chushihua(); ac1=(unsigned int)(test1); //获取进程1的入口地址 ac2=(unsigned int)(test2); //获取进程2的入口地址 ac3=(unsigned int)(test3); //获取进程3的入口地址 yonghuchushihua(); TR0=1; while(1); } //初始化时钟 void chushihua(void) { TMOD=0x01; // 邮箱:niewenli.2007@163.com EA=1; // 联系方式:13572614184 ET0=1; // QQ:723992349 TH0=TN/256; TL0=TN%256; } //中断处理,进程调度 void time0() interrupt 1 using 1 { uchar ib; TR0=0; //进程顺序分配 PID++; if(PID==4) {PID=1;} //进程调度 switch(PID) { case 1: { if(test3_1!=0) //第一次否? { //保存现场,还回地址 address3=*((unsigned char *)(SP-4)); //PC的高字节 address3 <<= 8; address3+=*((unsigned char *)(SP-5)); //PC的低字节 table3[0]=*((unsigned char *)(SP)); //现场保护 table3[1]=*((unsigned char *)(SP-1)); //现场保护 table3[2]=*((unsigned char *)(SP-2)); //现场保护 table3[3]=*((unsigned char *)(SP-3)); //现场保护 for(ib=0;ib<=7;ib++) //保护R0--R7 { tempbf3[ib]=temp[ib]; } } if(test1_1==0) //第一次执行 { //执行新进程,恢复现场 test1_1=1; *((unsigned char *)(SP-4))=ac1>>8; //PC的高字节 *((unsigned char *)(SP-5))=ac1 & 0x00ff; //PC的低字节 } else //非第一次执行 { //执行新进程,恢复现场 *((unsigned char *)(SP-4))=address1>>8; //PC的高字节 *((unsigned char *)(SP-5))=address1 & 0x00ff; //PC的低字节 *((unsigned char *)(SP))=table1[0]; //现场恢复 *((unsigned char *)(SP-1))=table1[1]; //现场恢复 *((unsigned char *)(SP-2))=table1[2]; //现场恢复 *((unsigned char *)(SP-3))=table1[3]; //现场恢复 for(ib=0;ib<=7;ib++) //恢复R0--R7 { temp[ib]=tempbf1[ib]; } } TH0=TN1/256; TL0=TN1%256; TR0=1; }break; case 2: { if(test1_1!=0) //第一次否? { //保存现场,还回地址 ,否 address1=*((unsigned char *)(SP-4)); //PC的高字节 address1 <<= 8; address1+=*((unsigned char *)(SP-5)); //PC的低字节 table1[0]=*((unsigned char *)(SP)); //现场保护 table1[1]=*((unsigned char *)(SP-1)); //现场保护 table1[2]=*((unsigned char *)(SP-2)); //现场保护 table1[3]=*((unsigned char *)(SP-3)); //现场保护 for(ib=0;ib<=7;ib++) //保护R0--R7 { tempbf1[ib]=temp[ib]; } } if(test2_1==0) //第一次 { //执行进程2,恢复现场 test2_1=1; *((unsigned char *)(SP-4))=ac2>>8; //PC的高字节 *((unsigned char *)(SP-5))=ac2 & 0x00ff; //PC的低字节 } else //非第一次 { //执行进程2,恢复现场 *((unsigned char *)(SP-4))=address2>>8; //PC的高字节 *((unsigned char *)(SP-5))=address2 & 0x00ff; //PC的低字节 *((unsigned char *)(SP))=table2[0]; //现场恢复 *((unsigned char *)(SP-1))=table2[1]; //现场恢复 *((unsigned char *)(SP-2))=table2[2]; //现场恢复 *((unsigned char *)(SP-3))=table2[3]; //现场恢复 for(ib=0;ib<=7;ib++) //恢复R0--R7 { temp[ib]=tempbf2[ib]; } } TH0=TN2/256; TL0=TN2%256; TR0=1; }break; case 3: { if(test2_1!=0) { //保存现场,还回地址 address2=*((unsigned char *)(SP-4)); //PC的高字节 address2 <<= 8; address2+=*((unsigned char *)(SP-5)); //PC的低字节 table2[0]=*((unsigned char *)(SP)); //现场保护 table2[1]=*((unsigned char *)(SP-1)); //现场保护 table2[2]=*((unsigned char *)(SP-2)); //现场保护 table2[3]=*((unsigned char *)(SP-3)); //现场保护 for(ib=0;ib<=7;ib++) //保护R0--R7 { tempbf2[ib]=temp[ib]; } } if(test3_1==0) { //执行进程3 test3_1=1; *((unsigned char *)(SP-4))=ac3>>8; //PC的高字节 *((unsigned char *)(SP-5))=ac3 & 0x00ff; //PC的低字节 } else { //执行进程3,恢复现场 *((unsigned char *)(SP-4))=address3>>8; //PC的高字节 *((unsigned char *)(SP-5))=address3 & 0x00ff; //PC的低字节 *((unsigned char *)(SP))=table3[0]; //现场恢复 *((unsigned char *)(SP-1))=table3[1]; //现场恢复 *((unsigned char *)(SP-2))=table3[2]; //现场恢复 *((unsigned char *)(SP-3))=table3[3]; //现场恢复 for(ib=0;ib<=7;ib++) //恢复R0--R7 { temp[ib]=tempbf3[ib]; } } TH0=TN3/256; TL0=TN3%256; TR0=1; }break; default: TH0=TN/256; TL0=TN%256; TR0=1; break; } } //以下部分是需要按用户要求添加的部分 void yonghuchushihua(void) //用户初始化函数 { //加入用户初始化函数 } //进程一 P1演示二进制加法 死循环 邮箱:niewenli.2007@163.com void test1(void) { while(1) //用户可以删除while(1)循环中的全部内容(演示用) 安排用户进程 { for(i1=0;i1<256;i1++) { for(k1=0;k1<=N1;k1++) {for(j1=0;j1<=20;j1++) for(m1=0;m1<=113;m1++);} // 约1ms*T1/T1+T2+T3 P1=i1; //P2=0x0; } } } //进程二 P2演示二进制加法 死循环 联系方式:13572614184 void test2(void) { while(1) //用户可以删除while(1)循环中的全部内容(演示用) 安排用户进程 { for(i2=0;i2<256;i2++) { for(k2=0;k2<=N2;k2++) {for(j2=0;j2<=20;j2++) for(m2=0;m2<=113;m2++);} P2=i2; } } } //进程三 P0口演示二进制加法 死循环 进程3的延时参数 QQ:723992349 void test3(void) { while(1) //用户可以删除while(1)循环中的全部内容(演示用) 安排用户进程 { for(i3=0;i3<256;i3++) { for(k3=0;k3<=N3;k3++) {for(j3=0;j3<=20;j3++) for(m3=0;m3<=113;m3++);} P0=i3; } } } /* //获取下一条语句地址:PC unsigned int Get_Next_PC(void) { unsigned int address; address=*((unsigned char *)SP); address <<= 8; address+=*((unsigned char *)(SP-1)); return address+4; } */
史海拾趣
|
缩短PCB设计周期已成为一个常规问题。设计师也面临着电路板技术的急剧变化,如处理速度越来越快,IC封装日趋复杂,从而为本是设计流程中最简单环节的PCB设计增添了复杂性。所以,为了提高设计流程的效率,约束管理工具已愈发变得不可或缺。 虽然 ...… 查看全部问答> |
|
TI 金刚狼 LaunchPad “优惠券” 可以绑定LCD优惠 TI 金刚狼 LaunchPad “优惠券” 在TI 的ESTORE里 TI 金刚狼 LaunchPad有2款,一款是绑定LCD的,价格才29.99美元 那我们自己用“优惠券” … 查看全部问答> |
|
在我烧写FLASH添加.lib文件后,编译就会报错,无法正常烧写进FLASH,但是去掉.lib文件编译就没错误。程序烧写进RAM是没有问题的。求大神解答啊… 查看全部问答> |
|
本帖最后由 曹世鹏 于 2015-5-18 18:57 编辑 最近在做用STM32F103的SPI总线和TI的ADS1247通信读取三线制的PT100的温度值,要求精度为0.5摄氏度。 现在遇到了一些问题。不知道该怎么处理。下面我就把问题总结一下。希望能在论坛里帮我解决一下。 ...… 查看全部问答> |
|
作者: 德州仪器设计工程师谢涌;设计与系统经理Paul Brohlin导读:将GaN FET与它们的驱动器集成在一起可以改进开关性能,并且能够简化基于GaN的功率级设计。氮化镓 (GaN) 晶体管的开关速度比硅MOSFET快很多,从而有可能实现更低的开关损耗。然而, ...… 查看全部问答> |




