?? 340_i2c.c
字號(hào):
#include <c8051f340.h>
#define uchar unsigned char
#define uint unsiged int
#define SYSCLK 12000000 // 12M內(nèi)部時(shí)鐘
#define SMB_FREQUENCY 50000 //SMBUS目標(biāo)時(shí)鐘頻率
#define WRITE 0x00 // SMBus 寫(xiě)命令
#define READ 0x01 // SMBus 讀命令
#define EEPROM_ADDR 0xA0 // 鐵電存儲(chǔ)器的地址
#define SMB_BUFF_SIZE 0x08 // 定義傳輸?shù)刂?
#define SMB_MTSTA 0xE0 // 開(kāi)始傳輸
#define SMB_MTDB 0xC0 // 數(shù)據(jù)傳輸
#define SMB_MRDB 0x80 // 數(shù)據(jù)接收
uchar* pSMB_DATA_IN; // 定義全局變量
uchar SMB_SINGLEBYTE_OUT; // 定義握手信號(hào)
uchar* pSMB_DATA_OUT; // 數(shù)據(jù)存儲(chǔ)變量
unsigned long q;
uchar SMB_DATA_LEN; // SMBUS傳輸數(shù)據(jù)長(zhǎng)度
uchar WORD_ADDR; // 數(shù)據(jù)地址
uchar TARGET; //目標(biāo)從地址
uchar temp_char;
uchar retval;
bit SMB_BUSY = 0; // 定義SMBUS忙標(biāo)志位
bit SMB_RW; // 傳輸標(biāo)志
bit SMB_SENDWORDADDR; // 傳輸?shù)刂肺?
bit SMB_RANDOMREAD; // 傳輸開(kāi)始信號(hào)發(fā)出后
bit SMB_ACKPOLL; // 設(shè)置應(yīng)答
sfr16 TMR3RL = 0x92;
sfr16 TMR3 = 0x94;
void SMBus_Init (void); //SMBUS初始化函數(shù)
void Timer1_Init (void); //定時(shí)器1初始化函數(shù)
void Timer3_Init (void); //定時(shí)器3初始化函數(shù)
void Port_Init (void);
void SMBus_ISR (void);
void Timer3_ISR (void);
void EEPROM_ByteWrite(uchar addr, uchar dat);
void EEPROM_WriteArray (uchar dest_addr, uchar* src_addr,
uchar len);
uchar EEPROM_ByteRead(uchar addr);
void EEPROM_ReadArray (uchar* dest_addr, uchar src_addr,
uchar len);
void main (void)
{
char in_buff[9] ;
char out_buff[8] = "ABCDEFG2";
PCA0MD &= ~0x40; // 關(guān)看門(mén)狗定時(shí)器
OSCICN |= 0x03; // 初始化內(nèi)部12M系統(tǒng)時(shí)鐘
Port_Init (); // 端口初始化
Timer1_Init ();
Timer3_Init ();
SMBus_Init (); // 初始化SMBUS
EIE1 |= 1; // SMBus 中斷允許
IE |= 0x20; // Timer2 中斷允許
EA = 1;
while(1){
EEPROM_ByteWrite(0x25, 0xAA); //寫(xiě)數(shù)據(jù)0XAA到地址0X25
temp_char = EEPROM_ByteRead(0x25); //讀數(shù)據(jù)從地址0X25 此處設(shè)斷點(diǎn)觀察值變化
EEPROM_ByteWrite(0x20, 0xBB); //寫(xiě)數(shù)據(jù)0Xbb到地址0X20
EEPROM_ByteWrite(0x38, 0xCC); //寫(xiě)數(shù)據(jù)0Xcc到地址0X38
temp_char = EEPROM_ByteRead(0x20); //讀數(shù)據(jù)從地址0X20 此處設(shè)斷點(diǎn)觀察值變化
temp_char = EEPROM_ByteRead(0x38); //讀數(shù)據(jù)從地址0X38 此處設(shè)斷點(diǎn)觀察值變化
EEPROM_WriteArray(0x100, out_buff, sizeof(out_buff)); //寫(xiě)數(shù)組數(shù)據(jù)到地址0X100
EEPROM_ReadArray(in_buff, 0x100, sizeof(in_buff));} //讀數(shù)據(jù)從地址0X100 此處設(shè)斷點(diǎn)觀察值變化
}
/*******************************************************************************
鐵電存儲(chǔ)器寫(xiě)字節(jié)函數(shù)
參數(shù):addr 目標(biāo)地址
dat 要寫(xiě)數(shù)據(jù)
*******************************************************************************/
void EEPROM_ByteWrite( uchar addr, uchar dat )
{
while (SMB_BUSY);
SMB_BUSY = 1;
TARGET = EEPROM_ADDR;
SMB_RW = WRITE;
SMB_SENDWORDADDR = 1;
SMB_RANDOMREAD = 0;
SMB_ACKPOLL = 1;
WORD_ADDR = addr;
SMB_SINGLEBYTE_OUT = dat;
pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;
SMB_DATA_LEN = 1;
STA = 1;
}
/**********************************************************************
連續(xù)向鐵電存儲(chǔ)器寫(xiě)入多個(gè)字節(jié)
參數(shù):
dest_addr 目標(biāo)地址
src_addr 目標(biāo)數(shù)據(jù)
len 數(shù)據(jù)長(zhǎng)度
***********************************************************************/
void EEPROM_WriteArray (uchar dest_addr, uchar* src_addr,
uchar len)
{
uchar i;
uchar* pData = (uchar*) src_addr;
for( i = 0; i <= len; i++ )
{
EEPROM_ByteWrite(dest_addr++, *pData++);
}
}
/**************************************************************************
函數(shù)功能:從目標(biāo)地址讀數(shù)據(jù)
參數(shù):addr 目標(biāo)地址
***************************************************************************/
uchar EEPROM_ByteRead( uchar addr)
{
while (SMB_BUSY);
SMB_BUSY = 1;
TARGET = EEPROM_ADDR;
SMB_RW = WRITE;
SMB_SENDWORDADDR = 1;
SMB_RANDOMREAD = 1;
SMB_ACKPOLL = 1;
WORD_ADDR = addr;
pSMB_DATA_IN = &retval;
SMB_DATA_LEN = 1;
STA = 1;
while(SMB_BUSY);
return retval;
}
/***************************************************************************
函數(shù)功能:從目標(biāo)地址連續(xù)讀出數(shù)據(jù)
參數(shù): dest_addr 保存數(shù)據(jù)的數(shù)組
src_addr 目標(biāo)地址
len 數(shù)據(jù)長(zhǎng)度
****************************************************************************/
void EEPROM_ReadArray (uchar* dest_addr, uchar src_addr,
uchar len)
{
while (SMB_BUSY);
SMB_BUSY = 1;
TARGET = EEPROM_ADDR;
SMB_RW = WRITE;
SMB_SENDWORDADDR = 1;
SMB_RANDOMREAD = 1;
SMB_ACKPOLL = 1;
WORD_ADDR = src_addr;
pSMB_DATA_IN = (unsigned char*) dest_addr;
SMB_DATA_LEN = len;
STA = 1;
while(SMB_BUSY);
}
/*******************************************************************************
函數(shù)功能:SMBUS初始化
*******************************************************************************/
void SMBus_Init (void)
{
SMB0CF = 0x5D;
SMB0CF |= 0x80;
}
/*******************************************************************************
函數(shù)功能:定時(shí)器3初始化
*******************************************************************************/
void Timer3_Init (void)
{
TMR3CN = 0x00;
TMR3 = -(SYSCLK/12/40);
TMR3RL = -(SYSCLK/12/40);
CKCON &= ~0x40;
TMR3 |= 0x04;
}
/*******************************************************************************
函數(shù)功能:定時(shí)器1初始化
*******************************************************************************/
void Timer1_Init (void)
{
CKCON &= ~0x0B;
TMOD = 0x20;
TH1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TL1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TR1 = 1;
}
/*******************************************************************************
函數(shù)功能:端口初始化
*******************************************************************************/
void Port_Init (void)
{ P0SKIP = 0xff;
P1SKIP =0x07;
XBR0 = 0x04;
XBR1 = 0x40;
P0MDIN = 0xFF;
P0MDOUT = 0x00;
P0 = 0xFF;
P1MDOUT = 0x00;
}
/*******************************************************************************
函數(shù)功能:SMBUS處理函數(shù),這部分函數(shù)按照SMBUS通訊協(xié)議進(jìn)行判斷處理.具體請(qǐng)參見(jiàn)F340數(shù)
據(jù)手冊(cè)SMBUS通訊部分.
*******************************************************************************/
void SMBus_ISR (void) interrupt 7
{
bit FAIL = 0;
static char i;
static bit SEND_START = 0;
switch (SMB0CN & 0xF0)
{
case SMB_MTSTA:
SMB0DAT = TARGET;
SMB0DAT |= SMB_RW;
STA = 0;
i = 0;
break;
case SMB_MTDB:
if (ACK)
{
if (SEND_START)
{
STA = 1;
SEND_START = 0;
break;
}
if(SMB_SENDWORDADDR)
{
SMB_SENDWORDADDR = 0;
SMB0DAT = WORD_ADDR;
if (SMB_RANDOMREAD)
{
SEND_START = 1;
SMB_RW = READ;
}
break;
}
if (SMB_RW==WRITE)
{
if (i < SMB_DATA_LEN)
{
SMB0DAT = *pSMB_DATA_OUT;
pSMB_DATA_OUT++;
i++;
}
else
{
STO = 1;
SMB_BUSY = 0;
}
}
else {}
}
else
{
if(SMB_ACKPOLL)
{
STA = 1;
}
else
{
FAIL = 1;
}
}
break;
case SMB_MRDB:
if ( i < SMB_DATA_LEN )
{
*pSMB_DATA_IN = SMB0DAT;
pSMB_DATA_IN++;
i++;
ACK = 1;
}
if (i == SMB_DATA_LEN)
{
SMB_BUSY = 0;
ACK = 0;
STO = 1;
}
break;
default:
FAIL = 1;
break;
}
if (FAIL)
{
SMB0CN &= ~0x40;
SMB0CN |= 0x40;
SMB_BUSY = 0;
}
SI=0;
}
/*******************************************************************************
函數(shù)功能:25MS后對(duì)SMBUS重新初始化
*******************************************************************************/
void Timer3_ISR (void) interrupt 14
{
SMB0CN &= ~0x40;
SMB0CN |= 0x40;
TMR3CN &= ~0x80;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -