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

📄 lesson10.c

📁 基于8051的生产线记件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*time1_interrupt段时间计数*/
/*************************************************/
void time1_interrupt(void) interrupt 3 using 0
{
	uchar uc_device_addr,uc_device_sub_addr;
	uchar j;

	g_ui_timer1_interval_cnt ++;
	if(g_ui_timer1_interval_cnt >= 600)//6000*0.1s=10min
	{
		TH1 = 0x3C   ;//初值15536
		TL1 = 0xB0   ;//100ms=0.1s
		g_ui_timer1_interval_cnt = 0;//重新开始计数
		g_uc_data_send[0] = g_st_current_time.min;
		g_uc_data_send[1] = g_st_current_time.sec;
		g_uc_data_send[2] = g_uc_log_number;
		uc_device_addr = 0xA0;//0xA0=1010 0000B, 1010is the device number,000 is the A2A1A0 hard wired, 0 write.
		uc_device_sub_addr = 0x00 + ((g_uc_time_interval + 1) << 3);//EEPROM 首地址
		ISendStr(uc_device_addr,uc_device_sub_addr,g_uc_data_send,3);//以页方式存储
		g_uc_time_interval ++;//时间段加1
		g_uc_log_number = 0;//新的时间段开始,清除记录值
		beep = 0;//连续发声
		delay(100,100);
		beep = 1;
	}
	if(g_uc_time_interval >= 7)
	{
		ET0 = 0;//禁止T0
		ET1 = 0;
		TR0 = 0;//停止T0
		TR1 = 0;
		EX0 = 0;//禁止外部中断0		
		beep = 0;
		for(j = 0;j < 8;j++)//断续提示声
		{
			delay(200,200);
			if(beep == 0)beep = 1;
			else beep = 0;
		}
	}
}
/*************************************************/
/*int0_interrupt*/
/*************************************************/
void int0_interrupt(void) interrupt 0 using 1
{
	beep = 0;//连续发声
	delay(50,100);
	beep = 1;
	EX0 = 0;

	g_uc_log_number ++;
	if((g_uc_log_number&0x0F) > 9)//显示为10进制数,CD4511不能显示A~F
	{
		g_uc_log_number += 6;
	}
	
	delay(55,255);//在短时间内不相应那么多中断,//看产品下线的速度而定
		//如果延时过多,应该给予时钟补偿,g_uc_sec_cnt+*

	//g_st_current_time.sec += 2;//给时钟进行时间补偿2s//因为外部中断0自然优先级比timer0高
	
	EX0 = 1;
}
/*************************************************/
/*serial_interrupt*/
/*************************************************/
void serial_interrupt(void) interrupt 4 using 2
{
	EA = 0;
	RI = 0;//软件清除中断标志
	g_uc_recv_serial_cnt ++;

	beep = 0;
	delay(30,55);
	beep = 1;

	if(g_uc_recv_serial_cnt < 7)
	{
		ACC = SBUF;
		//XBYTE[g_ui_ram_addr] = ACC;//不屏蔽掉,发ACC内容回PC时显示乱码
		//g_ui_ram_addr ++;

		//ACC = uc_temp_receive[g_uc_recv_serial_cnt][2] + 0x30;
		//delay(5,200);
		//delay(5,10);
		//delay(5,0);//添加了延时后,无法把ACC中内容在PC上显示出字符
		//SBUF = 0x21;//back to IBM, check the TI
		SBUF = ACC;
		//display_led(g_uc_data_receive[0],g_uc_data_receive[1],g_uc_data_receive[2]);
	}
	else
	{
		ACC = 0x2A;//ASCII 0x21:!
		SBUF = ACC;
	}

	while(TI == 0)
	{
		delay(3,255);
	}
	TI = 0;

	EA = 1;

}
/*************************************I2C start*****************************************/
/**********************************void Start_I2C()*********************************
该函数是启动总线函数,功能是启动I2C总线,即发送I2C起始条件
注意:	在SCL高电平时,SDA从高电平变低电平表示start;
		在SCL高电平时,SDA从低电平变高电平表示stop。
*********************************************************************************/
void Start_I2C(void)
{
	SDA = 1;//发送起始条件的数据信号
	_Nop();
	SCL = 1;
	_Nop();//起始条件建立时间大于4.7us,延时
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	SDA = 0;//发送起始信号
	_Nop();//起始条件锁定时间大于4us
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	SCL = 0;//嵌住I2C总线准备发送或接收数据
	_Nop();
	_Nop();
}
/******************************************************************
该函数为结束总线函数,功能是结束I2C总线,即发送I2C结束条件
******************************************************************/
void Stop_I2C(void)
{
	SDA = 0;//发送结束条件的数据信号
	_Nop();
	SCL = 1;//发送结束条件的时钟信号
	_Nop();//结束条件建立时间大于4us
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	SDA = 1;//发送I2C总线结束信号
	_Nop();
	_Nop();
	_Nop();
	_Nop();
}

/*********************void SendB(unsigned char c)*********************************
该函数为字节数据传送函数,功能是将数据c发送出去,可以是地址,也可以是数据,发送完毕后等待应答,
并对此状态位进行操作(不应答或非应答都使ack = 0,假)。发送数据正常ack = 1;ack = 0表示被控制
器无应答或损坏。
****************************************************************/
void SendB(unsigned char c)
{
	unsigned char BitCnt;

	for(BitCnt = 0;BitCnt < 8;BitCnt++)//要传送的数据长度为8位
	{
		if((c<<BitCnt)&0x80)
			SDA = 1;//判断发送位//判断需要发送的bit为0还是1
		else 
			SDA = 0;
		_Nop();
		SCL = 1;//置时钟线为高,通知被控制器开始接收数据位
		_Nop();
		_Nop();//保证时钟高电平周期大于4us
		_Nop();
		_Nop();
		_Nop();
		SCL = 0;
	}
	_Nop();
	_Nop();
	SDA = 1;//8位发送完毕后,释放数据线准备接收应答位
	_Nop();
	_Nop();
	SCL = 1;
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	if(SDA == 1)
	{
		ack = 0;//判断是否接收到应答信号			
	}
	else
		ack = 1;
	SCL = 0;
	_Nop();
	_Nop();
}
/***************************unsigned char RcvB()******************************
该函数是字节数据传送函数,功能:接收从器件传来的数据,并判断总线错误(不发应答信号),
发送完毕后调用应答函数。
************************************************************************/
unsigned char RcvB(void)
{
	unsigned char retc;
	unsigned char BitCnt;

	retc = 0;
	SDA = 1;
	for(BitCnt = 0;BitCnt < 8;BitCnt++)
	{
		_Nop();
		SCL = 0;//置时钟总线为低,准备接收数据
		_Nop();
		_Nop();//时钟低电平大于4us
		_Nop();
		_Nop();
		_Nop();
		SCL = 1;//置时钟总线为高,是数据线上数据有效
		_Nop();
		_Nop();
		retc = retc << 1;
		if(SDA == 1) retc = retc + 1;//读数据位,接收的数据位放入retc中
		_Nop();
		_Nop();
	}
	SCL = 0;
	_Nop();
	_Nop();
	return(retc);
}
/***********************************void Ack_I2C(bit a)*********************************
该函数为应答函数,功能:主控制器进行应答信号(主机发送的应答信号)(对于从机的应答信号,主机只需要检测)
******************************************************************************************/
void Ack_I2C(bit a)
{
	if(a == 0)
		SDA = 0;//在此发出应答或非应答信号
	else
		SDA = 1;
	_Nop();
	_Nop();
	_Nop();
	SCL = 1;
	_Nop();//时钟低电平周期大于4us
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	SCL = 0;//清时钟线,嵌住I2C总线以便接收
	_Nop();
	_Nop();
}
/******************************bit ISendB(unsigned char sla, unsigned char c)*********************************
该函数为无子地址器件发送字节数据函数,功能:从启动总线到发送地址、数据,结束总线的全过程,从器件地址sla,如果返回1,表示操作成功,否则操作有误。
*********************************************************************************************/
/*bit ISendB(unsigned char sla, unsigned char c)
{
	Start_I2C();
	SendB(sla);
	if(ack == 0) 
		return(0);
	SendB(c);
	if(ack == 0)
		return(0);
	Stop_I2C();
	return(1);
}
*/
/*******************************bit IRcvB(unsigned char sla, unsigned char *c)*****************************
该函数为向无子地址器件读字节数据函数,功能是从启动总线到发送地址、读数据,结束总线的全过程。
从器件地址sla返回值在c,如果返回1表示操作成功,否则操作有误。
*****************************************************************************************/
/*bit IRcvB(unsigned char sla, unsigned char *c)
{
	Start_I2C();//启动总线
	SendB(sla+1);//发送器件地址;LSB=1,读数据,LSB=0,写数据。
	if(ack == 0)
		return(0);
	*c = RcvB();//读取数据
	Ack_I2C(1);//发送非应答位
	Stop_I2C();//结束总线
	return(1);
}
*/
/*************bit ISendStr(unsigned char sla,unsigned char suba, unsigned char *s, unsigned char no)*****************************************
该函数为向有子地址器件发送多字节数据函数,功能是从启动总线到发送地址、子地址,数据结束总线的全过程,从器件地址sla,子地址suba。
发送内容是s指向的内容,发送no字节,如果返回1表示操作成功,否则操作有误。
注意:	不同的24CXX,no的最大值不用;对于24C01、24C02,按页写最大为8 bytes
		对于24C04、08、16,按页写最大为16 bytes
		向EEPROM写时,应答信号是从机在正确接收数据后,自动给出
***********************************************************************************************/
bit ISendStr(unsigned char sla, unsigned char suba, unsigned char * s,unsigned char no)
{
	unsigned char i;

	Start_I2C();//启动总线

	SendB(sla);//发送器件地址
	if(ack == 0)		
		return(0);
	SendB(suba);//发送器件子地址
	if(ack == 0)
		return(0);

	for(i=0;i<no;i++)
	{
		SendB(*s);//发送数据
		if(ack == 0)return (0);
		s++;
	}

	Stop_I2C();//结束总线
	return(1);
}
/****************************bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)************************
该函数为向有子地址器件读取多字节数据函数,功能是从启动总线到发送地址、子地址,读数据,结束总线的全过程。
从器件地址sla、子地址suba,读取内容放入s指向的存储区,读no字节。如果返回1表示操作争取,否则表示操作有误。
注意:	读EEPROM24CXX时,应答信号是主机正确接收数据后发出
		接收的最后一位数据,给出非应答信号
******************************************************************************************************/
bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
	unsigned char i;

	Start_I2C();//启动总线
	SendB(sla);//发送器件地址
	if(ack ==0)
		return(0);
	SendB(suba);//发送器件子地址
	if(ack ==0)
		return(0);
	Start_I2C();
	SendB(sla+1);//LSB=1,读数据,LSB=0,写数据。
	if(ack ==0)
		return(0);
	for(i = 0;i< no-1;i++)
	{
		*s=RcvB();//发送数据
		Ack_I2C(0);//主机发送应答位
		s++;
	}
	*s = RcvB();
	Ack_I2C(1);//发送非应答位。最后一位数据时,主机发送非应答信号。
	Stop_I2C();//结束总线
	return(1);
}
/************************************I2C End*********************************************/

⌨️ 快捷键说明

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