📄 i2c.c
字号:
#include <c8051f020.h> // SFR declarations
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define WRITE 0x00 // SMBus WRITE command
#define READ 0x01 // SMBus READ command
// Device addresses (7 bits, lsb is a don't care)
#define CLOCK3530_ADDRESS_RESET 0x60 //1 ack
#define CLOCK3530_ADDRESS_STATUS 0x62 //2 ack
#define CLOCK3530_ADDRESS_DATEHOUR 0x64 //8 ack year month day week hour minute second
#define CLOCK3530_ADDRESS_HOUR 0x66 //4 ack hour minute second
#define CLOCK3530_ADDRESS_INT1 0x68 //3 ack
#define CLOCK3530_ADDRESS_INT2 0x6A //3 ack
union
{
unsigned char ClockString[7];
struct RealClock
{
unsigned char Year,Month,Day,Week,Hour,Minute,Second;
} RT;
} RealTime;
// SMBus states:
// MT = Master Transmitter
// MR = Master Receiver
#define SMB_BUS_ERROR 0x00 // (all modes) BUS ERROR
#define SMB_START 0x08 // (MT & MR) START transmitted
#define SMB_RP_START 0x10 // (MT & MR) repeated START
#define SMB_MTADDACK 0x18 // (MT) Slave address + W transmitted;
// ACK received
#define SMB_MTADDNACK 0x20 // (MT) Slave address + W transmitted;
// NACK received
#define SMB_MTDBACK 0x28 // (MT) data byte transmitted; ACK rec'vd
#define SMB_MTDBNACK 0x30 // (MT) data byte transmitted; NACK rec'vd
#define SMB_MTARBLOST 0x38 // (MT) arbitration lost
#define SMB_MRADDACK 0x40 // (MR) Slave address + R transmitted;
// ACK received
#define SMB_MRADDNACK 0x48 // (MR) Slave address + R transmitted;
// NACK received
#define SMB_MRDBACK 0x50 // (MR) data byte rec'vd; ACK transmitted
#define SMB_MRDBNACK 0x58 // (MR) data byte rec'vd; NACK transmitted
//-----------------------------------------------------------------------------------
//Global VARIABLES
//-----------------------------------------------------------------------------------
char COMMAND; // Holds the slave address + R/W bit for use in the SMBus ISR.
unsigned char *I2CDataBuff;
char BYTE_NUMBER; // Used by ISR to check what data has just been
// sent - High address byte, Low byte, or data byte
unsigned char HIGH_ADD, LOW_ADD; // High & Low byte for EEPROM memory address
bit SM_BUSY; // This bit is set when a send or receive
// is started. It is cleared by the
// ISR when the operation is finished.
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SMBus_ISR (void);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
//
// Main routine configures the crossbar and SMBus, and tests
// the SMBus interface between the three EEPROMs
void ResetRealClock(void)
{
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 0; // 2 address bytes.
COMMAND = (CLOCK3530_ADDRESS_RESET | READ); // Chip select + READ
STA = 1; // Start transfer
while (SM_BUSY); // Wait for transfer to finish
}
//======================写S-3530A内部实时数据寄存器程序=====================
//功能:将设定年、月、日、星期、时、分、秒数据写入S-3530A |
//入口:发送数据放在年、月、日、星期、时、分、秒各寄存器 |
//出口:NONE |
//==========================================================================
void SetRealClock(void)
{
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 7; // 2 address bytes.
COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | WRITE); // Chip select + WRITE
I2CDataBuff = &RealTime.ClockString[0]; // Data to be writen
STA = 1; // Start transfer
}
//==================读S-3530A实时数据寄存器子程序===========================
//功能:从S-3530A读入当前时间数据 |
//入口:NONE |
//出口:接收数据放在年、月、日、星期、时、分、秒各寄存器 |
//==========================================================================
void GetRealClock(void)
{
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 7; // 2 address bytes.
COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | READ); // Chip select + READ
I2CDataBuff = &RealTime.ClockString[0]; // Data to be writen
STA = 1; // Start transfer
while (SM_BUSY); // Wait for transfer to finish
}
//============================写状态寄存器程序==============================
//功能:读/写S-3530A状态寄存器,对S-3530A进行设置 |
//入口:NONE 出口:NONE |
//==========================================================================
unsigned char GetRealClockStatus(void)
{
unsigned char result;
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 1;
COMMAND = (CLOCK3530_ADDRESS_STATUS | READ);
I2CDataBuff = &result;
STA = 1; // Start transfer
while (SM_BUSY); // Wait for transfer to finish
return result;
}
void SetRealClockStatus(unsigned char status)
{
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 1;
COMMAND = (CLOCK3530_ADDRESS_STATUS | WRITE);
I2CDataBuff = &status;
STA = 1; // Start transfer
}
/*
void SetRealClockINT1(unsigned int Int1)
{
while (SM_BUSY); // Wait for SMBus to be free.
SM_BUSY = 1; // Occupy SMBus (set to busy)
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
BYTE_NUMBER = 2;
COMMAND = (CLOCK3530_ADDRESS_INT1 | WRITE);
I2CDataBuff = (unsigned char*)&Int1;
STA = 1; // Start transfer
}
*/
#include "INTRINS.H"
unsigned char revolve(unsigned char val)
{
char i;
unsigned char val1=0;
for (i=0;i<8;i++)
{
if (val&0x1)
val1++;
val1=_crol_(val1,1);
val=_cror_(val,1);
}
val1=_cror_(val1,1);
return val1;
}
/*-- 文字: 时 --*/
char code Shi[]=
{
0x00,0x00,0xFC,0x44,0x44,0xFC,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x08,0x08,0x00,
0x00,0x00,0x1F,0x04,0x04,0x0F,0x00,0x00,0x00,0x11,0x20,0x1F,0x00,0x00,0x00,0x00,
};
/*-- 文字: 钟 --*/
char code Zhong[]=
{
0x00,0x60,0x38,0xE7,0x24,0x24,0x04,0x00,0xF8,0x88,0x88,0xFF,0x88,0x88,0xF8,0x00,
0x00,0x01,0x01,0x3F,0x11,0x09,0x01,0x00,0x01,0x00,0x00,0x3F,0x00,0x00,0x01,0x00,
};
/*-- 文字: 修 --*/
char code xiu[]=
{
0x00,0x20,0x10,0xFC,0x03,0xF8,0x10,0x88,0x47,0x2C,0x94,0x2C,0x46,0x44,0x40,0x00,
0x00,0x00,0x00,0x3F,0x00,0x2F,0x20,0x2A,0x2A,0x15,0x14,0x0A,0x09,0x04,0x00,0x00,
};
/*-- 文字: 改 --*/
char code gai[]=
{
0x00,0x04,0xC4,0x44,0x44,0x44,0x7E,0x44,0x30,0xDF,0x10,0x10,0xF0,0x18,0x10,0x00,
0x00,0x00,0x1F,0x10,0x08,0x08,0x24,0x20,0x10,0x0B,0x04,0x0A,0x11,0x20,0x20,0x00,
};
/*-- 文字: 改 --*/
char code Blank[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void LCD_WriteHZ(char x,char y,char *Dot);
void LCD_DispChar(char x,char y,char ch); //128*64 取值x=0-128 y=0-8
void InitLCD(void);
void Delay1ms(unsigned char T);
char GetKeyValue(void);
void WaitKeyOff(void);
extern bit FlashFlag,Flag500ms;
extern unsigned char C_1s;
unsigned char Input(unsigned char x,unsigned char y,unsigned char ch,unsigned char Min,unsigned char Max)
{
char i,temp;
unsigned char loc,Value;
C_1s=30;
loc=x;
Value=ch%100;
LCD_DispChar(x,y,ch/16);
LCD_DispChar(x+1,y,ch%16);
while (C_1s)
{
i=GetKeyValue();
if (Flag500ms)
{
Flag500ms=0;
if (FlashFlag)
{
if (loc==x)
{
LCD_DispChar(loc,y,Value/16);
}
else
{
LCD_DispChar(loc,y,Value%16);
}
}
else
{
if (loc==x)
{
LCD_DispChar(loc,y,0xc);
}
else
{
LCD_DispChar(loc,y,0xc);
}
}
}
if (i!=-1)
{
WaitKeyOff();
C_1s=30;
if (i<=9) //按下的是数字键
{
if (loc==x)
{
temp=Value%16+i*16;
if ((temp<=Max)&&(temp>=Min)) //输入十位有效
{
LCD_DispChar(loc,y,i);loc+=8;
Value=temp;
}
}
else
{
temp=(Value/16)*16+i;
if ((temp<=Max)&&(temp>=Min)) //输入个位有效
{
LCD_DispChar(loc,y,i);loc=x;
Value=temp;
}
}
}
if (i==0xf) //按下"F"键
{
LCD_DispChar(x,y,Value/16);
LCD_DispChar(x+1,y,Value%16);
return Value;
}
if (i==0xd) //按下"D"键
{
LCD_DispChar(x,y,ch/16);
LCD_DispChar(x+1,y,ch%16);
return ch;
}
}
}
LCD_DispChar(x,y,ch/16);
LCD_DispChar(x+1,y,ch%16);
return 0xff;
}
void SetTime(void)
{
char KeyValue;
char ch;
for (;;)
{
KeyValue=GetKeyValue();
switch (KeyValue)
{
case -1:
break;
case 0xf: //"F"键设置时间
ch=Input(0,2,RealTime.RT.Hour,0,0x23);
if (ch!=0xff)
{
RealTime.RT.Hour=ch;
}
ch=Input(24,2,RealTime.RT.Minute,0,0x59);
if (ch!=0xff)
{
RealTime.RT.Minute=ch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -