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 用于表示系統正在運行之中。
評論
查看更多