MSP430的IO口模拟I2C总线对AT24C25进行读写程序

时间:2023-01-09 20:14:40

功能: 实现MSP430口线模拟I2C总线协议与24C04通信.                                           *
* 描述: 主系统工作时钟为12MHz,I2C工作时钟频率为1MHz.给某地址写入一个数据     *
*         再读出来,如写入前和读出后的数据一致,则P1.0输出高电平,否则输出低电        *
*         平.                                                                                                                   *
*                                                  /|\    /|\                                                                     *
*               MSP430x22x4          10k   10k  ATMEL 24c04                                           *     
*                   master                     |      |       slave                                                       *
*             ---------------------------    |      |    ----------                                                      *
*           -|XIN     P3.1/UCB0SDA|<-|----+>|SDA      |                                                     *
*  32kHz |                                  |   |         |             |                                                     *
*           -|XOUT                         |    |        |             |                                                     *
*            |          P3.2/UCB0SCL|<-+-----> |SCL     |                                                      *
*            |                                  |             |             |                                                      *
*             --------------------------                ----------                                                       *
*                                                                                                                                 *
* 作者: Singel                                                                                                             *
* 时间: 2008年10月17日22时35分                                                                             *
*       此例在 IAR Embedded Workbench IDE for MSP430 v3.42a 调试通过 .            *
********************************************************************************************/

功能: 实现MSP430口线模拟I2C总线协议与24C04通信.                                           *
* 描述: 主系统工作时钟为12MHz,I2C工作时钟频率为1MHz.给某地址写入一个数据     *
*         再读出来,如写入前和读出后的数据一致,则P1.0输出高电平,否则输出低电        *
*         平.                                                                                                                   *
*                                                  /|\    /|\                                                                     *
*               MSP430x22x4          10k   10k  ATMEL 24c04                                           *
*                   master                     |      |       slave                                                       *
*             ---------------------------    |      |    ----------                                                      *
*           -|XIN     P3./UCB0SDA|<-|----+>|SDA      |                                                     *
*  32kHz |                                  |   |         |             |                                                     *
*           -|XOUT                         |    |        |             |                                                     *
*            |          P3./UCB0SCL|<-+-----> |SCL     |                                                      *
*            |                                  |             |             |                                                      *
*             --------------------------                ----------                                                       *
*                                                                                                                                 *
* 作者: Singel                                                                                                             *
* 时间: 2008年10月17日22时35分                                                                             *
*       此例在 IAR Embedded Workbench IDE for MSP430 v3.42a 调试通过 .            *
********************************************************************************************/
#include <MSP430x22x4.h>
#define  SlaveWriteAddress  0xa0
#define  SlaveReadAddress   0xa1
#define  OwnAddress         0xee
#define  I2CSDA             BIT1
#define  I2CSCL             BIT2
#define  I2CSDA_SET_1       P3OUT |=  I2CSDA
#define  I2CSDA_SET_0       P3OUT &=~ I2CSDA
#define  I2CSCL_SET_1       P3OUT |=  I2CSCL
#define  I2CSCL_SET_0       P3OUT &=~ I2CSCL
#define  I2CSDA_INPUT_IN    P3IN&I2CSDA
unsigned char READI2CBUF;

void delay5us( void )
{
    unsigned ;
    while(count--);
}     

void Delay_MS( unsigned int m )
{
    unsigned int i,j;
    ;i<m;i++)
        ;j<;j++);
} 

void Setting_System_Clock_For_On_Chip_RC( char Frequency )
{
    switch (Frequency)
    {
         :DCOCTL = BCSCTL1 = CALBC1_1MHZ;break;
         :DCOCTL = BCSCTL1 = CALBC1_8MHZ;break;
        :DCOCTL = BCSCTL1 = CALBC1_12MHZ;break;
        :DCOCTL = BCSCTL1 = CALBC1_16MHZ;break;
    }
} 

void I2C_Pins_DIR_Setting ( unsigned char SDADIR )
{
  P3DIR  |= I2CSDA + I2CSCL;
  )
    {
      P3DIR &=~ I2CSDA;
      P3OUT &=~ I2CSDA;
    }
}

void Engender_I2C_start_signal(void)
{
  I2CSCL_SET_1;  delay5us();
  I2CSDA_SET_1;  delay5us();
  I2CSDA_SET_0;  delay5us();
}       

void Engender_I2C_stop_signal(void)
{
  I2CSDA_SET_0;  delay5us();
  I2CSCL_SET_1;  delay5us();
  I2CSDA_SET_1;  delay5us();
}       

void Engender_I2C_ack_signal(void)
{
  I2CSCL_SET_0;  delay5us();
  I2CSCL_SET_1;  delay5us();
  I2CSCL_SET_0;  delay5us();
}          

void Engender_I2C_noack_signal(void)
{
    I2CSDA_SET_1;  delay5us();
    I2CSCL_SET_0;  delay5us();
    I2CSCL_SET_1;  delay5us();
    I2CSCL_SET_0;  delay5us();
}  

void WRITE_BYTE_TO_24C04( unsigned char BytEDAta )
{
    unsigned char count;
    ;count<;count++)
    {
        I2CSCL_SET_0;
        delay5us();
        if(BytEDAta&0x80)I2CSDA_SET_1;
        else             I2CSDA_SET_0;
        delay5us();
        I2CSCL_SET_1;
        delay5us();
        BytEDAta<<=;
    }
}          

unsigned char READ_BYTE_TO_24C04( void )
{
    unsigned ;
    I2CSCL_SET_0;
    ;count<;count++)
    {
        readbyte=readbyte<<;
        I2CSCL_SET_1;
        delay5us();
        if(I2CSDA_INPUT_IN)readbyte=readbyte|0x01;
        else               readbyte=readbyte&0xfe;
        delay5us();
        I2CSCL_SET_0;
        delay5us();
    }
    I2CSCL_SET_0;
    return readbyte;
}
void WRITE_DATA_TO_24C04( unsigned char Address,unsigned char Date )
{
    Setting_System_Clock_For_On_Chip_RC();
    I2C_Pins_DIR_Setting();
    Engender_I2C_start_signal();
    WRITE_BYTE_TO_24C04(SlaveWriteAddress);
    Engender_I2C_ack_signal();
    WRITE_BYTE_TO_24C04(Address);
    Engender_I2C_ack_signal();
    WRITE_BYTE_TO_24C04(Date);
    Engender_I2C_ack_signal();
    Engender_I2C_stop_signal();
    Delay_MS();
    I2CSCL_SET_0;
    I2CSDA_SET_0;
    Setting_System_Clock_For_On_Chip_RC();
}
unsigned char READ_DATA_FROM_24C04( unsigned char Address )
{
    unsigned char readdate;
    Setting_System_Clock_For_On_Chip_RC();
    I2C_Pins_DIR_Setting();
    Engender_I2C_start_signal();
    WRITE_BYTE_TO_24C04(SlaveWriteAddress);
    Engender_I2C_ack_signal();
    WRITE_BYTE_TO_24C04(Address);
    Engender_I2C_ack_signal();
    Delay_MS();
    Engender_I2C_start_signal();
    WRITE_BYTE_TO_24C04(SlaveReadAddress);
    I2C_Pins_DIR_Setting();
    Engender_I2C_ack_signal();
    readdate=READ_BYTE_TO_24C04();
    I2C_Pins_DIR_Setting();
    Engender_I2C_noack_signal();
    Engender_I2C_stop_signal();
    I2CSCL_SET_0;
    I2CSDA_SET_0;
    Setting_System_Clock_For_On_Chip_RC();
    return (readdate);
}

void main( void )
{
    unsigned char Data=0x59;
    WDTCTL  =  WDTPW+WDTHOLD;
    Setting_System_Clock_For_On_Chip_RC();
    P1DIR |= BIT0;
    )
    {
        WRITE_DATA_TO_24C04(0X00,Data);
        READI2CBUF=READ_DATA_FROM_24C04(0x00);
        if(Data == READI2CBUF)
        {
            P1OUT |=  BIT0;
        }
        else
        {
            P1OUT &=~ BIT0;
        }
        Delay_MS();
    }
}

通过微处理器I/O口模拟I2C总线对AT24C进行读写之前应注意一下两个问题:
一、微处理器的两个模拟I/O口在和SDA,SCL连接时必须使用上拉电阻。
一、I2C总线空闲的时候,两条信号线应该维持高电平。否则,上拉电阻上会有耗电。特别是在上电过程中,I/O线上电平也应保持在高电平状态。也就是说:当Master的I2C使用的是I/O软件模拟时,一定要保证该两个I/O上电默认均为输入(或高阻)或者输出高电平,切不可默认为输出低电平。I/O默认为输入时,可以通过外部上拉电阻将I2C信号线拉至高电平。
该程序通过调试,可以直接应用,程序如下:

/***********************************************************************************************
* 文 件 名 : AT24C256.S43.C
* 功能描述 : I/O模拟I2C时序读写AT24CXX(支持字节写、页写、字节读、顺序读)
* 作 者 : 梦回大唐
* 创建日期 : 2011-4-18
* 版 本 : Version1.0
*************************************************************************************************/
#include <msp430x16x.h>
#define SDA_IN            P5DIR &=~BIT0    // P5.0 IN
#define SDA_OUT           P5DIR |=BIT0     // P5.0 OUT
#define SDA_LOW           P5OUT &=~BIT0   // sda=0
#define SDA_HIGH          P5OUT |=BIT0   // sda=1
#define SCL_IN            P5DIR &=~BIT1    // P5.1 IN
#define SCL_OUT           P5DIR |=BIT1    // P5.1 OUT
#define SCL_LOW           P5OUT &=~BIT1
#define SCL_HIGH          P5OUT |=BIT1
#define W_EEPROM_LENGH    14

#define   TURE                1
#define   FALSE               0
#define   AckError            0x55
#define   OutOfRang           0xaa
#define   OutOfAddr           0xbb
unsigned ,,,,,,,,,,,,,};
unsigned char    x[W_EEPROM_LENGH];
void i2c_delay(unsigned char us);
void i2c_delay_ms(unsigned char ms);
void i2c_start();
void i2c_stop(void);
void i2c_SendAck(void);
void i2c_SendNoAck(void);
unsigned char i2c_check_ACK(void);
void i2c_SendByte(unsigned char data);
unsigned char i2c_RevByte(void);
unsigned char EEPROM_ByteWrite(unsigned int addr,unsigned char data);
unsigned char EEPROM_RandomRead(unsigned int addr);
unsigned char EEPROM_SequentialRead(unsigned int addr,unsigned int n,unsigned char* p);
unsigned int EEPROM_PageWrite(unsigned int page,unsigned char* p,unsigned char n);

void i2c_delay(unsigned char us)
{
    unsigned char tmp;
    while(us--)
    {
        ;tmp<;tmp++)
        {
            _NOP();
        }
    }
}

void i2c_delay_ms(unsigned char ms)
{
    unsigned int tmp;
    while(ms--)
    {
    ;tmp<;tmp++)
    {
        _NOP();
    }
    }
}

void i2c_start(void)
{
    SDA_OUT;
    i2c_delay();
    SDA_HIGH;
    i2c_delay();
    SCL_HIGH;
    i2c_delay();
    SDA_LOW;
    i2c_delay();
    SCL_LOW;
    i2c_delay();
}

void i2c_stop(void)
{
    SDA_OUT;
    SDA_LOW;
    i2c_delay();
    SCL_HIGH;
    i2c_delay();
    SDA_LOW;
    i2c_delay();
    SDA_HIGH;
}

void i2c_SendAck(void)
{
    SDA_OUT;
    SDA_LOW;
    i2c_delay();
    SCL_LOW;
    i2c_delay();
    SCL_HIGH;
    i2c_delay();
    SCL_LOW;
    SDA_HIGH;
}

void i2c_SendNoAck(void)
{
    SDA_OUT;
    SDA_HIGH;
    i2c_delay();
    SCL_LOW;
    i2c_delay();
    SCL_HIGH;
    i2c_delay();
    SCL_LOW;
}

unsigned char i2c_check_ACK(void)
{
    unsigned char AckStatus;
    SDA_IN;
    SCL_HIGH;
    i2c_delay();
    if(P5IN & 0x01)
    {
        AckStatus = FALSE;
    }
    else
    {
        AckStatus = TURE;
    }
    SCL_LOW;
    i2c_delay();
    SDA_OUT;
    return AckStatus;
}

void i2c_SendByte(unsigned char data)
{
    unsigned char tmp;
    SDA_OUT;
    ;tmp<;tmp++)
    {
        if(data & 0x80)
        {
            SDA_HIGH;
        }
        else
        {
            SDA_LOW;
        }
        i2c_delay();
        SCL_HIGH;
        i2c_delay();
        SCL_LOW;
        i2c_delay();
        data <<= ;
    }
    i2c_delay();
}

unsigned char i2c_RevByte(void)
{
    unsigned char tmp;
    unsigned ;
    SDA_IN;
    SCL_LOW;
    i2c_delay();
    ;tmp<;tmp++)
    {
        SCL_HIGH;
        i2c_delay();
        DATA <<= ;
        if(P5IN & 0x01)
        {
            DATA |= 0x01;
        }
        else
        {
            DATA &= 0xfe;
        }
        SCL_LOW;
    }
    SDA_OUT;
    return DATA;
}

unsigned char EEPROM_ByteWrite(unsigned int addr,unsigned char data)
{
    unsigned char Dev_addr; //设备地址
    unsigned char AddrLow;
    unsigned char AddrHigh;
    AddrLow = (unsigned char)addr;
    AddrHigh = (unsigned );
    Dev_addr = );
    i2c_start();
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(AddrHigh);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(AddrLow);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(data);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_stop();
    i2c_delay_ms();
    ;
}

unsigned char EEPROM_RandomRead(unsigned int addr)
{
    unsigned char Dev_addr; //设备地址
    unsigned char AddrLow;
    unsigned char AddrHigh;
    unsigned char tmp;
    AddrLow = (unsigned char)addr;
    AddrHigh = (unsigned );
    Dev_addr = );
    i2c_start();
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    i2c_SendByte(AddrHigh);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(AddrLow);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    i2c_start();
    Dev_addr = );
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    tmp = i2c_RevByte();
    i2c_SendNoAck();
    i2c_stop();
    i2c_delay();
    return tmp;
}

unsigned int EEPROM_PageWrite(unsigned int page,unsigned char* p,unsigned char n)
{
    unsigned char Dev_addr;
    unsigned char AddrLow;
    unsigned char AddrHigh;
    unsigned int tmp;
    )|(page > )) //根据读写的设备而变更为适合的页数和每页字节数
    {
        return OutOfRang;
    }
    tmp = ((unsigned ; //得出页首地址
    AddrLow = (unsigned char)tmp;
    AddrHigh = (unsigned );
    Dev_addr = );
    i2c_start();
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    i2c_SendByte(AddrHigh);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(AddrLow);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    while(n--)
    {
        i2c_SendByte(*p++);
        if(i2c_check_ACK() == FALSE)
        {
            return AckError;
        }
    }
    i2c_stop();
    i2c_delay_ms();
    ;
}

unsigned char EEPROM_SequentialRead(unsigned int addr,unsigned int n,unsigned char* p)
{
    unsigned char Dev_addr; //设备地址
    unsigned char AddrLow;
    unsigned char AddrHigh;
     - addr)) //检查预写入地址是否有效
    {
    return OutOfAddr;
    }
    AddrLow = (unsigned char)addr;
    AddrHigh = (unsigned );
    Dev_addr = );
    i2c_start();
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    i2c_SendByte(AddrHigh);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_SendByte(AddrLow);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    i2c_delay_ms();
    i2c_start();
    Dev_addr = );
    i2c_SendByte(Dev_addr);
    if(i2c_check_ACK() == FALSE)
    {
        return AckError;
    }
    while(n--)
    {
        *p = i2c_RevByte();
        p++;
        if(n)
        i2c_SendAck();
        else
        i2c_SendNoAck();
    }
    i2c_stop();
    ;
}

main()
{
    //unsigned char tt,tt1;
    WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
    DCOCTL = 0X73;
    BCSCTL1= 0X87; // 设置时钟频率4.00MHz
    P5DIR |=0X03;
    P5OUT |=0X03;
    //EEPROM_ByteWrite(0x0,12);
    //tt=EEPROM_RandomRead(0x0);
    //tt1=tt;
    EEPROM_PageWrite(,dat,);
    EEPROM_SequentialRead(,,x);
}

MSP430的IO口模拟I2C总线对AT24C25进行读写程序的更多相关文章

  1. C51 I2C接口驱动,IO口模拟I2C&lpar;主&plus;从&rpar;

    Master.asm ;/*------------------------------------------------------------------*/ ;/* --- STC MCU I ...

  2. 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)&lpar;转载&rpar;

     版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...

  3. stm32 普通IO口模拟串口通信

    普通IO口模拟串口通信 串口通信协议 串口传输 默认 波特率9600 1起始位 1停止位 其他0 数据位是8位(注意图上的给错了). 传输时,从起始位开始,从一个数据的低位(LSB)开始发送,如图从左 ...

  4. 模拟I2C协议学习点滴之原理框架

    I2C是一种串行总线协议. 目前几种常用的串行总线有UART.SPI和I2C协议.UART协议的总线只有两条,发送(Transmit:TX)和接收(Receive:RX),没有时钟信号,这就要求两位数 ...

  5. 51单片机GPIO口模拟串口通信

    51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于:   分类: 深入C语言(20) 作者同 ...

  6. STM32F10x&lowbar;模拟I2C读写EEPROM

    Ⅰ.写在前面 说到IIC,大家都应该不会陌生,我们初学单片机的时候或多或少都知道或了解过,甚至使用I2C控制过器件.但是,有多少人真正去深入理解,或者深入研究过I2C通信协议呢? 1.我们有必要学习I ...

  7. STM32F4XX中断方式通过IO模拟I2C总线Master模式

    STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...

  8. lpc1788IO口模拟IIC

    #ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...

  9. 单片机小白学步系列(二十) IO口原理

    IO口操作是单片机实践中最基本最重要的一个知识,本篇花了比較长的篇幅介绍IO口的原理. 也是查阅了不少资料,确保内容正确无误,花了非常长时间写的. IO口原理原本须要涉及非常多深入的知识,而这里尽最大 ...

随机推荐

  1. Windows Server 2008 R2 域控服务器运行nslookup命令默认服务器显示 UnKnown

    一.问题: 域控服务器DOS窗口运行nslookup命令提示如下: 二.原因分析: 主要原因在于域控服务器的DNS服务器没有设置反向查找区域,计算机名称是通过IP地址反向查找到域控服务器的计算机名称. ...

  2. JS刷新父窗口的几种方式

    浮层内嵌iframe及frame集合窗口,刷新父页面的多种方法   <script language=JavaScript>       parent.location.reload(); ...

  3. svn学习笔记(2)操作----还原,重命名,冲突处理,权限配置等

    1.查看某个文件的所有版本信息 2.版本还原,还原到之前的某一个版本 通过show log查看 查看某个文件的所有版本后,可以在这些版本之间*切换 3.文件改名 文件改名字给我们一个教训: 如:in ...

  4. apk文件分析原则

    如果在dex生成的jar文件里没有发现关键内容的话,就要注意jar里面的native函数以及loadlibrary操作,从而可以判断出加载了哪些so,调用了什么函数.就不会出现判断不出是不是加载了某s ...

  5. shadow dom 隔离代码 封装

    Shadow DOM是指浏览器的一种能力,它允许在文档(document)渲染时插入一棵DOM元素子树,但是这棵子树不在主DOM树中.   Shadow DOM 解决了 DOM 树的封装问题.     ...

  6. iOS ----------要学习的地方(链接整理)

    1.http://www.cocoachina.com/special/xcode/ 2.http://blog.csdn.net/a416863220/article/details/4111387 ...

  7. Welcom to Swift

    1.第一个程序 import Foundation println(“hello world”) 2.常用数据类型 int/UInt/Double/Float/Bool/String/Array/Di ...

  8. JDBC 和连接池

    1 JDBC概述 Java DataBase Connectivity,Java数据库连接,一种执行SQL的Java API,为多种关系数据库提供统一访问规范,由一组Java语言编写的类和接口组成.数 ...

  9. luogu P1052 过河

    传送门 容易想到设\(f_i\)表示走到坐标\(i\)的最少走过的石子数 但是这题数据范围很大,,, 不过一次可以走的步数范围是1-10,石子个数最多100个,所以中间会有很多多出来的没石子的路,可以 ...

  10. 20155302 Exp2 后门原理与实践

    20155302<网络对抗>后门原理与实践 实验要求 1.使用netcat获取主机操作Shell,cron启动 (0.5分) 2.使用socat获取主机操作Shell, 任务计划启动 (0 ...