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

📄 main(i2c).c

📁 main(I2C)直读压力计的开发程序
💻 C
字号:
/******************************************************************************************
文件名:	main(I2c).c
文件功能:	程序主文件
创建人:	
创建日期:	2007年5月13日
******************************************************************************************/

//---------------------------------------------------------------------------------------
//			头文件
//---------------------------------------------------------------------------------------
#include	<ADuC845.h>
#include	<stdio.h>
#include	<math.h>
#include	"main.h"
#include	"intrins.h"
#define	ADDR1	0x01

//----------------------------------------------------------------------------------------
//			全局变量定义
//----------------------------------------------------------------------------------------
bit	Recieve_Mode = 0;			//	数据接收模式标志位(0:接收命令字;1:接收数据)
bit	success = 0;				//	操作成功标志位
BYTE	Command_Buffer[2];		//	命令字缓存区
BYTE	Data_Buffer[5];			//	数据缓存区
BYTE	CRC_Buffer[2];			//	校验码缓存区
UINT	N=0;					//	一个采集周期内采集的次数
ULONG	G;						//	压力码值
BYTE	D[6]; 					//	压力,温度缓冲区

//----------------------------------------------------------------------------------------
//			函数原型
//----------------------------------------------------------------------------------------
void	AD_Adj (void);			//	AD校准函数
void	Read_Command(void);		//	读命令字函数
void	UART_ISR(void);			//	串口中断服务函数
void	UART_Send(BYTE);		//	向串口发送数据函数
void	Make_Respond(BYTE);		//	命令响应函数
void	Start_Collect(void);	//	开始采集函数
void	Stop_Collect(void);		//	停止采集函数
void	Send_Data(void);		//	发送数据函数
void	Self_Check(void);		//	自检函数
void	CRC_Init(void);			//	校验码初始化函数
void	ModBus_CRC(BYTE);		//	校验码计算函数
void	Delay(void);			//	延时
void	LM92_RD(void);			//	读取LM92数据函数
void	I2C_Write(BYTE);		//	向I2C总线写数据函数
BYTE	I2C_Read(void);			//	从I2C总线读数据函数
void	I2C_Start(void);		//	I2C起始函数
void	I2C_Stop(void);			//	I2C停止函数
void	I2C_ACK(void);			//	I2C确认函数
void	I2C_NACK(void);			//	I2C非确认函数
BYTE	I2C_RACK(void);			//	I2C接收确认信号函数
void	I2C_NOP(void);			//	延时函数

extern	void	UART_Send(BYTE);

//----------------------------------------------------------------------------------------
//			主函数
//----------------------------------------------------------------------------------------

void	main(void)
{	BYTE	m=0;
	ICON=0x0B;					// 选择激励电流源,400uA,由IEXC1输出
	AD_Adj();					// AD校准
	T3CON = 0x83;				// 9600 Baud rate
	T3FD = 0x12;
	SCON = 0xC4; 				// 方式2,REN=1,SM2=1,TB8=0,RB8=1
	while(!RI);					// 等待上位机发送校验信号AA
	RI=0;
	if(SBUF==0xAA);
	do{							// 接收到AA后回发11
	SBUF=0x11;
	}while(!TI);
	TI=0;
	ES=1;						// 允许串口中断	
	EA=1;					   	// 开启总中断
}

//----------------------------------------------------------------------------------------
//			AD校准函数
//----------------------------------------------------------------------------------------

void	AD_Adj (void)
{
	SF=0xFF;					// 设置为最大值
	ADC0CON1=0x07;				// 主ADC选用双极性方式,2.56V输入范围
	ADC0CON2=0x4A;				// 主ADC选用外部参考电源通过REFIN+/-引脚输入
	ADCMODE=0x6E;				// 60Hz,主ADC使能,非斩波模式,内部零点校准
	CAL=0;
	while(RDY0)
	{
		GN0L=ADC0L;				// 保存主ADC内部零点的校准系数(偏移系数)
		GN0M=ADC0M;
		GN0H=ADC0H;
	};
	ADCMODE=0x6F;
	CAL=0;
	while(RDY0)
	{
	OF0L=ADC0L;
	OF0M=ADC0M;
	OF0H=ADC0H;
	};	
	ADCMODE=0x6E;				// 第二次主ADC零点校准
	CAL=0;
	while(RDY0)
	{
	GN0L=ADC0L;
	GN0M=ADC0M;
	GN0H=ADC0H;	
	};	
}

//----------------------------------------------------------------------------------------
//			串口中断服务函数
//----------------------------------------------------------------------------------------

void	UART_ISR(void)	interrupt	8
{	
	if(SBUF==ADDR1)
	{					  
		SM2=0;					// 准备接收、发送数据
		RI=0;
		do{
		Command_Buffer[0]=SBUF;
		}while(!RI);
		RI=0;
		Read_Command();	
	}
}

//----------------------------------------------------------------------------------------
//			执行命令函数
//----------------------------------------------------------------------------------------

void	Read_Command(void)				// 判断命令类型并散转执行
{
 switch(Command_Buffer[0])
	{
	case	START:
		if(Command_Buffer[1] == START)	// 响应开始采集命令
		{
			Make_Respond(0x44);	
			Start_Collect();
		}
		break;
		
	case	STOP:
		if(Command_Buffer[1] == STOP)	// 响应停止采集命令
		{
			Make_Respond(0x55);
			Stop_Collect();
		}
		break;

	case	SEND:
		if(Command_Buffer[1] == SEND)	// 响应传输数据命令
		{
			Make_Respond(0x66);
			Send_Data();
		}
		break;

	case	CHECK:
		if(Command_Buffer[1] == CHECK)	// 响应自检命令
		{
			Make_Respond(0x77);
			Self_Check();
		}
		break;

	default:
		break;
	}
}

//---------------------------------------------------------------------------------------
//			命令响应函数
//---------------------------------------------------------------------------------------

void	Make_Respond(BYTE m1)			// 发送命令ID并等待响应
{
	do{
	SBUF=m1;
	while(TI);
	TI=0;
	while(RI);
	RI=0;
	}while(SBUF!=0xBB);
}

//---------------------------------------------------------------------------------------
//			开始采集函数
//---------------------------------------------------------------------------------------
void	Start_Collect(void)
{
	SF=0xFF;
	ADC0CON1=0x07;				// 主ADC选用单极性方式,2.56V输入范围	
	ADC0CON2=0x4A;				// 主ADC选用外部参考电压REFIN+/-引脚输入
	ADCMODE=0x63;				// 60Hz抑制,主ADC使能,连续转换
	TIMECON=0x39;				//	设置TIC为24小时,秒寄存器输出
	INTVAL=0x0A;				// 设置每10秒中断一次,10秒到时产生中断,求出平均值
	ET1=1;						// 允许TIC中断
	while(RDY0)
	{
	RDY0=0;
	G+=ADC0H*65536+ADC0M*256+ADC0L;
	LM92_RD();
	N++;
	}
}

//---------------------------------------------------------------------------------------
//			定时器中断执行求平均数函数
//---------------------------------------------------------------------------------------
void	TIME_ISR(void)	interrupt	10	using	1
{
	ULONG	R;
	R=G/N;
	N=0;
}

//---------------------------------------------------------------------------------------
//			停止采集函数
//---------------------------------------------------------------------------------------
void	Stop_Collect(void)
{

}

//---------------------------------------------------------------------------------------
//			发送数据函数
//---------------------------------------------------------------------------------------
void	Send_Data(void)
{	UINT	i;
	do{		   					// 联络
	SBUF=0xDD;
	while(TI);
	TI=0;
	while(RI);
	RI=0;
	}while(SBUF!=0xEE);
	for(i=0;i<6;i++)			//	发送温度、压力数据
	{
	SBUF=D[i];
	while(!TI);
	TI=0;
	}
}
//----------------------------------------------------------------------------------------
//			自检函数
//----------------------------------------------------------------------------------------
void	Self_Check(void)
{
//	检测数据电压


//	检测恒流源


//	检测参考电压


//	通信校验

}

//-----------------------------------------------------------------------------------------
//			读取LM92数据函数
//-----------------------------------------------------------------------------------------
void	LM92_RD(void)
{
	BYTE	i;
	MDE = 1;
	MDO = 1;
	MCO = 1;
	I2C_Start();
	I2C_NOP();
	I2C_Write(0x91);
	//MDE = 0;
	for(i=0;i<100;i++)	I2C_NOP();
	UART_Send(I2C_RACK());
	I2C_NOP();
	Temp_Buffer[0] = I2C_Read();
	I2C_ACK();
	Temp_Buffer[1] = I2C_Read();
	I2C_NACK();
	I2C_Stop();
}

//----------------------------------------------------------------------------------------
//			向串口发送数据函数
//----------------------------------------------------------------------------------------
void	UART_Send(BYTE	byte_send)
{
	ES = 0;
	SBUF = byte_send;
	while(!TI);
	TI = 0;
	ES = 1;	 	
}

//-----------------------------------------------------------------------------------------
//			向I2C总线写数据函数
//-----------------------------------------------------------------------------------------
void	I2C_Write(BYTE	I2C_Data)
{
	BYTE	i;
	//MDE = 1;	
	I2C_NOP();
	
	for(i=0;i<8;i++)
	{
		SCK = 0;
	 	I2C_NOP();
	 	if(I2C_Data & 0x080)	SDA = 1;
		else	SDA = 0;
		I2C_Data = I2C_Data << 1;
		I2C_NOP();
		SCK = 1;
	   	I2C_NOP();
	}
	SCK = 0;
	I2C_NOP();
}

//-----------------------------------------------------------------------------------------
//			从I2C总线读数据函数
//-----------------------------------------------------------------------------------------
BYTE	I2C_Read(void)
{
	BYTE	i,I2C_Data = 0;
	//MDE = 0;
	SCK = 0;
	I2C_NOP();
	SDA = 1;
	
	for(i=0;i<8;i++)
	{
		SCK = 0;
		I2C_NOP();
		SCK = 1;
		I2C_NOP();
		if(SDA)	I2C_Data ++;
		I2C_Data = I2C_Data << 1;
	}
	SCK = 0;
	I2C_NOP();

	return(I2C_Data);
}

//-----------------------------------------------------------------------------------------
//			I2C起始函数
//-----------------------------------------------------------------------------------------
void	I2C_Start(void)
{
	//MDE = 1;			//	发送状态
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
	SDA = 1;			//	SDA = 1
	I2C_NOP();
	SCK = 1;			//	SCL = 1
	I2C_NOP();
	SDA = 0;		   	//	SDA = 0
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
}

//-----------------------------------------------------------------------------------------
//			I2C停止函数
//-----------------------------------------------------------------------------------------
void	I2C_Stop(void)
{
	//MDE = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
	SDA = 0;			//	SDA = 0
	I2C_NOP();
	SCK = 1;			//	SCL = 1
	I2C_NOP();
	SDA = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
}

//-----------------------------------------------------------------------------------------
//			I2C确认函数
//-----------------------------------------------------------------------------------------
void	I2C_ACK(void)
{
	//MDE = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
	SDA = 0;
	I2C_NOP();
	SCK = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
}

//-----------------------------------------------------------------------------------------
//			I2C非确认函数
//-----------------------------------------------------------------------------------------
void	I2C_NACK(void)
{
	//MDE = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
	SDA = 1;
	I2C_NOP();
	SCK = 1;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
}

//-----------------------------------------------------------------------------------------
//			I2C接收确认信号函数
//-----------------------------------------------------------------------------------------
BYTE	I2C_RACK(void)
{
 	BYTE	i;	
	//MDE = 0;
	I2C_NOP();
	SCK = 0;
	I2C_NOP();
	SDA = 1;
	I2C_NOP();
	SCK = 1;
	I2C_NOP();
	if(SDA)	i = 0xEE;
	else	i = 0xAA;
	SCK = 0;
	I2C_NOP();	
	return(i);	
}

//-----------------------------------------------------------------------------------------
//			延时函数
//-----------------------------------------------------------------------------------------
void	I2C_NOP(void)
{
	BYTE	i;
	for(i=0;i<32;i++);
}

//----------------------------------------------------------------------------------------
//			校验码初始化函数
//----------------------------------------------------------------------------------------
void	CRC_Init(void)
{
	CRC_Buffer[0] = 0xFF;			//	校验码低字节
	CRC_Buffer[1] = 0xFF;			//	校验码高字节
}

//----------------------------------------------------------------------------------------
//			校验码计算函数
//----------------------------------------------------------------------------------------
void	ModBus_CRC(BYTE	Data_CRC)
{
	BYTE 	i;	UINT	CRC;
	CRC_Buffer[0] ^= Data_CRC;
	
	for(i=0;i<8;i++)
	{
		Data_CRC = CRC_Buffer[0] & 0x01;
		CRC = ((UINT)(CRC_Buffer[1]) << 8) + CRC_Buffer[0];
 		CRC = CRC >> 1;
		CRC_Buffer[1] = ((BYTE)(CRC >> 8)) & 0x7F;
		CRC_Buffer[0] = (BYTE)(CRC);

		if(Data_CRC == 0x01)
		{
			CRC_Buffer[1] ^= 0xA0;
			CRC_Buffer[0] ^= 0x01;
		}
	}	
}

//----------------------------------------------------------------------------------------
//			延时函数
//----------------------------------------------------------------------------------------
void	Delay(void)
{
 	BYTE	i,j;
	for(i=0;i<0xFF;i++)
		for(j=0;j<0xFF;j++);                       
} 

⌨️ 快捷键说明

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