CAT24WC02 驱动程序演示实验
一.实验目的
本程序展示了如何编写基于Small RTOS 的I2C 总线驱动程序。
二.实验设备及器件
PC 机 一台
DP-51PROC 单片机综合仿真实验仪 一台
三.实验步骤
1. 使用导线连接D5 区的SCL、SDA 和A2 区的P16、P17(SCL~P16、SDA~P17),
短接D5 区的JP1 跳线;
2. 下载Cat24WC02.hex 文件到DP-51PROC 中并运行;
3. 打开DPFlash.exe 软件的串口调试窗口(或者其他的串口调试软件),设置波特率
为4800 b/s 8 位数据 1 位停止位 和Hex 方式显示数据,输入数据并按16 进
制方式发送。
四.实验参考程序主要部分
/***************************************************************
** Small RTOS(51)
** The Real-Time Kernel(For Keil c51)
** (c) Copyright 2002-2004
** All Rights Reserved
** V1.20
*************************************************************/
#include "config.h"
uint8 ShowCase[8]; //显示缓存,用来保存各个显示位的段码
//指针的NULL 为0,这个变量占用0 地质避免出现有效的NULL 指针
uint8 OS_Q_MEM_SEL NotUse _at_ 0x0000;
uint8 OS_Q_MEM_SEL SerialInData[10]; //给读串口消息队列分配的队列空间
uint8 OS_Q_MEM_SEL SerialOutData[10]; //给写串口消息队列分配的队列空间
bit SerialCanSend = 1; // 正在发送标志,0:正在发送
uint8 EepRomBuf[5]; //读写串行eeprom 数据的缓存
void PutChar(uint8 Data); //发送一个字节
void Send(uint8 Data); //发送一个数据
void SerialInit(void);
void command(void);
void Display(void);
void TimeSum(void);
/***************************************************
** 函数名称: init
** 功能描述: 初始化函数,一般在多任务环境启动前调用
*****************************************************/
void init(void)
{
TMOD = (TMOD & 0XF0) | 0X01;
TH0 = (65536 - (11059200 / 12) / 100) / 256;
TL0 = (65536 - (11059200 / 12) / 100) % 256;
TR0 = 1;
ET0 = 1;
TF0 = 0;
}
/******************************************************************
** 函数名称: main
** 功能描述: 主函数,用户程序从这里执行
****************************************************************/
void main(void)
{
OSInit();
init();
OSTaskCreate(command,NULL,0);
OSTaskCreate(Display,NULL,1);
OSTaskCreate(TimeSum,NULL,2);
while(1)
{
PCON = PCON | 0x01; /* CPU 进入休眠状态 */
}
}
/****************************************************************
**显示任务
*************************************************************/
void Display(void)
{
while(1)
{
ShowCase[3] = 31;
ShowCase[4] = 31;
ShowCase[5] = 31;
ShowCase[6] = 31;
ZLG7290_SendBuf(ShowCase,8);
OSWait(K_TMO,1);
}
}
/*****************************************************
** 函数名称: command
** 功能描述: 命令处理任务,高层命令由这个任务执行,相当于应用程序
***********************************************************/
void command(void)
{
uint8 data temp;
OSSemCreate(IICSem,1);
OSSemCreate(Cat24WCxxSem,1);
OSQCreate(SerialInData,10);
OSQCreate(SerialOutData,10);
SerialInit();
while (1)
{
OSQPend(&temp,SerialInData,0);
/* 把接收到的数据在LED 数码显示器上显示出来 */
ShowCase[0] = temp % 10;
ShowCase[1] = (temp / 10) % 10;
ShowCase[2] = temp / 100;
/* 把接收到的数据写入cat24wc02 */
EepRomBuf[0] = 0; //外部地址
EepRomBuf[1] = 1; //写多少字节
EepRomBuf[2] = 0; //开始写地址
EepRomBuf[3] = temp; //数据
OSCat24WCxxWrite(EepRomBuf);
OSWait(K_TMO,10);
/* 从cat24wc02 读出刚才写入的数据*/
EepRomBuf[0] = 0; //器件外部地址
EepRomBuf[1] = 1; //读多少字节
EepRomBuf[2] = 0; //开始读地址
OSCat24WCxxRead(EepRomBuf);
/* 把读出的数据发送回去 */
Send(EepRomBuf[0]);
OSWait(K_TMO,10);
}
}
/*****************************************************************
******
** 函数名称: SerialInit
** 功能描述: 初始化串行口
****************************************************************
******/
void SerialInit(void)
{
SCON = 0x50;
PCON = 0x80;
TMOD = TMOD & 0x0f;
TMOD = TMOD | 0x20;
TH1 = 0xf4; //波特率为 4800 b/s
TL1 = 0xf4;
TR1 = 1;
ES = 1;
}
/***********************************************************
*******
** 函数名称: Send
** 功能描述: 发送一个数据包
** 输 入: Data:指向要发送的数据指针
*******************************************************
*******/
void Send(uint8 Data)
{
PutChar(Data);
}
/*******************************************************************
******
** 函数名称: PutChar
** 功能描述: 发送一个字节
******************************************************************
********/
void PutChar(uint8 Data)
{
OS_ENTER_CRITICAL();
if (SerialCanSend == 1)
{
SerialCanSend = 0;
SBUF = Data;
}
else
{
OSQIntPost(SerialOutData,Data);
}
OS_EXIT_CRITICAL();
}
/*****************************************************************
** 函数名称: comm
** 功能描述: 串口中断处理程序
**************************************************************/
#pragma disable /* 除非最高优先级中断,否则,必须加上这一句 */
void comm(void) interrupt 4
{
uint8 data temp;
if (RI == 1)
{
OS_INT_ENTER();
RI = 0;
OSQPost(SerialInData,SBUF);
OSIntExit();
return;
}
if (TI == 1)
{
TI = 0;
if (OSQAccept(&temp,SerialOutData) == OS_Q_OK)
{
SBUF = temp;
}
else
{
SerialCanSend = 1;
}
}
}
/*************************************************************
** 函数名称: TimeSum
** 功能描述: 使LED 显示0~9 的任务
**************************************************************/
void TimeSum(void)
{
while (1)
{
ShowCase[7] ++;
if(ShowCase[7] > 9)
{
ShowCase[7] = 0;
}
OSWait(K_TMO,OS_TICKS_PER_SEC); /* 延时1 秒 */
}
}
五.实验例程序简析
由于对I2C 总线驱动程序的操作具有不可重入性,故使用了信号量Cat24WcxxSem 来
实现互斥操作,为了使用信号量,必须在OS_cfg . h 文件中将EN_OS_SEM 置为1。
以下为多任务对Cat24WCxx 的写操作代码
#define OSCat24WCxxWrite(a) \
if (OSSemPend(Cat24WCxxSem,10) == OS_SEM_OK) \
{ \
Cat24WCxxWrite (a); \
OSSemPost(Cat24WCxxSem); \
}
以下为多任务对Cat24WCxx 的读操作代码:
#define OSCat24WCxxRead(a) \
if (OSSemPend(Cat24WCxxSem,10) == OS_SEM_OK) \
{ \
Cat24WCxxRead(a); \
OSSemPost(Cat24WCxxSem); \
}
本程序中也使用的消息队列来缓冲数据,故也必须在OS_cfg . h 文件中将EN_OS_Q 置
为1,以使Small RTOS51 配置为允许使用消息队列。
从串口接收到的数据按10 进制的方式在LED 上显示出来。最左边的LED 循环的显示
0~9 用于表示系统正在运行之中。
评论
查看更多