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

📄 i2c.c

📁 c8051单片机程序包,keil C编写
💻 C
📖 第 1 页 / 共 2 页
字号:
				}
				ch=Input(48,2,RealTime.RT.Second,0,0x59);
				if (ch!=0xff)
				{
					RealTime.RT.Second=ch;
				}

				ch=Input(0,4,RealTime.RT.Year,0,0x20);
				if (ch!=0xff)
				{
					RealTime.RT.Year=ch;
				}
				ch=Input(24,4,RealTime.RT.Month,0x1,0x12);
				if (ch!=0xff)
				{
					RealTime.RT.Month=ch;
				}
				ch=Input(48,4,RealTime.RT.Day,0x1,0x31);
				if (ch!=0xff)
				{
					RealTime.RT.Day=ch;
				}
				SetRealClock();
				return;				
			case 0xd: //"D"键忽略设置
				return;				
			default:
				break;
		}
		WaitKeyOff();
	}
}

void TestI2C (void)
{
unsigned char var ;
char KeyValue;
	WDTCN = 0xde;									// disable watchdog timer
	WDTCN = 0xad;
	
	OSCICN |= 0x03;								// Set internal oscillator to highest setting
														// (16 MHz)

	XBR0 |= 0x07;									// Route SMBus to GPIO pins through crossbar
	XBR2 |= 0x44;									// Enable crossbar and weak pull-ups

    P0MDOUT |= 0x1D; 
    P1MDOUT |= 0x01; 
	
	SMB0CN = 0x44;									// Enable SMBus with ACKs on acknowledge cycle
	SMB0CR = -80;									// SMBus clock rate = 100kHz.

	EIE1 |= 2;										// SMBus interrupt enable
	EA = 1;											// Global interrupt enable

	SM_BUSY = 0;									// Free SMBus for first transfer.

//	SetRealClockINT1(0x8000);
	var = GetRealClockStatus();
	ResetRealClock();
	var = GetRealClockStatus();
	SetRealClockStatus(0xC2);  //24小时制
	var = GetRealClockStatus();
	GetRealClock();
/*	RealTime.RT.Year=0x02;	
	RealTime.RT.Month=0x06;	
	RealTime.RT.Day=0x05;	
	RealTime.RT.Week=0x02;	
	RealTime.RT.Hour=0x11;	
	RealTime.RT.Minute=0x14;	
	RealTime.RT.Second=0x45;	
*/	SetRealClock();
	GetRealClock();
	InitLCD();
	LCD_WriteHZ(0,1,Shi); 
	LCD_WriteHZ(2,1,Zhong); 
//在0,2处显示00:00:00
	LCD_DispChar(0,2,0); //128*64  取值x=0-128 y=0-8
	LCD_DispChar(8,2,0);
	LCD_DispChar(16,2,0xa);
	LCD_DispChar(24,2,0);
	LCD_DispChar(32,2,0);
	LCD_DispChar(40,2,0xa);
	LCD_DispChar(48,2,0);
	LCD_DispChar(56,2,0);
//在0,4处显示02/01/01
	LCD_DispChar(0,4,0); //128*64  取值x=0-128 y=0-8
	LCD_DispChar(8,4,2);
	LCD_DispChar(16,4,0xb);
	LCD_DispChar(24,4,0);
	LCD_DispChar(32,4,1);
	LCD_DispChar(40,4,0xb);
	LCD_DispChar(48,4,0);
	LCD_DispChar(56,4,1);
	for (;;)
	{
		KeyValue=GetKeyValue();
		switch (KeyValue)
		{
			case -1:
				break;
			case 0xf: //"F"键设置时间
				{
					LCD_WriteHZ(0,1,xiu); 
					LCD_WriteHZ(2,1,gai); 
					LCD_WriteHZ(4,1,Shi); 
					LCD_WriteHZ(6,1,Zhong); 
					SetTime();
					LCD_WriteHZ(0,1,Shi); 
					LCD_WriteHZ(2,1,Zhong); 
					LCD_WriteHZ(4,1,Blank); 
					LCD_WriteHZ(6,1,Blank); 
				}
				break;
			default:
				break;
		}
		WaitKeyOff();
		GetRealClock();
		LCD_DispChar(0,2,RealTime.RT.Hour/16); //128*64  取值x=0-128 y=0-8
		LCD_DispChar(8,2,RealTime.RT.Hour%16);
		LCD_DispChar(24,2,RealTime.RT.Minute/16);
		LCD_DispChar(32,2,RealTime.RT.Minute%16);
		LCD_DispChar(48,2,RealTime.RT.Second/16);
		LCD_DispChar(56,2,RealTime.RT.Second%16);
		//在0,4处显示02/01/01
		LCD_DispChar(0,4,RealTime.RT.Year/16); 
		LCD_DispChar(8,4,RealTime.RT.Year%16);
		LCD_DispChar(24,4,RealTime.RT.Month/16);
		LCD_DispChar(32,4,RealTime.RT.Month%16);
		LCD_DispChar(48,4,RealTime.RT.Day/16);
		LCD_DispChar(56,4,RealTime.RT.Day%16);
		Delay1ms(100);	
	}
}

//------------------------------------------------------------------------------------
// Interrupt Service Routine
//------------------------------------------------------------------------------------
void SMBUS_ISR (void) interrupt 7
{
	switch (SMB0STA)
		{ 	// SMBus 状态码SMB0STA 寄存器
			// 主发送器/接收器起始条件已发送
		case SMB_START:
			SMB0DAT = COMMAND ; // 装入要访问的从器件的地址
			STA = 0; 			// 手动清除START 位
			break;
			//主发送器/接收器重复起始条件已发送
			// 该状态只应在读操作期间出现在存储器地址已发送并得到确认之后 ?
		case SMB_RP_START:
			SMB0DAT = COMMAND; // COMMAND 中应保持从地址 + R.
			STA = 0;
			break;
			// 主发送器从地址 + WRITE 已发送收到ACK
		case SMB_MTADDACK:
			// 主发送器数据字节已发送收到ACK
		case SMB_MTDBACK:
			if (BYTE_NUMBER)
			{
					SMB0DAT = revolve(*I2CDataBuff);					// If R/W=WRITE, load byte to write.
					I2CDataBuff++;
					BYTE_NUMBER--;			
			}
			else
			{
				STO = 1;	SM_BUSY = 0;						// Free SMBus
			}
			break;
			// 主发送器从地址 + WRITE 已发送收到NACK
			// 从器件不应答发送STOP + START 重试
		case SMB_MTADDNACK:
			STO = 1;			STA = 1;
		break;
			// 主发送器数据字节已发送收到NACK
			// 从器件不应答发送STOP + START 重试
		case SMB_MTDBNACK:
			STO = 1;			STA = 1;
		break;
			// 主发送器竞争失败
			// 不应出现如果出现重新开始传输过程
		case SMB_MTARBLOST:
			STO = 1;			STA = 1;
		break;

			// 主接收器从地址 + READ 已发送,收到ACK
		case SMB_MRADDACK:
			AA = 1; // 在应答周期ACK
			if (!BYTE_NUMBER)
			{	
				STO = 1;	SM_BUSY = 0; // 释放SMBus
			}
		break;
			// 主接收器从地址 + READ 已发送收到NACK
			// 从器件不应答发送重复起始条件重试
		case SMB_MRADDNACK:
			STA = 1;
		break;
			// 收到数据字节ACK 已发送
			// 该状态不应出现因为AA 已在前一状态被清0 如果出现发送停止条件
		case SMB_MRDBACK:
			if (BYTE_NUMBER)
			{
				*I2CDataBuff=revolve(SMB0DAT);		
				I2CDataBuff++;
				BYTE_NUMBER--;			
			}
			if (!BYTE_NUMBER)	AA= 0;
		break;
			// 收到数据字节NACK 已发送
			// 读操作已完成读数据寄存器后发送停止条件
		case SMB_MRDBNACK:
			STO = 1;
			SM_BUSY = 0; // 释放SMBus
		break;
			// 在本应用中所有其它状态码没有意义通信复位
		default:
			STO = 1; // 通信复位
			SM_BUSY = 0; 
		break;
		}
	SI=0; // 清除中断标志
}
/*
{
	switch (SMB0STA){			// Status code for the SMBus (SMB0STA register)
		case SMB_START:					
			SMB0DAT = COMMAND;					// COMMAND should hold slave address + R.
			break;
		case SMB_MTADDNACK:
			STO = 1;
			STA = 1;
			break;
		case SMB_RP_START:
//			SMB0DAT = COMMAND;					// COMMAND should hold slave address + R.
//			STA = 0;											
//			break;
		case SMB_MTADDACK:
		case SMB_MTDBACK:
			if (BYTE_NUMBER)
			{
					if (COMMAND & 0x01)					// If R/W=READ, 
					{
						STA = 1;
					}
					else
					{
						SMB0DAT = *I2CDataBuff;					// If R/W=WRITE, load byte to write.
						I2CDataBuff++;
						BYTE_NUMBER--;			
					}
			}
			else
			{
				STO = 1;
				SM_BUSY = 0;						// Free SMBus
			}
			break;
		
		// Master Transmitter: Data byte transmitted.  NACK received.
		// Slave not responding.  Send STOP followed by START to try again.
		case SMB_MTDBNACK:
			STO = 1;
			STA = 1;
			break;
		
		// Master Transmitter: Arbitration lost.
		// Should not occur.  If so, restart transfer.
		case SMB_MTARBLOST:
			STO = 1;
			STA = 1;
			break;

		// Master Receiver: Slave address + READ transmitted.  NACK received.
		// Slave not responding.  Send repeated start to try again.
		case SMB_MRADDNACK:
			STA = 1;
			break;

		// Data byte received.  ACK transmitted.
		// State should not occur because AA is set to zero in previous state.
		// Send STOP if state does occur.
		case SMB_MRDBACK:
			STO = 1;
			SM_BUSY = 0;
			break;

		// Master Receiver: Slave address + READ transmitted.  ACK received.
		// Set to transmit NACK after next transfer since it will be the last (only) byte.
		case SMB_MRADDACK:
//			AA = 0;										// NACK sent on acknowledge cycle.
//			break;

		// Data byte received.  NACK transmitted.
		// Read operation has completed.  Read data register and send STOP.
		case SMB_MRDBNACK:
			if (BYTE_NUMBER)
			{
					if (COMMAND & 0x01)					// If R/W=READ, 
					{
						*I2CDataBuff=SMB0DAT;		
						I2CDataBuff++;
					}
					BYTE_NUMBER--;			
			}
			else
			{
				STO = 1;
				SM_BUSY = 0;						// Free SMBus
			}
			break;
		// All other status codes meaningless in this application. Reset communication.
		default:
			STO = 1;										// Reset communication.
			SM_BUSY = 0;
			break;
		}
	
	SI=0;													// clear interrupt flag
}
*/

⌨️ 快捷键说明

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