📄 iic.c
字号:
#include <msp430x13x.h>
// p40=SDA
// p41=SCL
// p42=WP
// I2C_Write(550,0x55); //字节写
// I2C_Write(551,0xaa); //字节写
// a=I2C_Read(550); //字节读
// a=I2C_Read(551); //字节读
// for(i=0;i<32;i++) write_buff[i]=i;
// PageWrite(3200); //页写
// ReadSeq(3200); //页读
#define SCL BIT0
#define SDA BIT1
//定义函数
unsigned char write_buff[32];
void I2C_Initial(void);
void I2C_Set_sda_high(void);
void I2C_Set_sda_low (void);
void I2C_Set_sck_high(void);
void I2C_Set_sck_low (void);
int I2C_GetACK(void);
void I2C_SetACK(void);
void I2C_SetNAk(void);
void I2C_START(void);
void I2C_STOP(void);
void I2C_TxByte(int);
int I2C_RxByte(void);
void I2C_Write(int nAddr,char nValue);
int PageWrite(int nAddr);
char I2C_Read(int nAddr);
int ReadSeq(int nAddr);
void Delay_ms(unsigned long nValue);
void Delay_us(unsigned long nValue);
void I2C_Initial( void )
{
P2DIR |= 0X04;
P2OUT &= ~0x04;
// P2DIR |= SCL; //将SCL管脚(P2.3)设置为输出管脚
// P2DIR |= 0x04;
// P2OUT &= ~0x04; //chenren add
//P2OUT |=0x04; //chenren add
I2C_Set_sck_low();
I2C_STOP();
Delay_ms(10);
return;
}
void I2C_Set_sda_high( void )
{
P2DIR |= SDA; //将SDA设置为输出模式
P2OUT |= SDA; //SDA管脚输出为高电平
_NOP();
_NOP();
return;
}
void I2C_Set_sda_low ( void )
{
P2DIR |= SDA; //将SDA设置为输出模式
P2OUT &= ~(SDA); //SDA管脚输出为低电平
_NOP();
_NOP();
return;
}
void I2C_Set_sck_high( void )
{
P2DIR |= SCL; //将SCL设置为输出模式
P2OUT |= SCL; //SCL管脚输出为高电平
_NOP();
_NOP();
return;
}
void I2C_Set_sck_low ( void )
{
P2DIR |= SCL; //将SCL设置为输出模式
P2OUT &= ~(SCL); //SCL管脚输出为低电平
_NOP();
_NOP();
return;
}
int I2C_GetACK(void)
{
int nTemp = 0;
int j;
_NOP();
_NOP();
I2C_Set_sck_low();
for(j = 30;j > 0;j--);
P2DIR &= ~(SDA); //将SDA设置为输入方向
//I2C_Set_sda_high();
I2C_Set_sck_high();
for(j = 30;j > 0;j--);
nTemp = (int)(P2IN & SDA); //获得数据
I2C_Set_sck_low();
return (nTemp & SDA);
}
void I2C_SetACK(void)
{
I2C_Set_sck_low();
I2C_Set_sda_low();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_SetNAk(void)
{
I2C_Set_sck_low();
I2C_Set_sda_high();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_START(void)
{
int i;
I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
return;
}
void I2C_STOP(void)
{
int i;
I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
Delay_ms(10); //延迟一点时间
return;
}
void I2C_TxByte(int nValue)
{
int i;
int j;
for(i = 0;i < 8;i++)
{
if(nValue & 0x80)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j = 30;j > 0;j--);
I2C_Set_sck_high();
nValue <<= 1;
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}
return;
}
/////////////////////////////////////////////
// 接收是从 LSB 到 MSB 的顺序
int I2C_RxByte(void)
{
unsigned char nTemp = 0;
int i;
int j;
I2C_Set_sda_high();
P2DIR &= ~(SDA); //将SDA管脚设置为输入方向
_NOP();
_NOP();
_NOP();
_NOP();
for(i = 0;i < 8;i++)
{
I2C_Set_sck_high();
if(P2IN & SDA)
{
nTemp |= (0x01<< (7-i));
}
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}
return nTemp;
}
void I2C_Write(int nAddr,char nValue)
{ unsigned char a_h,a_l;
int nTemp = 0xA0;//写命令
a_h=(nAddr&0xff00)>>8;
a_l=(nAddr&0xff);
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
/*********chenren add ****************************************/
// 发送地址字节
I2C_TxByte(a_h);
// 等待 ACK
nTemp = I2C_GetACK();
/*************************************************/
// 发送地址字节
I2C_TxByte(a_l);
// 等待 ACK
nTemp = I2C_GetACK();
// 发送数据字节
I2C_TxByte(nValue);
// 等待 ACK
nTemp = I2C_GetACK();
// 停止总线
I2C_STOP();
return;
}
int PageWrite(int nAddr)
{
unsigned char a_h,a_l;
int i;
int nTemp = 0xA0;//写命令
a_h=(nAddr&0xff00)>>8;
a_l=(nAddr&0xff);
// 启动数据总线 write_buff
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送地址字节
I2C_TxByte(a_h);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送地址字节
I2C_TxByte(a_l);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送数据字节
for(i = 0; i < 32;i++)
{
I2C_TxByte(write_buff[i]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
}
// 停止总线
I2C_STOP();
return (nTemp & SDA);
}
char I2C_Read(int nAddr)
{
unsigned char a_h,a_l;
int nRes = -1;
//写命令
int nTemp = 0xA0;
a_h=(nAddr&0xff00)>>8;
a_l=(nAddr&0xff);
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
/*************************************************/
// 发送地址字节
I2C_TxByte(a_h);
// 等待 ACK
nTemp = I2C_GetACK();
/*************************************************/
// 发送地址字节
I2C_TxByte(a_l);
// 等待 ACK
nTemp = I2C_GetACK();
// 启动数据总线
I2C_START();
// 发送控制字节
nTemp = 0xA1;
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
//读取数据
nRes = I2C_RxByte();
// 停止总线
I2C_STOP();
//成功返回
return nRes;
}
int ReadSeq(int nAddr)
{
unsigned char a_h,a_l;
int i;
//写命令
int nTemp = 0xA0;
a_h=(nAddr&0xff00)>>8;
a_l=(nAddr&0xff);
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送地址字节
I2C_TxByte(a_h);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送地址字节
I2C_TxByte(a_l);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
// 发送地址字节
//I2C_TxByte(nAddr);
// 等待 ACK
//nTemp = I2C_GetACK();
//if(nTemp & BIT3) return 0;
// 启动数据总线
I2C_START();
// 发送控制字节
nTemp = 0xA1;
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
//读取数据
for(i = 0; i < 32; i++)
{
//读一个字节数据
write_buff[i] = I2C_RxByte();
//发送ACK
I2C_SetACK();
}
// 停止总线
I2C_STOP();
//成功返回
return 1;
}
void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
unsigned long nCount;
int i;
unsigned long j;
nCount = 2667;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
int nCount;
int i;
int j;
nCount = 3;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -