?? f31xsr176.c
字號:
/**************************************************************************************
描述: 利用C8051F31x的SMBus總線實現對射頻讀卡芯片
的基本讀寫,并將讀寫的結果通過串行接口傳送
到PC端的演示程序顯示出來。
-C8051F31x的SMBus總線工作在主模式
-中斷下實現數據的收發
-定時器0作為SMBus的時鐘源
-定時器3作為SMBus時鐘信號SCL的低電平超時檢測
-SCL頻率由常數SMB_FREQUENCY定義
-P0.0 -> SDA (SMBus)
-P0.1 -> SCL (SMBus)
-P0.4 -> TXD
-P0.5 -> RXD
**************************************************************************************/
#include "serial.h" /* 特殊功能寄存器定義,串行通信函數原型宣告 */
/*常量定義*/
#define SMB_FREQUENCY 50000 /* SCL時鐘頻率 */
#define WRITE 0x00 /* SMBus寫命令 */
#define READ 0x01 /* SMBus讀命令 */
#define CRX14_ADDR 0xA0 /* CRX14設備地址 */
/* SMBus狀態向量 - 僅高4位 */
#define SMB_MTSTR 0xE0 /* (MT) 開始發送 */
#define SMB_MTDB 0xC0 /* (MT) 數據字節發送 */
#define SMB_MRDB 0x80 /* (MR) 數據字節接收 */
#define SMB_DELAY 0xA0 /* 延時 */
/*************************************************************************************/
/*全局變量定義*/
BYTE TX_buf[10]; /* 發送緩沖區 */
BYTE RX_buf[10]; /* 接收緩沖區 */
BYTE SMB_state,SMB_data_len,SMB_data_index,read_len; /* SMB狀態,SMB數據長度,SMB數據索引,讀取數據長度 */
BYTE CommSendBufferHead, CommSendBufferTail; /* 發送緩沖區頭,尾變量 */
BYTE CommRecBufferHead, CommRecBufferTail; /* 接收緩沖區頭,尾變量 */
bit SMB_BUSY; /* SMBus忙旗標 */
bit FirstTime; /* 首次旗標*/
bit SMB_RW; /* 指示當前傳送方向的旗標 */
bit Read_Bit; /* 讀旗標 */
sfr16 TMR3RL = 0x92; /* 定時器3重載寄存器 */
sfr16 TMR3 = 0x94; /* 定時器3計數寄存器 */
/*************************************************************************************/
/* 函數原型 */
void Buzzer(BYTE delaytime);
void SMBus_Init(void);
void Timer0_Init(void);
void Timer3_Init(void);
void Port_Init(void);
void SMBus_ISR(void);
void Timer3_ISR(void);
BYTE xhl_i2c_Master_Xmit(BYTE N);
BYTE xhl_i2c_Master_Recv(BYTE N);
/***************************************************************************************
函數名稱: BYTE HEXToASC(BYTE x)
功能描述: 十六進數轉化成ASCII碼
輸入: BYTE x(所要轉化的十六進數)
輸出: 轉化后的ASCII碼
全局變量: 無
調用模塊: 無
***************************************************************************************/
BYTE HEXToASC(BYTE x)
{
if (x>9) return x+0x40-9;
else return x+0x30;
}
/***************************************************************************************
函數名稱: BYTE ASCToHEX(BYTE x)
功能描述: ASCII碼轉化成十六進數
輸入: BYTE x(所要轉化的ASCII碼)
輸出: 轉化后的十六進數
全局變量: 無
調用模塊: 無
***************************************************************************************/
BYTE ASCToHEX(BYTE x)
{
if ((x>='0')&&(x<='9')) /* 數字 */
{
return x-0x30;
}
else
{
if ((x>='A')&&(x<='F')) /* 大寫字母 */
return x-'A'+10;
if ((x>='a')&&(x<='f')) /* 小寫字母 */
return x-'a'+10;
}
return 0;
}
/***************************************************************************************
函數名稱: void sleep_ms(WORD count)
功能描述: 延時
輸入: WORD count(所要延時的長度)
輸出: 無
全局變量: 無
調用模塊: _nop_()
***************************************************************************************/
void sleep_ms(WORD count)
{
WORD i,j;
for(i=0;i<count;i++)
{
for(j=0;j<203;j++)
_nop_();
}
}
/***************************************************************************************
函數名稱: void OneBuzzer(BYTE delaytime)
功能描述: 蜂鳴器響一聲后關閉
輸入: BYTE delaytime(響一聲的長度)
輸出: 無
全局變量: BUZZER -> 蜂鳴器的控制I/O
調用模塊: void sleep_ms(WORD count)
***************************************************************************************/
void OneBuzzer(BYTE delaytime)
{
BYTE i;
BUZZER = 1; /* 響 */
for(i=0;i<delaytime;i++){
sleep_ms(30); /* 蜂鳴器響時間延時 */
}
BUZZER = 0; /* 不響 */
}
/***************************************************************************************
函數名稱: BYTE Write_Parameters()
功能描述: 寫CRX14參數寄存器
輸入: 無
輸出: 運行結果返回碼
全局變量: 無
調用模塊: BYTE xhl_i2c_Master_Xmit(BYTE N)
***************************************************************************************/
BYTE Write_Parameters()
{
BYTE rewp;
rewp = xhl_i2c_Master_Xmit(2);
if(rewp==0x01)
return 0; /* 錯誤 */
else
return rewp; /* 正確 */
}
/***************************************************************************************
函數名稱: BYTE Read_Parameters()
功能描述: 讀CRX14參數寄存器
輸入: 無
輸出: 運行結果返回碼
全局變量: Read_bit -> 是否結束此次讀寫操作
Tx_buf -> 發送緩沖區
調用模塊: BYTE xhl_i2c_Master_Xmit(BYTE N)
BYTE xhl_i2c_Master_Recv(BYTE N)
***************************************************************************************/
BYTE Read_Parameters()
{
BYTE rerp;
Read_Bit=1;
TX_buf[0]=0x00;
rerp = xhl_i2c_Master_Xmit(1);
Read_Bit=0;
if(rerp!=0x01){
return rerp; /* 主發送失敗 */
}
rerp = xhl_i2c_Master_Recv(1);
if(rerp==0x01) return 0; /* 正確 */
else return rerp; /* 失敗 */
}
/***************************************************************************************
函數名稱: BYTE Write_IO_data()
功能描述: 寫CRX14輸入/輸出幀寄存器
輸入: 無
輸出: 運行接過返回碼
全局變量: 無
調用模塊: BYTE xhl_i2c_Master_Xmit(BYTE N)
***************************************************************************************/
BYTE Write_IO_data()
{
BYTE rewid;
rewid = xhl_i2c_Master_Xmit(TX_buf[1]+2);
if(rewid==0x01){
return 0; /* 正確 */
}
else return rewid; /* 錯誤 */
}
/***************************************************************************************
函數名稱: BYTE Read_IO_data()
功能描述: 讀CRX14輸入/輸出幀寄存器
輸入: 無
輸出: 運行結果返回碼
全局變量: Read_Bit -> 是否結束此次讀寫操作
Tx_buf -> 發送緩沖區
read_len -> 接收數據長度
調用模塊: BYTE xhl_i2c_Master_Xmit(BYTE N)
BYTE xhl_i2c_Master_Recv(BYTE N)
***************************************************************************************/
BYTE Read_IO_data()
{
BYTE rerid;
Read_Bit=1;
TX_buf[0]=0x01;
rerid = xhl_i2c_Master_Xmit(1);
Read_Bit=0;
if(rerid!=0x01) return rerid; /* 主發送失敗 */
rerid = xhl_i2c_Master_Recv(read_len);
if(rerid==0x01) return 0; /* 正確 */
else return rerid; /* 失敗 */
}
/***************************************************************************************
函數名稱: BYTE RF_OFF(void)
功能描述: 關閉載頻信號輸出
輸入: 無
輸出: 運行結果返回碼
全局變量: Tx_buf -> 發送緩沖區
Rx_buf -> 接收緩沖區
調用模塊: BYTE Read_Parameters()
BYTE Write_Parameters()
***************************************************************************************/
BYTE RF_OFF (void)
{
BYTE rero;
rero = Read_Parameters();
if(rero!=0) return rero;
TX_buf[0] = 0;
TX_buf[1]=RX_buf[0]&0xEF; /* 復位參數寄存器的第4位 */
rero = Write_Parameters();
if(rero!=0) return rero; /* 錯誤 */
return 0; /* 正確 */
}
/***************************************************************************************
函數名稱: BYTE RF_ON(void)
功能描述: 打開載頻信號輸出
輸入: 無
輸出: 運行結果返回碼
全局變量: Tx_buf -> 發送緩沖區
Rx_buf -> 接收緩沖區
調用模塊: BYTE Read_Parameters()
BYTE Write_Parameters()
***************************************************************************************/
BYTE RF_ON (void)
{
BYTE rero;
rero = Read_Parameters();
if(rero!=0) return rero;
TX_buf[0]=0x00;
TX_buf[1]=RX_buf[0]|0x10; /* 設置參數寄存器的第4位 */
rero = Write_Parameters();
if(rero!=0) return rero; /* 錯誤 */
return 0; /* 正確 */
}
/***************************************************************************************
函數名稱: BYTE Send_Receive_Data()
功能描述: 向射頻卡發送命令后,依據命令字的不同等待射頻卡返回相應數據
輸入: 無
輸出: 運行結果的返回碼
全局變量: Tx_Buf ->發送緩沖區
調用模塊: BYTE Write_IO_data(void)
void sleep_ms(WORD count)
BYTE Read_IO_data(void)
***************************************************************************************/
BYTE Send_Receive_Data()
{
BYTE reval;
BYTE i=0;
reval = Write_IO_data();
if(reval==0){ /* 發送正確 */
if((TX_buf[2]==0x09)||(TX_buf[2]==0x0F)) return 0;
RX_buf[0] = 0;
sleep_ms(160);
while ((i++<5)&&(RX_buf[0]==0)){
reval = Read_IO_data();
if(reval==0) break;
//sleep_ms(1000);
}
if(reval!=0) return reval; /* 接收錯誤 */
}
else return reval; /* 發送錯誤 */
return 0;
}
/***************************************************************************************
函數名稱: BYTE xhl_i2c_Master_Xmit(BYTE N)
功能描述: SMBus主模式發送數據(數據在SMBus中斷內發送)
輸入: BYTE N(待發送數據字節的長度)
輸出: 運行結果的返回碼
全局變量: SMB_data_len ->數據長度
SMB_data_index ->數據索引
SMB_BUSY ->SMBus忙標志
SMB_RW ->讀寫標志
SMB_state ->SMBus運行狀態
STA ->開始標志
調用模塊: 無
***************************************************************************************/
BYTE xhl_i2c_Master_Xmit(BYTE N)
{
SMB_data_len=N;
SMB_data_index=0;
while(SMB_BUSY); /* 等候SMBus不忙 */
SMB_BUSY = 1; /* 設置到忙 */
SMB_RW = 0; /* 指示這次傳送是寫 */
SMB_state=0x55;
STA = 1; /* 開始傳送 */
do{ }while(SMB_state==0x55);
if(SMB_state==0x01)
return 0x01; /* 正確 */
else
return 0x00; /* 錯誤 */
}
/***************************************************************************************
函數名稱: BYTE xhl_i2c_Master_recv(BYTE N)
功能描述: SMBus的主模式接收數據
輸入: BYTE N(待接收數據字節的長度)
輸出: 運行結果的返回碼
全局變量: SMB_data_len ->數據長度
SMB_data_index ->數據索引
SMB_BUSY ->SMBus忙標志
SMB_RW ->讀寫標志
SMB_state ->SMBus運行狀態
STA ->開始標志
調用模塊: 無
***************************************************************************************/
BYTE xhl_i2c_Master_recv(BYTE N)
{
SMB_data_len=N;
SMB_data_index=0;
while(SMB_BUSY); /* 等候總線不忙 */
SMB_BUSY = 1; /* 設置到忙 */
SMB_RW = 1; /* 指示這次傳送是讀 */
STA = 1; /* 開始傳送 */
SMB_state=0x55;
do{}while(SMB_state==0x55);
if(SMB_state==0x01) return 0x01;/* 正確 */
else return 0x00; /* 錯誤 */
//while (SMB_BUSY); /* 等待傳送完成 */
}
/***************************************************************************************
函數名稱: void SMBus_ISR(void) interrupt 6
功能描述: SMBus中斷服務子程序,進行數據的發送和接收
輸入: 無
輸出: 無
全局變量: SMB_data_len ->數據長度
SMB_data_index ->數據索引
SMB_BUSY ->SMBus忙標志
SMB_RW ->讀寫標志
SMB_state ->SMBus運行狀態
STA ->開始標志
STO ->結束標志
調用模塊: BYTE sleep_ms(WORD count)
***************************************************************************************/
void SMBus_ISR (void) interrupt 7
{
bit FAIL; /* 傳送失敗標志 */
_nop_();
switch(SMB0CN & 0xF0){ /* 狀態向量 */
case SMB_MTSTR: //1110 /* 主模式發送/接收: 發送START.
SMB0DAT = CRX14_ADDR; /* 輔設備器件地址 */
SMB0DAT |= SMB_RW; /* 填充R/W位 */
STA = 0; /* 清除START位 */
break;
case SMB_MTDB: //1100 /* 主模式傳送: 數據字節被傳送 */
if(ACK){ /* 輔設備ACK? */
if((SMB_data_index)<(SMB_data_len)){
if (SMB_RW==WRITE){ /* 如果是寫 */
SMB0DAT=TX_buf[SMB_data_index];
SMB_data_index++;
}
else{} // If this transfer is a READ, proceed with transfer without
// writing to SMB0DAT (switch to receive mode)
}
else{ /* 如果上個字節不是輔設備地址 */
if(SMB_data_index==SMB_data_len){
if(Read_Bit==0)
STO=1; /* 設置STO=1,結束發送 */
SMB_BUSY = 0; /* 釋放SMBus接口 */
SMB_state=0x01;
}
}
}
else{ /* 如果輔設備NACK */
FAIL = 1; /* 傳送失敗,跳到中斷服務程序的最后進行失敗處理 */
}
break;
case SMB_DELAY:
sleep_ms(100);
break;
case SMB_MRDB: //1000 /* 主模式接收:按字節接收 */
if(SMB_data_index<SMB_data_len-1){
RX_buf[SMB_data_index]=SMB0DAT;
SMB_data_index++;
ACK=1; /* 響應ACK */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -