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

📄 zlg500s_comm.c

📁 嵌入式系统开发 MRC 522 S50 S70
💻 C
字号:
#define ZLG500S_COMM_GLOBALS
#include "config.h"
#include "zlg500S_comm.h"


void ZLG500S_COMM_Init()
{
	PINSEL0 = (PINSEL0 & 0xffffff0f) | 0x50;
	
	I2SCLH = (Fpclk/400000L+1)/2;	//设置I2C速率为400K
	I2SCLL = (Fpclk/400000L)/2;
	
	SerDTvalid = FALSE;
}


INT8U Zlg500S_Rcv(INT8U slv_adr,volatile INT8U *databfr)
{
	INT8U i,LCnt;
	INT8U Status = TRUE;
	
	LCnt = 3;
	
	I2CONCLR = 0x6c;
	I2CONSET = 0x40;	//发送起始位
	I2CONSET = 0x60;	//发送起始位
	
	while(LCnt--)
	{
		while(!(I2CONSET & 0x08));
		
		switch(I2STAT)
		{
			case 0x08:	//已发送起始条件
				
				I2DAT = slv_adr | 0x01;	//发送zlg500S从机地址+R
				break;
				
			case 0x40:	//已发送zlg500S从机地址+R,已接收ACK
			
				I2CONSET = 0x04;	//准备返回ACK
				i = 0;
				break;
				
			case 0x50:	//已接收数据,已返回ACK	
			
				databfr[i] = I2DAT;
				i++;
				
				if(i == 1)
				{
					LCnt = databfr[0]-1;
					if(databfr[0] < PRTCLEN || databfr[0] > MAXSERSIZE)
					{						//通信错误
						I2CONSET = 0x10;	//发送停止位
						I2CONCLR = 0x04;	//不返回ACK
						Status = FALSE;
						break;
					}		
				}
				
				if(i == databfr[0])
				{
					I2CONSET = 0x10;	//发送停止位
					I2CONCLR = 0x04;	//不返回ACK
				}	
							
				break;
			
			case 0x48:	//已发送zlg500S从机地址+R,已接收非ACK
			case 0x58:	//已接收数据,已返回非ACK
			
				I2CONSET = 0x10;	//发送停止位
				I2CONCLR = 0x04;	//不返回ACK
				Status = FALSE;
				break;
				
			default:
			
				Status = FALSE;
				break;
		}
		I2CONCLR = 0x28;
		if(Status == FALSE)	break;
	
	}
	for(i=200;i>0;i--);
	return Status;
}

INT8U Ser_Rcv()
{
	INT8U i,BCC;
	INT8U Status = FALSE;

	if(!zlg500S_Int)
	{
		if(Zlg500S_Rcv(0xb2,SerBfr))
			SerDTvalid = TRUE;
	}

	if(SerDTvalid)
	{									//已接收一帧数据,进行数据校验
		if(SerBfr[SerBfr[FRAMELEN]-1] == ETX && SerBfr[FRAMELEN] == (SerBfr[LENGTH]+PRTCLEN))
		{			//且正确接收到ETX,及帧长度等于数据长度加协议长度,则数据有效
			BCC = 0;
			for(i=0; i<(SerBfr[FRAMELEN]-1); i++)
			{
				BCC ^= SerBfr[i];
			}
			if(BCC == 0xff)
				Status = TRUE;	//BCC校验通过
		}
		SerDTvalid = FALSE;
	}
	
	return Status;
}

INT8U Zlg500S_Send(INT8U slv_adr,volatile INT8U *databfr,INT8U len)
{
	INT8U i,LCnt;
	INT8U Status = TRUE;
	
	LCnt = len+2;
	
	I2CONCLR = 0x6c;
	I2CONSET = 0x40;	//发送起始位
	I2CONSET = 0x60;	//发送起始位
	
	while(LCnt--)
	{
		while(!(I2CONSET & 0x08));
			
		switch(I2STAT)
		{
			case 0x08:	//已发送起始条件
				
				I2DAT = slv_adr;	//发送zlg500S从机地址+W
				i = 0;
				break;
				
			case 0x18:	//已发送zlg500S从机地址+W,已接收ACK
			case 0x28:	//已发送I2DAT中的数据,已接收ACK	
			
				if(i == len)
					I2CONSET = 0x10;	//发送停止位
				else	
				{
					I2DAT = databfr[i];
					i++;
				}
				break;
				
			case 0x20:	//已发送zlg500S从机地址+W,已接收非ACK
			case 0x30:	//已发送I2DAT中的数据,已接收非ACK
			
				I2CONSET = 0x10;	//发送停止位
				Status = FALSE;
				break;
				
			default:
			
				Status = FALSE;
				break;
		}
		I2CONCLR = 0x28;
		if(Status == FALSE)	break;
	}
	return Status;
}

INT8U Ser_Send()
{
    INT8U i,BCC;

	SerBfr[FRAMELEN] = SerBfr[LENGTH]+PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC = 0;
	for(i=0; i<(SerBfr[FRAMELEN]-2); i++)
		BCC ^= SerBfr[i];
	SerBfr[SerBfr[FRAMELEN]-2] = ~BCC;
	SerBfr[SerBfr[FRAMELEN]-1] = ETX;
	
	return Zlg500S_Send(0xb2,SerBfr,SerBfr[FRAMELEN]);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -