stc系列单片机μCOSⅡ在C8051F系列单片机上的移植及其应用系统开发
单片机IIC程序设计用c8051f单片机

#include <c8051f020.h> // SFR declarations//------------------------------------------------------------------------------------// Global CONSTANTS//------------------------------------------------------------------------------------#define WRITE 0x00 // SMBus WRITE command#define READ 0x01 // SMBus READ command// Device addresses (7 bits, lsb is a don't care)#define CLOCK3530_ADDRESS_RESET 0x60 //1 ack#define CLOCK3530_ADDRESS_STATUS 0x62 //2 ack#define CLOCK3530_ADDRESS_DATEHOUR 0x64 //8 ack year month day week hour minute second#define CLOCK3530_ADDRESS_HOUR 0x66 //4 ack hour minute second#define CLOCK3530_ADDRESS_INT1 0x68 //3 ack#define CLOCK3530_ADDRESS_INT2 0x6A //3 ackunion{unsigned char ClockString[7];struct RealClock{unsigned char Year,Month,Day,Week,Hour,Minute,Second;} RT;} RealTime;// SMBus states:// MT = Master Transmitter// MR = Master Receiver#define SMB_BUS_ERROR 0x00 // (all modes) BUS ERROR#define SMB_START 0x08 // (MT & MR) START transmitted#define SMB_RP_START 0x10 // (MT & MR) repeated START#define SMB_MTADDACK 0x18 // (MT) Slave address + W transmitted;// ACK received#define SMB_MTADDNACK 0x20 // (MT) Slave address + W transmitted;// NACK received#define SMB_MTDBACK 0x28 // (MT) data byte transmitted; ACK rec'vd #define SMB_MTDBNACK 0x30 // (MT) data byte transmitted; NACK rec'vd#define SMB_MTARBLOST 0x38 // (MT) arbitration lost#define SMB_MRADDACK 0x40 // (MR) Slave address + R transmitted;// ACK received#define SMB_MRADDNACK 0x48 // (MR) Slave address + R transmitted;// NACK received#define SMB_MRDBACK 0x50 // (MR) data byte rec'vd; ACK transmitted #define SMB_MRDBNACK 0x58 // (MR) data byte rec'vd; NACK transmitted//-----------------------------------------------------------------------------------//Global V ARIABLES//-----------------------------------------------------------------------------------char COMMAND; // Holds the slave address + R/W bit for use in the SMBus ISR. unsigned char *I2CDataBuff;char BYTE_NUMBER; // Used by ISR to check what data has just been// sent - High address byte, Low byte, or data byteunsigned char HIGH_ADD, LOW_ADD; // High & Low byte for EEPROM memory addressbit SM_BUSY; // This bit is set when a send or receive// is started. It is cleared by the// ISR when the operation is finished.//------------------------------------------------------------------------------------// Function PROTOTYPES//------------------------------------------------------------------------------------void SMBus_ISR (void);//------------------------------------------------------------------------------------// MAIN Routine//------------------------------------------------------------------------------------//// Main routine configures the crossbar and SMBus, and tests// the SMBus interface between the three EEPROMsvoid ResetRealClock(void){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 0; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_RESET | READ); // Chip select + READ STA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish }//======================写S-3530A内部实时数据寄存器程序=====================//功能:将设定年、月、日、星期、时、分、秒数据写入S-3530A |//入口:发送数据放在年、月、日、星期、时、分、秒各寄存器|//出口:NONE |//===================================================================== =====void SetRealClock(void){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 7; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | WRITE); // Chip select + WRITEI2CDataBuff = &RealTime.ClockString[0]; // Data to be writenSTA = 1; // Start transfer}//==================读S-3530A实时数据寄存器子程序===========================//功能:从S-3530A读入当前时间数据|//入口:NONE |//出口:接收数据放在年、月、日、星期、时、分、秒各寄存器|//===================================================================== =====void GetRealClock(void){while (SM_BUSY); // Wait for SMBus to befree.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 7; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | READ); // Chip select + READI2CDataBuff = &RealTime.ClockString[0]; // Data to be writenSTA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish }//============================写状态寄存器程序==============================//功能:读/写S-3530A状态寄存器,对S-3530A进行设置|//入口:NONE 出口:NONE | //===================================================================== =====unsigned char GetRealClockStatus(void){unsigned char result;while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 1;COMMAND = (CLOCK3530_ADDRESS_STATUS | READ);I2CDataBuff = &result;STA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish return result;}void SetRealClockStatus(unsigned char status){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 1;COMMAND = (CLOCK3530_ADDRESS_STA TUS | WRITE);I2CDataBuff = &status;STA = 1; // Start transfer}/*void SetRealClockINT1(unsigned int Int1){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 2;COMMAND = (CLOCK3530_ADDRESS_INT1 | WRITE);I2CDataBuff = (unsigned char*)&Int1;STA = 1; // Start transfer}*/#include "INTRINS.H"unsigned char revolve(unsigned char val){char i;unsigned char val1=0;for (i=0;i<8;i++){if (val&0x1)val1++;val1=_crol_(val1,1);val=_cror_(val,1);}val1=_cror_(val1,1);return val1;}/*-- 文字: 时--*/char code Shi[]={0x00,0x00,0xFC,0x44,0x44,0xFC,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x08,0x08,0x00, 0x00,0x00,0x1F,0x04,0x04,0x0F,0x00,0x00,0x00,0x11,0x20,0x1F,0x00,0x00,0x00,0x00, };/*-- 文字: 钟--*/char code Zhong[]={0x00,0x60,0x38,0xE7,0x24,0x24,0x04,0x00,0xF8,0x88,0x88,0xFF,0x88,0x88,0xF8,0x00, 0x00,0x01,0x01,0x3F,0x11,0x09,0x01,0x00,0x01,0x00,0x00,0x3F,0x00,0x00,0x01,0x00, };void LCD_WriteHZ(char x,char y,char *Dot);void LCD_DispChar(char x,char y,char ch); //128*64 取值x=0-128 y=0-8void InitLCD(void);void Delay1ms(unsigned char T);void TestI2C (void){unsigned char var ;WDTCN = 0xde; // disable watchdog timerWDTCN = 0xad;OSCICN |= 0x03; // Set internal oscillator to highest setting// (16 MHz)XBR0 |= 0x07; // Route SMBus to GPIO pins through crossbarXBR2 |= 0x44; // Enable crossbar and weak pull-upsP0MDOUT |= 0x1D;P1MDOUT |= 0x01;SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge cycleSMB0CR = -80; // SMBus clock rate = 100kHz.EIE1 |= 2; // SMBus interrupt enableEA = 1; // Global interrupt enableSM_BUSY = 0; // Free SMBus for first transfer.// SetRealClockINT1(0x8000);var = GetRealClockStatus();ResetRealClock();var = GetRealClockStatus();SetRealClockStatus(0xc2);var = GetRealClockStatus();GetRealClock();RealTime.RT.Year=0x02;RealTime.RT.Month=0x12;RealTime.RT.Day=0x010;RealTime.RT.Week=0x05;RealTime.RT.Hour=0x11;RealTime.RT.Minute=0x59;RealTime.RT.Second=0x57;SetRealClock();GetRealClock();InitLCD();LCD_WriteHZ(0,0,Shi);LCD_WriteHZ(16,0,Zhong);//在0,2处显示00:00:00LCD_DispChar(0,2,0); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,2,0);LCD_DispChar(16,2,10);LCD_DispChar(24,2,0);LCD_DispChar(32,2,0);LCD_DispChar(40,2,0xa);LCD_DispChar(48,2,0);LCD_DispChar(56,2,0);//在0,4处显示02/01/01LCD_DispChar(0,4,0); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,4,2);LCD_DispChar(16,4,0xb);LCD_DispChar(24,4,0);LCD_DispChar(32,4,1);LCD_DispChar(40,4,0xb);LCD_DispChar(48,4,0);LCD_DispChar(56,4,1);for (;;){GetRealClock();LCD_DispChar(0,2,(RealTime.RT.Hour>>4)&0x03);//(RealTime.RT.Hour>>4)&0x0f); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,2,RealTime.RT.Hour&0x0f);LCD_DispChar(24,2,(RealTime.RT.Minute>>4)&0x0f);LCD_DispChar(32,2,RealTime.RT.Minute&0x0f);LCD_DispChar(48,2,(RealTime.RT.Second>>4)&0x0f);LCD_DispChar(56,2,RealTime.RT.Second&0x0f);//在0,4处显示02/01/01LCD_DispChar(0,4,(RealTime.RT.Year>>4)&0x0f);LCD_DispChar(8,4,RealTime.RT.Year&0x0f);LCD_DispChar(24,4,(RealTime.RT.Month>>4)&0x0f);LCD_DispChar(32,4,RealTime.RT.Month&0x0f);LCD_DispChar(48,4,(RealTime.RT.Day>>4)&0x0f);LCD_DispChar(56,4,RealTime.RT.Day&0x0f);Delay1ms(100);}}//------------------------------------------------------------------------------------// Interrupt Service Routine//------------------------------------------------------------------------------------void SMBUS_ISR (void) interrupt 7{switch (SMB0STA){ // SMBus 状态码SMB0STA 寄存器// 主发送器/接收器起始条件已发送case SMB_START:SMB0DAT = COMMAND ; // 装入要访问的从器件的地址STA = 0; // 手动清除START 位break;//主发送器/接收器重复起始条件已发送// 该状态只应在读操作期间出现在存储器地址已发送并得到确认之后?case SMB_RP_START:SMB0DAT = COMMAND; // COMMAND 中应保持从地址+ R.STA = 0;break;// 主发送器从地址+ WRITE 已发送收到ACKcase SMB_MTADDACK:// 主发送器数据字节已发送收到ACKcase SMB_MTDBACK:if (BYTE_NUMBER){SMB0DAT = revolve(*I2CDataBuff); // If R/W=WRITE, load byte to write.I2CDataBuff++;BYTE_NUMBER--;}else{STO = 1; SM_BUSY = 0; // Free SMBus}break;// 主发送器从地址+ WRITE 已发送收到NACK// 从器件不应答发送STOP + START 重试case SMB_MTADDNACK:STO = 1; STA = 1;break;// 主发送器数据字节已发送收到NACK// 从器件不应答发送STOP + START 重试case SMB_MTDBNACK:STO = 1; STA = 1;break;// 主发送器竞争失败// 不应出现如果出现重新开始传输过程case SMB_MTARBLOST:STO = 1; STA = 1;break;// 主接收器从地址+ READ 已发送,收到ACKcase SMB_MRADDACK:AA = 1; // 在应答周期ACKif (!BYTE_NUMBER){STO = 1; SM_BUSY = 0; // 释放SMBus}break;// 主接收器从地址+ READ 已发送收到NACK// 从器件不应答发送重复起始条件重试case SMB_MRADDNACK:STA = 1;break;// 收到数据字节ACK 已发送// 该状态不应出现因为AA 已在前一状态被清0 如果出现发送停止条件case SMB_MRDBACK:if (BYTE_NUMBER){*I2CDataBuff=revolve(SMB0DA T);I2CDataBuff++;BYTE_NUMBER--;}if (!BYTE_NUMBER) AA= 0;break;// 收到数据字节NACK 已发送// 读操作已完成读数据寄存器后发送停止条件case SMB_MRDBNACK:STO = 1;SM_BUSY = 0; // 释放SMBusbreak;// 在本应用中所有其它状态码没有意义通信复位default:STO = 1; // 通信复位SM_BUSY = 0;break;}SI=0; // 清除中断标志}/*{switch (SMB0STA){ // Status code for the SMBus (SMB0STA register) case SMB_START:SMB0DAT = COMMAND; // COMMAND should hold slave address + R.break;case SMB_MTADDNACK:STO = 1;STA = 1;break;case SMB_RP_START:// SMB0DAT = COMMAND; // COMMAND should hold slave address + R.// STA = 0;// break;case SMB_MTADDACK:case SMB_MTDBACK:if (BYTE_NUMBER){if (COMMAND & 0x01) // If R/W=READ,{STA = 1;}else{SMB0DAT = *I2CDataBuff; // If R/W=WRITE, load byte to write.I2CDataBuff++;BYTE_NUMBER--;}}else{STO = 1;SM_BUSY = 0; // Free SMBus}break;// Master Transmitter: Data byte transmitted. NACK received.// Slave not responding. Send STOP followed by START to try again.case SMB_MTDBNACK:STO = 1;STA = 1;break;// Master Transmitter: Arbitration lost.// Should not occur. If so, restart transfer.case SMB_MTARBLOST:STO = 1;STA = 1;break;// Master Receiver: Slave address + READ transmitted. NACK received.// Slave not responding. Send repeated start to try again.case SMB_MRADDNACK:STA = 1;break;// Data byte received. ACK transmitted.// State should not occur because AA is set to zero in previous state.// Send STOP if state does occur.case SMB_MRDBACK:STO = 1;SM_BUSY = 0;break;// Master Receiver: Slave address + READ transmitted. ACK received.// Set to transmit NACK after next transfer since it will be the last (only) byte.case SMB_MRADDACK:// AA = 0; // NACK sent on acknowledge cycle.// break;// Data byte received. NACK transmitted.// Read operation has completed. Read data register and send STOP.case SMB_MRDBNACK:if (BYTE_NUMBER){if (COMMAND & 0x01) // If R/W=READ,{*I2CDataBuff=SMB0DA T;I2CDataBuff++;}BYTE_NUMBER--;}else{STO = 1;SM_BUSY = 0; // Free SMBus}break;// All other status codes meaningless in this application. Reset communication.default:STO = 1; // Reset communication.SM_BUSY = 0;break;}SI=0; // clear interrupt flag }*/。
uCOS在C51单片机上的移植

uCOS-II 在C51 单片机上的移植(1)实时系统和前/后台系统;前/后台系统:一个大循环,循环查询各种标志位。
如果标志位置位,就执行相应的服务程序。
标志位就是标志事件的发生,事件响应延时处于不可预测状态。
最坏的情况是循环中所有其他的事件服务程序执行完,才响应当前事件。
中断服务虽然能即时/优先响应,但是它们和主循环的通讯,也是通过置主循环中相应的标志位来完成的。
实时系统(uCOS):整个程序分成一个个看起来好象是并行的任务,每个任务都在等待事件的发生。
因为uCOS不支持时间片轮转,除了最低优先级任务(在uCOS中是IDLE任务)是死循环以外,其他的任务都不能死循环,只能在驱动事件驱动下工作。
任何驱动事件的产生,都使优先级最高的就绪任务运行。
任务和任务/任务和中断的通讯,是通过相应事件驱动来完成的。
驱动事件:不论是什么系统,CPU不可能一直在工作。
CPU的工作是在各种驱动事件的驱动下工作的。
CPU在完成一次驱动事件事件服务程序以后,进入IDLE模式等待新的驱动事件的发生。
包括实时系统和前/后台系统都是在驱动事件的驱动下运行的。
按照uCOS中的观点,驱动事件分为三类:1、事件(Event)。
包括信号量(Semaphores)、事件标志组(Flag)、邮箱(Message Box)、邮箱队列(Message Queue)。
2、时间(Time Tick)。
包括时间延时和事件超时。
3、中断(Interrupt)。
可以发出各种event。
由于第1种事件,通常都是在第2、3种状态下发出的,所以其实事件的驱动只有两种:时间(定时)和中断(各种异步中断)。
时间实际上也是中断的一种,可以说程序的驱动事件只有一种,就是:中断。
前/后台系统中还有一种驱动事件的产生,在主循环中不断的查询。
有别与一般的定时查询,这种查询是为了将事件的响应时间降到最低,也可以将其归纳于定时(时间)事件。
(2)uCOS C51移植的准备工作;2004年8月份,我在书城买了一本《uCOS-Ⅱ第2版》,准备学习RTOS。
uCOS-II在51单片机上的移植

#if OS_CRITICAL_METHOD = = 3 #define OS_ENTER_CRITICAL() ?? #define OS_EXIT_CRITICAL() ?? #endif
#define OS_STK_GROWTH
1
#define OS_TASK_SW()
???
9
7.1.8 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()
功能
处理临界段方式选择 堆栈增长方向 进入临界区 退出临界区 就绪态最高优先级任务运行 任务级任务切换 中断级任务切换 时钟节拍 任务堆栈初始化
表7-1 需要修改的关键函数和宏定义
6
7.1.6 INCLUDES.H
❖ 使得项目中的每个.c文件不用分别考虑它实际上需要那些头文件。 ❖ 它会包含一些不相关的头文件 ❖ INCLUDES.H 是一个头文件,它在所有的.c文件的第一行被包含。 ❖ #include “includes.h”
/***************************************************************************
*
uC/OS-II 实时内核
*
(c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
*
版权所有
方法1:
asm(“DI”);
在OS_ENTER_CRITICAL()中调用处理器指令来禁止#中def断ine ,OS以_EX及IT在_CRITICAL() \
OS_EXIT_CRITICAL()中调用允许中断指令。
asm(“POP PSW”);
方法2:
基于实时多任务操作系统μCOS-Ⅱ的C8051F系列单片机应用系统开发

基于实时多任务操作系统μCOS-Ⅱ的C8051F系列单片机应
用系统开发
黄亮亮;朱欣华
【期刊名称】《测控技术》
【年(卷),期】2005(024)009
【摘要】介绍了μCOS-Ⅱ的工作原理及C8051F系列单片机的特点,讨论了将
μCOS-Ⅱ移植到C8051F040单片机应用系统中的方法.应用系统实现了串口通信及CAN通信等任务.
【总页数】4页(P39-42)
【作者】黄亮亮;朱欣华
【作者单位】东南大学,仪器科学与工程系,江苏,南京,210096;东南大学,仪器科学与工程系,江苏,南京,210096
【正文语种】中文
【中图分类】TP316;TP368
【相关文献】
1.基于C8051F040的实时操作系统μC/OS-Ⅱ的移植 [J], 朱光远;徐海贤
2.基于实时操作系统的单片机应用系统设计 [J], 吴强;黄石红;沈玲玲
3.嵌入式实时操作系统μCOS-Ⅱ基于ARM9移植 [J], 廖临光;纪金水;杨筱平
4.一种用于PC系列微机的实时多任务操作系统 [J], 刘晓蕙;冯欣
5.基于C8051F系列单片机应用选型的教学改革研究 [J], 桑胜举;李芳;吴月英
因版权原因,仅展示原文概要,查看原文内容请购买。
C8051F系列单片机的发展和应用

C8051F系列单片机的发展和应用摘要:C8051F系列单片机的推出,使单片机进入SoC ( System on Chip )时代。
C8051F系列单片机功能强大,能够作为嵌入式系统的主控制器,具有上手快(全兼容8051指令集)、研发快(开发工具易用,可缩短研发周期)和见效快(调试手段灵活)等特点,使得C8051F系列单片机得到广泛的应用。
本文首先对C8051F 系列单片机做了大概的介绍,之后详细分析说明了它的原理机制,介绍了C8051F 系列单片机的特点,阐述了它的发展和应用。
关键词:C8051F SoC 发展应用前言在嵌入式系统低端的单片机领域, 80C51系列一直扮演着一个重要角色,近年来,由于80C51的速度低(每一条指令至少需要12个时钟周期) ,功耗高(几毫安到几十毫安) ,功能少(不能直接处理模拟信号)等等, 80C51系列单片机似乎已经走道了尽头,然而当前CYGNAL公司推出的C8051F系列单片机又将80C51兼容单片机推上了8位机的先进行列,使80C51系列从MCU时代进入到了SoC ( System on Chip )时代。
SoC是随着半导体生产技术的不断发展而产生的新概念,它是集成度越来越高和对嵌入式控制技术可靠性越来越高的产物[1]。
SoC是指片上系统或系统级芯片, SoC的完整定义为:在同一个芯片上集成了控制部件(微处理器,存储器)和执行部件( I/O接口,微型开关,微机械) ,能够自成体系,独立工作的芯片。
因此, C8051F系列单片机功能强大,能够作为嵌入式系统的主控制器。
本文主要介绍了C8051F系列单片机的特点,以及它的发展和应用。
一 C8051F系列单片机简介C8051F系列单片机是完全集成的混合信号系统级芯片,具有与8051兼容的CIP-51微控制器内核,采用流水线结构,单周期指令运行速度是8051的12倍,全指令集运行速度是原来的9.5倍。
C8051F020的内部电路包括CIP-51微控制器内核及RAM、ROM、I/O 口、定时/计数器、ADC、DAC、PCA(Printed Circuit Assembly 印制电路组装)、SPI(Serial Peripheral Interface--串行外设接口)和SMBus(System Management Bus)等部件,即把计算机的基本组成单元以及模拟和数字外设集成在一个芯片上,构成一个完整的片上系统(SoC) [2]。
UCOS-II在51单片机上的移植

UCOS-II在51单片机上的移植做操作系统的移植首先明白什么是移植,操作系统是一种鱼硬件(处理器)相关的软件,根据某一种处理器来设计的操作系统通常不能运行在那其他处理器。
所谓的移植是指修改操作系统,然后加载到一个处理器上。
本文只讲解步骤,至于理论知识,需要大家自己学习。
步骤:1,在UCOS-II的官网上下载,操作系统。
2,在网上找到或者自己建三四个文件:OS_CPU_A.ASSMOS_CPU.HOS_CPU_C.COS_CFG.H以上文件需要修改3,移植源码的编写和修改❖OS_CPU.H1)定义与编译器有关的数据类型typedef unsigned char BOOLEAN; /* 不能使用bit定义,结构中无法使用*/typedef unsigned char INT8U; /* 无符号8位数*/typedef unsigned char INT8S; /* 有符号8位数*/typedef unsigned int INT16U; /* 无符号16位数*/typedef signed int INT16S; /* 有符号16位数*/typedef unsigned long INT32U; /* 无符号32位数*/typedef signed long INT32S; /* 有符号32位数*/typedef float FP32; /* 单精度浮点数*/typedef double FP64; /* 双精度浮点数*/typedef unsigned char OS_STK; /* 定义堆栈入口宽度为8位*/typedef unsigned char OS_CPU_SR; /* 定义CPU状态字的宽度为8位*/2)定义堆栈增长方向#define OS_STK_GROWTH 0 /* MCS-51堆栈从下往上增长,1=向下,0=向上*/3)定义任务级的任务切换宏#define OS_TASK_SW() OSCtxSw() /* 任务级的任务切换宏*/4)定义临界段宏:#define OS_ENTER_CRITICAL() EA=0#define OS_EXIT_CRITICAL() EA=1❖OS_CPU_C.C①初始化任务栈void *OSTaskStkInit(void(*task)(void *pd), void *ppdata, void *ptos, INT16U opt) REENTRANT{O S_STK *stk;p pdata=ppdata; //pata data 为52文件关键字o pt =opt; /* opt没被用到,保留此语句防止警告产生 */s tk =(OS_STK *)ptos; /* 任务堆栈最低有效地址*/*stk++=15; /* 任务堆栈长度*/ *stk++=(INT16U)task & 0xFF; /* 任务代码地址低8位*/*stk++=(INT16U)task >> 8; /* 任务代码地址高8位*//* 处理器是按特定的顺序将寄存器存入堆栈的,所以用户在将寄存器存入堆栈的时候也要依照这一顺序 */*stk++=0x00; /* PSW*/*stk++=0x0A; /* ACC*/*stk++=0x0B; /* B */ *stk++=0x00; /* DPL*/*stk++=0x00; /* DPH*/*stk++=0x00; /* R0 */ *stk++=0x01; /* R1 */ *stk++=0x02; /* R2 */ *stk++=0x03; /* R3 */ *stk++=0x04; /* R4 */ *stk++=0x05; /* R5 */ *stk++=0x06; /* R6 */ *stk++=0x07; /* R7 */ /* 不用保存SP,任务切换时根据用户堆栈长度计算得出*/*stk++=(INT16U)(ptos+MAX_STK_SIZE) >> 8; /* ?C_XBP 仿真堆栈指针高8位 */*stk++=(INT16U)(ptos+MAX_STK_SIZE) & 0xFF; /* ?C_XBP 仿真堆栈低8位*/r eturn ((void *)ptos); /* 返回最低地址,这里不用弹出栈顶指针是为了提高计算效率 */}②初始化定时器void InitTimer0(void) REENTRANT{TMOD=TMOD&0xF0; //屏蔽高四位TMOD=TMOD|0x01; /* 模式1(16位定时器),仅受TR0控制 */ TH0=TIMER_20MS_TH0;TL0=TIMER_20MS_TL0;E A=0; /* EA和ET0,51上电缺省值为0,EA将在OSStartHighRdy()中打开*/ET0=0; /* 满足在OSStart()前不产生时钟中断的要求,系统启动后第一时间开定时器T0中断 */TR0=1;}❖OS_CPU_A.ASM编写4个函数OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()❖OS_CFG.H主要为参数和使能的宏定义#define MAX_STK_SIZE 1024 /* 最大堆栈大小为1k*/#define OS_MAX_EVENTS 5 /* 应用程序中事件控制块的最大数量(必须大于零)*/#define OS_MAX_FLAGS 2 /* 应用程序中事件标志组的最大数目(必须大于零)*/#define OS_MAX_MEM_PART 5 /* 内存分区的最大数目(必须大于零)*/#define OS_MAX_QS 2 /* 应用程序中队列控制块的最大数目(必须大于零)*/#define OS_MAX_TASKS 11 /* 应用程序中任务的最大数目(必须大于2)*/#define TASK_START_PRIO 2 /* 应用程序开始优先级*/#define OS_LOWEST_PRIO 12 /* 定义可分配的最低优先级(必须大于63)*/#define TASK_STK_SIZE 512 /* 默认任务堆栈大小*/#define OS_TICKS_PER_SEC 50 /* 设置每秒节拍数*/#define TIMER_20MS_TH0 0x70 /* CPU=22.1184MHz, OS_TICKS_PER_SEC=50, TH0=0x70 */#define TIMER_20MS_TL0 0x00 /* CPU=22.1184MHz, OS_TICKS_PER_SEC=50, TL0=0x00 */晶振频率为22.1184MHz时才有OS_TICKS_PER_SEC=50,OS_TICKS_PER_SEC=50。
uCOS-II在51单片机上的移植

uC\OS-II在51单片机上的移植戴国强、史培杰(安阳工学院计算机科学与信息工程系)摘要:uC\OS-II以其结果清晰、性能稳定、源码公开等特点,受到广大嵌入式开发人员的青睐,已作为嵌入式实时操作系统被移植到许多微处理器上,在国防、航空航天、交通、能源、工业控制、通信以及人们日常生活等各个领域得到了广泛应用。
关键字:嵌入式实时操作系统、uC\OS-II、移植、MCS-51单片机Abstract: Based on the advantage of clear structure,stable capability and free sound code,the uC\OS-II comes in for lots of people's like who empolder the embedded system.As a embedded real-time operation system,the uC\OS-II has been repoted on lots of MCU,and has widely used an plays a very important role in many fields, such as national defence,spacenavigation,traffic,energy sources,industry control,communications,and civil living.Key words: the embedded real-time operationsystem,uC\OS-II,transplant,Single Chip Computer of MCS-51随着电子技术与软件技术的飞速发展,嵌入式系统技术已经成了最热门的技术之一。
嵌入式实时操作系统是嵌入式应用软件的基础和开发平台,其中涉及到软件和硬件两方面的问题。
嵌入式系统_C_OS_在C8051F120上的移植的研究

开发研究与设计技术本栏目责任编辑:谢媛媛1嵌入式系统μC/OS-Ⅱ简介μC/OS-Ⅱ是一个完整的、可移植、固化、裁剪的占先式实时多任务内核。
μC/OS-Ⅱ用C语言编写,包含一小部分汇编语言代码,使之可供不同的微处理器使用,它可以移植到8位到64位不同的微处理器上[1]。
μC/OS-Ⅱ包括任务调度、时间管理、内存管理、资源管理四大部分,没有文件系统、网络接口、用户图形接口界面。
它的移植只与四个文件相关:汇编文件(OS_CPU_A.ASM)、处理相关C文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。
有64个优先级,系统占有8个,用户可以创建56个任务。
它的基本思路就是“近似地每时每刻总是让优先级最高的就绪任务处于运动状态”。
为了保证这一点,它在调用系统API函数、中断结束、定时中断结束时总是执行调度算法。
它具有以下特点:可移植性:绝大部分μC/OS-Ⅱ的源码是用移植性很强的ANSIC写的,和微处理器硬件相关的那部分使用汇编语言写的。
汇编语言的部分已经压到最低限度,使得μC/OS-Ⅱ便于移植到其它微处理器上。
μC/OS-Ⅱ可以在绝大多数8位、16位、32位以至64位微处理器、微控制器、数字信号处理器(DSP)上运行。
可固化:μC/OS-Ⅱ是为了嵌入式应用设计的,只要有固化手段(C编译、连接、下载和固化),μC/OS-Ⅱ就可以潜入到产品中成为产品的一部分。
可裁剪:可以只使用μC/OS-Ⅱ中应用程序需要的系统函数,也就是说某产品可以使用很少几个μC/OS-Ⅱ调用,而另一个产品则可以使用几乎所有μC/OS-Ⅱ的功能,这样可以减少产品中的μC/OS-Ⅱ所需要存储空间。
占先式:μC/OS-Ⅱ总是运行就绪条件下优先级最高的任务。
多任务:μC/OS-Ⅱ可以管理64个任务,应用程序可以有56个任务。
2开发工具和运行环境实现μC/OS-Ⅱ的移植,要求所用的C编译器支持混合编程[2]。
KEILC51可为众多的8051派生器件编程,并且提供了丰富的调试工具和调试手段,使操作灵活简便。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
stc系列单片机μCOSⅡ在C8051F系列单片机上的移植及其
应用系统开发
随着微处理器技术的飞速发展和嵌入式系统实时性要求的不断提高,应用实时多任务操作系统(RTOS)作为嵌入式设计的开发平台已逐步成为嵌入式应用设计的主流。
本研究讨论将μC/OS-Ⅱ移植到C8051F系列高性能8位单片机中,并以C8051F060为例阐述了其应用系统的开发过程。
一、μC/OS-Ⅱ的基本工作原理
1.任务管理
?C/OS-II中的任务可以是一个无限的循环,也可以在一次执行完毕后被“删除”掉,即该任务可以认为CPU完全属于该任务本身,实时应用程序的设计过程包括将问题分割为多个任务。
?C/OS-II可以管理64个任务,每个任务有一定的优先级,且优先级不重复。
2.任务调度机制的实现
?C/OS-II是可剥夺型内核,优先级高的任务一旦就绪就能剥夺优先级较低任务的CPU使用权,这提高了系统的实时响应能力。
在没
有中断情况下,任务间的切换一般会调用OSSched()函数。
?C/OS-II 的中断服务子程序和一般前/后台的操作有所不同。
3.任务之间的通信
在?C/OS-II中,可以通过信号量、消息邮箱和消息队列等机制,实现数据共享和任务通信。
消息邮箱用一个指针型变量,一个任务或一个中断服务子程序通过内核服务,将一则消息放入邮箱,一个或多个任务通过内核服务接受这则消息。
每个邮箱有相应的等待消息任务表,等待消息的任务在无消息时被置挂起态,并记入邮箱等待消息任务表中。
消息放入邮箱,内核将运行等待消息任务表中优先级最高的任务。
二、移植及应用
C8051F060系列单片机特别适用于任务繁重的小型化测控系统。
当芯片具有的功能被较多地使用时,系统要处理的任务就较多,编程头绪也多。
为了简化应用程序实现程序模块化,提高应用程序的实时性和可靠性,将μCOS2Ⅱ移植到C8051F060中就成为一件很有意义的事。
1.?C/OS-II的移植
(1)修改INCLUDES.H文件:增加的头文件放在头文件列表的最后。
#include "os_cpu.h"
#include "os_cfg.h"
#include "ucos_ii.h"
(2)修改OS CPU.H文件:为确保系统在KEIL环境下正常运行,重新定义了一系列与C8051F060和KEIL编译器相关的数据结构、宏和常数。
typedef unsigned char OS_STK;/*定义堆栈宽度为8位*/
typedef unsigned char OS_CPU_SR;
#define OS_ENTER_CRITICAL() EA="0"
#define OS_EXIT CRITICAL()EA="1"
(3)修改OS_CPU_A.ASM文件
①编写OSSTartHihgRdy()函数:获得将要恢复运行的就绪任务的堆栈映像的最低地址,并计算出堆栈长度,然后向系统堆栈复制数据、堆栈指针SP和堆栈映像指针?C_XBP,最后利用中断返回。
②编写OSCtxSw()函数:先从当前任务的TCB控制块中获得当前任务堆栈长度和堆栈映像指针,然后将系统堆栈的内容复制到任务堆栈映像,最后获得将要恢复运行的就绪任务的TCB,程序跳至OSSTartHihgRdy()函数的入口,实现任务的切换。
③编写OSIntCtxSw()函数:代码大部分与OSCtxSw()相同,不同之处在于此处不需要再保存寄存器;需要调整堆栈指针
(SP=SP-4),去掉在调用OSIntExit(),OSIntCtxSw()中压入堆栈中的多余的内容,以使堆栈中只包含任务的运行环境。
④编写OSTickISR()函数:用定时器0作中断源,初始化定时器0使系统每秒中断100次,节拍率Tick=100次/秒。
(4)修改OS_CPU_C.C文件:编写OSTaskStkInit()函数用来初始化堆栈。
2. 基于?C/OS-II的C8051F060应用系统开发
移植了?C/OS-II的C8051F060的每个功能都可以作为一个独立的任务,每个任务都有自己的堆栈空间,可以被其他任务和中断服务程序挂起。
在设计中,主函数均以OSInit()开始,以OSStart()结束,中间部分为与硬件相关的系统初始化函数。
对于任务的建立,必须依照?C/OS-II系统中建立任务的格式,根据自己的需求来确定任务的个数,并且根据任务的重要程度和被调用的频率来设置好优先级。
创建好任务后,在主函数外面分别列出各个任务函数,每个任务函数都是一个无限循环程序,调用实现某些功能的应用程序函数,然后按设计的需求设置挂起方式和挂起时间。
应用系统测试程序实现了6个任务:Task1是每1s发送CAN数据包,Task2是处理CAN接收到的数据,Task3是每3s发送串口数据,Task4是处理串口接收到的数据,Task5是处理按键信息,Task6是显示数据。
CAN总线接收采用中断方式,其优先级高于其他任务,为了保证系统的实时性,在中断程序中不处理数据,只是发送一个信号量,在Task2中处理CAN数据。
串口数据接收亦采用中断方式,其优先级低于CAN高于其他任务。
串口数据发送采用的是查询方式,按字节发送。
程序中设置6个任务的优先级依次为13,11,14,12,15,16。
在主程序中,首先初始化C8051F060和CAN,调用OsInit();然后调用API函数,创建6个任务(不包括空闲任务);再创建一个信号量CAN_EVENT,为中断与Task2通信所用;最后调用OSStart(),OS系统开始运行优先级最高的任务。
Task2的优先级最高,但是在没收到CAN_EVENT之前,任务一直处于休眠状态,当CAN __收到数据包后,Task2进入就绪态,在中断返回时,进行任务切换,执行优先级最高Task2。
在Task2还未收到信号量之前,Task1、Task3、Task4、Task5和Task6根据时间延时和优先级的不同各自独立运行。
三、结束语
将编写的测试程序下载到C8051F060应用系统中进行了实际的运行测试,测试表明,基于?C/OS-II的C8051F060应用系统中的各任务工作稳定可靠,取得了满意的效果,为进行嵌入式应用系统的进一步设计奠定了基础。
(:黑龙江省大庆职业学院)
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文
本文为全文原貌未安装PDF浏览器用户请先下载安装原版全文
内容仅供参考。