📄 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 + -