I2C程序和流程图
更新时间:2024-04-20 04:58:01 阅读量: 综合文库 文档下载
- i2c读写流程图推荐度:
- 相关推荐
程序和流程图: IIC.h
void Init_IIC(void);
void EEPROM_ByteWrite(unsigned char nAddr,unsigned char nVal); unsigned char EEPROM_RandomRead(unsigned char nAddr); unsigned char EEPROM_CurrentAddressRead(void); void EEPROM_AckPolling(void); void Init_CLK(void); void Init_IIC_Port(void); Main.C
/*******************************************
IIC for AT24c16 OR AT24CXXX 系列
只要控制好IICRM IICSTP IICSTT 其硬件会自动完成
SCL SDA的一系列时序 只要注意各个发送与接收的控制标志位. ******************************************/ #include
volatile unsigned char Data[6]; void main(void) {
//volatile unsigned char Data[6];
//停止看门狗
WDTCTL = WDTPW+WDTHOLD; //初始化端口 Init_IIC_Port();
//初始化时钟 Init_CLK(); //I2C初始化
Init_IIC(); //置传输方式及控制方式
//打开中断 _EINT();
//写入数据
EEPROM_ByteWrite(0x0000,0x12); //等待写操作完成
EEPROM_AckPolling(); //写入数据
EEPROM_ByteWrite(0x0001,0x34); //等待写操作完成
EEPROM_AckPolling(); //写入数据
EEPROM_ByteWrite(0x0002,0x56); //等待写操作完成
EEPROM_AckPolling(); //写入数据
EEPROM_ByteWrite(0x0003,0x78); //等待写操作完成
EEPROM_AckPolling(); //写入数据
EEPROM_ByteWrite(0x0004,0x9A); //等待写操作完成
EEPROM_AckPolling(); //写入数据
EEPROM_ByteWrite(0x0005,0xBC); //等待写操作完成
EEPROM_AckPolling();
//读出数据,随机读
Data[0] = EEPROM_RandomRead(0x0000); //地址自动加1 //读出数据,当前地址读
Data[1] = EEPROM_CurrentAddressRead(); //读出数据,当前地址读
Data[2] = EEPROM_CurrentAddressRead(); //读出数据,当前地址读
Data[3] = EEPROM_CurrentAddressRead(); //读出数据,当前地址读
Data[4] = EEPROM_CurrentAddressRead(); //读出数据,当前地址读
Data[5] = EEPROM_CurrentAddressRead(); }
IIC.C
#include
#define SLAVEADDR 0x50; int tx_count; int rx_count;
unsigned char I2CBuffer[3]; void Init_IIC(void) {
//将P3.1和P3.3设置为I2C管脚 P3SEL = 0x0A;
//设置P3.1和P3.3管脚的方向 P3DIR &= ~0x0A; //选择为I2C模式
U0CTL |= I2C + SYNC; //禁止I2C模块
U0CTL &= ~I2CEN;
//设置I2C为7位地址模式,不使用DMA, //字节模式,时钟源为SMCLK, //设置成传输模式
I2CTCTL = I2CTRX + I2CSSEL_2; //定义从器件地址
I2CSA = SLAVEADDR; //设置本身的地址
I2COA = 0x01A5;
//I2C时钟为SMCLK / 160 I2CPSC = 159;
//SCL 高电平为:5 *I2C 时钟 I2CSCLH = 0x03;
//SCL 低电平为:5 *I2C 时钟 I2CSCLL = 0x03; //I2C 模块有效 U0CTL |= I2CEN; tx_count = 0; rx_count = 0; }
void I2CWriteInit(void) //对于AT24CXXX的写操作是置成主模式并置位中断使能. {
//主(Master)模式 U0CTL |= MST;
//传输模式,R/W 为:0 I2CTCTL |= I2CTRX; //清除中断标志
I2CIFG &= ~TXRDYIFG; //发送中断使能
I2CIE = TXRDYIE; }
void I2CReadInit(void) {
//接收模式,R/W 为:1 I2CTCTL &= ~I2CTRX; //接收中断使能
I2CIE = RXRDYIE; }
void EEPROM_ByteWrite(unsigned char nAddr, unsigned char nVal) {
//等待I2C模块完成所有操作 //在选定的地址写入数据. while (I2CDCTL&I2CBUSY) ; //设置地址数据
I2CBuffer[1] = nAddr; //设置数据
I2CBuffer[0] = nVal; //设置缓冲区指针 tx_count = 1; //写数据初始化
I2CWriteInit(); //设置为主模式 //发送数据的长度
//1个控制字节,2个数据字节
I2CNDAT = 2; //开始和停止条件产生 //开始I2C通信
I2CTCTL |= I2CSTT+I2CSTP; return; }
unsigned char EEPROM_CurrentAddressRead(void)
{
//等待I2C模块完成所有操作 while (I2CDCTL&I2CBUSY); //读操作的初始化 I2CReadInit(); //主(Master)模式 U0CTL |= MST;
//接收1个字节的数据 I2CNDAT = 1; //清除中断标志
I2CIFG &= ~ARDYIFG;
//开始接收,产生重新起始和停止条件 I2CTCTL |= I2CSTT + I2CSTP; //等待传输完成
while ((~I2CIFG)&ARDYIFG) ; //返回数据
return I2CBuffer[0]; }
unsigned char EEPROM_RandomRead(unsigned char nAddr) {
//等待I2C模块完成所有操作 while (I2CDCTL&I2CBUSY); //设置地址
I2CBuffer[0] = nAddr; //设置缓冲区指针 tx_count = 0; //写操作初始化 I2CWriteInit(); //传输数据长度
//1个控制字节和一个地址数据 I2CNDAT = 1; //清除中断标志
I2CIFG &= ~ARDYIFG; //起始条件产生
I2CTCTL |= I2CSTT; //等待传输完成
while ((~I2CIFG)&ARDYIFG); //读操作初始化 I2CReadInit();
//接收一个字节的数据 I2CNDAT = 1; //清除中断标志
I2CIFG &= ~ARDYIFG;
//开始接收,产生重新起始和停止条件 I2CTCTL |= I2CSTT + I2CSTP; //等待传输完成
while ((~I2CIFG)&ARDYIFG); //返回数据
return I2CBuffer[0]; }
void EEPROM_AckPolling(void) {
unsigned int count;
//等待I2C模块完成所有操作 while (I2CDCTL&I2CBUSY);
count=0;
//清除I2CEN位
U0CTL &= ~I2CEN; I2CTCTL |= I2CRM; //使能I2C模块 U0CTL |= I2CEN; //设置NACKIFG标志 I2CIFG = NACKIFG;
while (NACKIFG & I2CIFG) {
//清除中断标志 I2CIFG=0x00; //主(Master)模式 U0CTL |= MST; //设置传输模式
I2CTCTL |= I2CTRX; //产生起始条件
I2CTCTL |= I2CSTT;
//等待I2CSTT被清除
while (I2CTCTL & I2CSTT) ; //产生停止条件
I2CTCTL |= I2CSTP; //等待停止条件复位
while (I2CDCTL & I2CBUSY) ; count = count + 1; }
//清除I2CEN位 U0CTL &= ~I2CEN; I2CTCTL &= ~I2CRM; //使能I2C
U0CTL |= I2CEN;
return; }
#if __VER__ < 200
interrupt [USART0TX_VECTOR] void ISR_I2C(void) #else
#pragma vector=USART0TX_VECTOR __interrupt void ISR_I2C(void)
#endif //上面的程序其实只要编写 :
//#pragma vector=USART0TX_VECTOR {
__interrupt void ISR_I2C(void)就行.
switch (I2CIV) {
case I2CIV_AL: {
//仲裁中断 break; }
case I2CIV_NACK: {
//NACK中断 break; }
case I2CIV_OA: {
//自己地址中断 break; }
case I2CIV_ARDY: {
//访问准备好中断 break; }
case I2CIV_RXRDY: {
//接收准备好中断
I2CBuffer[0]=I2CDRB; break; }
case I2CIV_TXRDY: {
//发送准备好中断
I2CDRB = I2CBuffer[tx_count]; tx_count = tx_count - 1; if (tx_count < 0) {
//禁止发送中断
I2CIE &= ~TXRDYIE; }
break;
} case I2CIV_GC: {
//一般调用中断 break; }
case I2CIV_STT: {
//起始条件中断 break; }
} }
void Init_IIC_Port(void) {
//初始化端口寄存器 与IIC口无关的PX口关闭以便于对编写系统板的综合程序. //P1DIR = 0xFF; //P2DIR = 0xFF; P3DIR = 0xF5; //P4DIR = 0xFF; P5DIR = 0x7F; //P6DIR = 0xFF; //P4OUT = 0X11; //P5OUT &= 0XF0;
P3SEL|=BIT1+BIT3; //在这里如果设置成 }
void Init_CLK(void) {
unsigned int i;
//将寄存器的内容清零 //XT2震荡器开启
//LFTX1工作在低频模式 //ACLK的分频因子为1 BCSCTL1 = 0X00; do
{// 清除OSCFault标志
IFG1 &= ~OFIFG; for (i = 0x20; i > 0; i--); }
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1 //open XT2, LFTX2 选择低频率
BCSCTL1 &= ~(XT2OFF + XTS); //BCSCTL1=0X00 功能一样 //DCO Rsel=7(Freq=3200k/25摄氏度) BCSCTL1 |= RSEL0 + RSEL1 + RSEL2; BCSCTL1 |= 0x07;
//MCLK的时钟源为TX2CLK,分频因子为1 BCSCTL2 += SELM1;
//SMCLK的时钟源为TX2CLK,分频因子为1 BCSCTL2 += SELS; }
//对于系统时钟的选择关系到整个程序运行稳定性.
/************************************************************ *文件名:msp430f169i2c.c
*整体描述:MSP430F169单片机硬件IIC软件,字节方式,主方式 * IIC接口:P3.3=SCL,P3.1=SDA;(开漏输出)
* 相应寄存器:地址寄存器 I2COA 用于存放自身从地址(从方式时才有用) * 地址寄存器 I2CSA 用于存放外围的从机地址(主方式时才有用) * 控制寄存器 U0CTL 硬件I2C的设置、使能、模式等。 发送控制寄存器 I2CTCTL
* 数据控制寄存器 I2CDCTL 指示I2C总线的状态 *
* U0CTL -- RXDMAEN,TXDMAEN,I2C, XA, LISREN,SYNC,MST,I2CEN * 0 0 1 0 0 1 1 1 (0x17)
* I2CTCTL --I2CWORD,I2CRM,I2CSSEL1,I2XSSEL0, I2CTRX,I2CSTB, I2CSTP, I2CSTT * 0 1 1 0 * 0 * * *作者: jy *状态: 通过
************************************************************/ #include
#define WR24C512
#define LED1_1 (0x20) /* Port 3.5 Output -> LED1 */ #define LED1_0 (0xdf)
#define SDA_1 P3OUT |= BIT1 //串行数据线,SDA = 1 #define SDA_0 P3OUT &=~ BIT1 //SDA = 0
#define SCL_1 P3OUT |= BIT3 //串行时钟线,SCL = 1 #define SCL_0 P3OUT &=~ BIT3 //SCL = 0
#define SDADIR_IN P3DIR &=~ BIT1 //SDA,I/O口为输入 #define SDADIR_OUT P3DIR |= BIT1 //I/0口为输出 #define SDA_IN ((P3IN >> 1) & 0x01) //Read SDA
#define SCLDIR_IN P3DIR &=~ BIT3 //SCL,I/O口为输入 #define SCLDIR_OUT P3DIR |= BIT3 //I/0口为输出 #define SCL_IN ((P3IN >> 3) & 0x01) //Read SCL
#ifdef WR24C512
static int numi = 0; //Data Pointer #else
static int numj = 0; //Data Pointer #endif
#define I2CSLA 0x50
/*-------------------------------------------------------- --功能描述: 检查总线是否空闲 --子程序状况: 09-23调试通过
---------------------------------------------------------- --*/
void I2c_Idle_Check(void) {
while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 }
void DelayTime10us(unsigned char n) {
unsigned char i;
while(n--) // 5 cycles
for(i=0;i<10;i++); // 8mhz 110:771 + 4 to while }
/*--------------------------------------------------------- --功能描述:发送数据:用于向总线发送数据 --子程序状况: 09-23调试通过
----------------------------------------------------------- --*/
void I2cBusSendByte(unsigned char c) {
while((I2CIFG & TXRDYIFG) != TXRDYIFG); // 检测发送准备 I2CDRB = c; // 写发送寄存器 }
/*------------------ MSP430 I2C 写数据 09-23调试通过---------------------*/ /*--------------------------------------------------------
--功能描述:申请总线:进行I2C总线的初始化-发送起始信号 --子程序状况: 09-23调试通过
---------------------------------------------------------- --*/
void I2C_Send(unsigned char ndatNum) {
// 注意:通讯结束,I2CMST 自动清零,再次通讯必须重新置位 P3OUT = 0x00; // clear P3 output register
P3SEL = 0x0A; // P3.1=SDA, P3.3=SCL,Select I2C pins, Setup I2C module U0CTL |= (I2C + SYNC); // select I2C mode;XA=0,7bit_addresing; U0CTL &= ~I2CEN; // i2c功能使能无效
// I2CTCTL = I2CRM + I2CSSEL_2; // x(x>256)字节模式 ,new start测试使用
// 选择方式 I2CRM=0,最终用户使用 I2CTCTL = I2CSSEL_2;
I2CNDAT = 2 + ndatNum; // 最终用户使用,2byte地址 + 128byte数据
I2CPSC = 2; // set scl I2CIFG = 0;
I2CSA = 0x50; // Slave address of At24c512
U0CTL |= I2CEN; // enable I2C module, 7 bit addr, master mode 08-26 U0CTL |= MST;
while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 I2CTCTL |= I2CTRX + I2CSTT + I2CSTP ; // I2CRM =0,启动总线,发送从器件地址
while((I2CIFG & NACKIFG) == 0x02); // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1 }
/*----------------------------------------------------------------
--子程标号 :I2cWrSlaSubAddr --子程功能 :主机发送从机的子地址
--入口参数 :unsigned char sla,unsigned int suba
--参数说明 :子地址
--子程序状况 :09-23调试通过
--说明 :完成地址信息的定位,先确定顺序读写的起始地址 ----------------------------------------------------------------- --*/
unsigned char I2cSendSubAddr(unsigned int suba,unsigned char ndatNum) {
unsigned char Hi_suba,Lo_suba;
I2C_Send(ndatNum); // 启动总线,等待地址应答位
Hi_suba = ( unsigned char )( suba >> 8 );
Lo_suba = ( unsigned char )( suba & 0x00ff );
I2cBusSendByte( Hi_suba ); //发送器件子地址 while((I2CIFG & 0x02) == NACKIFG ) // 等待数据的应答 {
I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); }
I2cBusSendByte( Lo_suba ); //发送器件子地址 while((I2CIFG & 0x02 )==0x02 ) // 等待数据的应答 {
I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); }
return(1); }
/*------------------------------------------------------------------
--子程标号 :I2cWriteStr (用户函数) --子程功能 :向I2C从器件写入数据
--入口参数 :unsigned char *ps,unsigned char num --参数说明 :写入数据的地址指针,数据个数 --子程序状况 : 09-23调试通过 --说明 :I2C读取数据 ------------------------------------------------------------------- --*/
unsigned char I2cSendStr(const unsigned char * ps,unsigned char num) {
// unsigned char i;
unsigned char tempnum; tempnum = num-1;
for(numi=0;numi I2cBusSendByte(*ps); while((I2CIFG & 0x02) == NACKIFG) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } ps++; } // I2CTCTL |= I2CSTP; //I2CRM =1模式中,在发送最后一个数据之前将停止位置位,*特别注意,必须 I2cBusSendByte(*ps); while((I2CIFG & 0x02) == NACKIFG) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } return(1); } //------------------写at24c512---- void I2cWrAt24c512(void) { unsigned int j=0; unsigned char m,n; unsigned int tempAddr; for (j = 0;j <462;j++) // page write { tempAddr = 128*j; while (I2CBUSY & I2CDCTL); // I2C ready? I2cSendSubAddr(tempAddr,0x80); I2cSendStr(FPGACfg+tempAddr,0x80); P4OUT ^= 0x80; for (m=0;m<125;m++) {for (n=0;n<110;n++);} P4OUT ^= 0x80; } tempAddr = 128*j; while (I2CBUSY & I2CDCTL); // I2C ready? I2cSendSubAddr(tempAddr,0x4f); I2cSendStr(FPGACfg+tempAddr,0x4f); P4OUT ^= 0x80; for (m=0;m<125;m++) {for (n=0;n<110;n++);} P4OUT ^= 0x80; } /*-------------------------- MSP430 I2C 读取数据-----------------------------*/ /*--------------------------------------------------------------------- --子程标号 :I2cSlaSubAddr --子程功能 :主器件发送从机器件地址和子地址 --入口参数 :unsigned int suba --参数说明 :子地址 --子程调用 :I2cBusSendByte --子程序状况 :Y --说明 :完成地址信息的定位,先确定顺序读写的起始地址 --------------------------------------------------------------------- --*/ void I2cReceSubAddr(unsigned int suba) // test 09-25 读之前先写地址 { unsigned char Hi_suba,Lo_suba; P3OUT = 0x00; // clear P3 output register P3SEL = 0x0A; // P3.1=SDA, P3.3=SCL,Select I2C pins, Setup I2C module U0CTL |= I2C + SYNC; // select I2C mode;XA=0,7bit_addresing; U0CTL &= ~I2CEN; // i2c功能使能无效 // I2CTCTL = I2CRM + I2CSSEL_2; // I2CRM = 1,自己设定字节个数 I2CTCTL = I2CSSEL_2; // I2CRM = 0, I2CNDAT = 2; // I2CRM = 0,2byte地址 + 128byte数据,固定字节 I2CIFG = 0; I2CPSC = 1; // set scl // I2CSCLH = 0x02; // High period of SCL // I2CSCLL = 0x02; // Low period of SCL I2CSA = 0x50; // Slave address of At24c512 U0CTL |= I2CEN; // enable I2C module, 7 bit addr, master mode 08-26 U0CTL |= MST; Hi_suba = ( unsigned char )( suba >> 8 ); Lo_suba = ( unsigned char )( suba & 0x00ff ); while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 I2CTCTL |= I2CTRX + I2CSTT + I2CSTP ; // I2CRM =0,启动总线,发送从器件地址 while((I2CIFG & NACKIFG) == 0x02) // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1 { I2CTCTL |= I2CSTP; // 结束总线 } I2cBusSendByte( Hi_suba ); //发送器件子地址 while((I2CIFG & NACKIFG) == 0x02) // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1 { I2CTCTL |= I2CSTP; // 结束总线 } I2cBusSendByte( Lo_suba ); //发送器件子地址 while((I2CIFG & NACKIFG) == 0x02) // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1 { I2CTCTL |= I2CSTP; // 结束总线 } DelayTime10us(250); DelayTime10us(250); DelayTime10us(250); DelayTime10us(250); } /*--------------------------------------------------------------------- --子程标号 :I2cSlaSubAddr --子程功能 :主器件接收初始化 --入口参数 :无 --子程序状况 : --说明 : --------------------------------------------------------------------- --*/ void InitI2cRece(unsigned char num) { P3OUT = 0x00; // clear P3 output register P3SEL = 0x0A; // P3.1=SDA, P3.3=SCL,Select I2C pins, Setup I2C module U0CTL |= I2C + SYNC; // select I2C mode;XA=0,7bit_addresing; U0CTL &= ~I2CEN; // i2c功能使能无效 // I2CTCTL = I2CRM + I2CSSEL_2; // I2CRM=1 x(x>256)字节模式 I2CTCTL = I2CSSEL_2; // I2CRM=0 I2CNDAT = num; // 1个字节 I2CPSC = 1; // set scl // I2CSCLH = 0x01; // High period of SCL // I2CSCLL = 0x01; // Low period of SCL I2CIFG = 0; I2CSA = 0x50; // Slave address of At24c512 I2CTCTL &= ~I2CTRX; U0CTL |= I2CEN; // enable I2C module, 7 bit addr, master mode 08-26 } /*--------------------------------------------------------------- --功能描述 : 读一个字节 --子程序状况 : ------------------------------------------------------------------ --*/ unsigned char I2cReceSlaByte(void) { unsigned char ch; DelayTime10us(15); U0CTL |= MST; //主模式 while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 I2CTCTL |= I2CSTT + I2CSTP; // I2CRM =0; Receive, ST, SP (clears MST) while((I2CIFG & RXRDYIFG) != RXRDYIFG); // 等待地址应答位 ,判断 ch = I2CDRB; return(ch); } /*--------------------------------------------------------------- --功能描述 : 连续读数据 --子程序状况 : ------------------------------------------------------------------ --*/ void I2cReceSlaStr(unsigned char num) { unsigned char i; DelayTime10us(15); U0CTL |= MST; //主模式 while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 I2CTCTL |= I2CSTT + I2CSTP; // I2CRM =0; Receive, ST, SP (clears MST) for (i=0;i while((I2CIFG & RXRDYIFG) != RXRDYIFG); // 等待地址应答位 ,判断 rxDataArray = I2CDRB; } }
正在阅读:
I2C程序和流程图04-20
梦幻深处作文300字06-22
干部职工日常管理考核办法模板02-23
北师大版小学四年级下册第二单元第六课时《四边形分类》12-07
关于组织文化对员工效率影响的实验设计05-26
路街道人大终工作总结10-20
实验四 茶叶中咖啡碱含量的测定(3学时)05-18
百善孝为先作文800字07-15
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 流程图
- 程序
- I2C
- 接触网作业车学习司机应知应会部分资料 - 图文
- 结直肠癌诊疗指南及规范
- 检验批、分项、分部、单位工程质量检查、申报和签认制度
- 北语17秋《Java语言程序设计》作业4
- 综合办公室作业指导书(培训) - 图文
- 幕墙知识测试题(有答案)
- 剑桥少儿英语二级下册单元测试
- 自由基聚合的速率和聚合度的影响因素
- 人教版初中语文中考十大考点复习材料
- 美化班级课程表 - 教学设计
- 新课标人教版小学数学五年级上册《用字母表示数》教学设计
- 简易升降机检验细则 - 图文
- 消防大队“为何从警、如何做警、为谁用警”主题征文
- 金融练习题集
- 有关情绪的英文表达
- 恩格尔注塑机操作说明书 - 图文
- 高效HIT异质结太阳能电池相关资料介绍
- 宏观经济学答案
- 进口棉基础知识
- 小学综合实践说课稿