⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f31xsr176.c

📁 利用C8051F31x的SMBus总线实现对射频读写芯片的基本读写
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************
描述:			利用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 + -