📄 i2c.c
字号:
}
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 + -