📄 340_i2c.c
字号:
#include <c8051f340.h>
#define uchar unsigned char
#define uint unsiged int
#define SYSCLK 12000000 // 12M内部时钟
#define SMB_FREQUENCY 50000 //SMBUS目标时钟频率
#define WRITE 0x00 // SMBus 写命令
#define READ 0x01 // SMBus 读命令
#define EEPROM_ADDR 0xA0 // 铁电存储器的地址
#define SMB_BUFF_SIZE 0x08 // 定义传输地址
#define SMB_MTSTA 0xE0 // 开始传输
#define SMB_MTDB 0xC0 // 数据传输
#define SMB_MRDB 0x80 // 数据接收
uchar* pSMB_DATA_IN; // 定义全局变量
uchar SMB_SINGLEBYTE_OUT; // 定义握手信号
uchar* pSMB_DATA_OUT; // 数据存储变量
unsigned long q;
uchar SMB_DATA_LEN; // SMBUS传输数据长度
uchar WORD_ADDR; // 数据地址
uchar TARGET; //目标从地址
uchar temp_char;
uchar retval;
bit SMB_BUSY = 0; // 定义SMBUS忙标志位
bit SMB_RW; // 传输标志
bit SMB_SENDWORDADDR; // 传输地址位
bit SMB_RANDOMREAD; // 传输开始信号发出后
bit SMB_ACKPOLL; // 设置应答
sfr16 TMR3RL = 0x92;
sfr16 TMR3 = 0x94;
void SMBus_Init (void); //SMBUS初始化函数
void Timer1_Init (void); //定时器1初始化函数
void Timer3_Init (void); //定时器3初始化函数
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; // 关看门狗定时器
OSCICN |= 0x03; // 初始化内部12M系统时钟
Port_Init (); // 端口初始化
Timer1_Init ();
Timer3_Init ();
SMBus_Init (); // 初始化SMBUS
EIE1 |= 1; // SMBus 中断允许
IE |= 0x20; // Timer2 中断允许
EA = 1;
while(1){
EEPROM_ByteWrite(0x25, 0xAA); //写数据0XAA到地址0X25
temp_char = EEPROM_ByteRead(0x25); //读数据从地址0X25 此处设断点观察值变化
EEPROM_ByteWrite(0x20, 0xBB); //写数据0Xbb到地址0X20
EEPROM_ByteWrite(0x38, 0xCC); //写数据0Xcc到地址0X38
temp_char = EEPROM_ByteRead(0x20); //读数据从地址0X20 此处设断点观察值变化
temp_char = EEPROM_ByteRead(0x38); //读数据从地址0X38 此处设断点观察值变化
EEPROM_WriteArray(0x100, out_buff, sizeof(out_buff)); //写数组数据到地址0X100
EEPROM_ReadArray(in_buff, 0x100, sizeof(in_buff));} //读数据从地址0X100 此处设断点观察值变化
}
/*******************************************************************************
铁电存储器写字节函数
参数:addr 目标地址
dat 要写数据
*******************************************************************************/
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;
}
/**********************************************************************
连续向铁电存储器写入多个字节
参数:
dest_addr 目标地址
src_addr 目标数据
len 数据长度
***********************************************************************/
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++);
}
}
/**************************************************************************
函数功能:从目标地址读数据
参数:addr 目标地址
***************************************************************************/
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;
}
/***************************************************************************
函数功能:从目标地址连续读出数据
参数: dest_addr 保存数据的数组
src_addr 目标地址
len 数据长度
****************************************************************************/
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);
}
/*******************************************************************************
函数功能:SMBUS初始化
*******************************************************************************/
void SMBus_Init (void)
{
SMB0CF = 0x5D;
SMB0CF |= 0x80;
}
/*******************************************************************************
函数功能:定时器3初始化
*******************************************************************************/
void Timer3_Init (void)
{
TMR3CN = 0x00;
TMR3 = -(SYSCLK/12/40);
TMR3RL = -(SYSCLK/12/40);
CKCON &= ~0x40;
TMR3 |= 0x04;
}
/*******************************************************************************
函数功能:定时器1初始化
*******************************************************************************/
void Timer1_Init (void)
{
CKCON &= ~0x0B;
TMOD = 0x20;
TH1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TL1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TR1 = 1;
}
/*******************************************************************************
函数功能:端口初始化
*******************************************************************************/
void Port_Init (void)
{ P0SKIP = 0xff;
P1SKIP =0x07;
XBR0 = 0x04;
XBR1 = 0x40;
P0MDIN = 0xFF;
P0MDOUT = 0x00;
P0 = 0xFF;
P1MDOUT = 0x00;
}
/*******************************************************************************
函数功能:SMBUS处理函数,这部分函数按照SMBUS通讯协议进行判断处理.具体请参见F340数
据手册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;
}
/*******************************************************************************
函数功能:25MS后对SMBUS重新初始化
*******************************************************************************/
void Timer3_ISR (void) interrupt 14
{
SMB0CN &= ~0x40;
SMB0CN |= 0x40;
TMR3CN &= ~0x80;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -