模拟I2C主机的比较多,但是从机相对主机而言要难很多,这个供大家借鉴。
这个从机程序支持主机对它的随机写和随机读,连续读和连续写没做,有兴趣的可以完善下,呵呵。

//Microcontrol CODE 

#include <msp430x22x4.h>
#define SDA BIT1
#define SCL BIT2 

#define SEG_A 0xA0 //0x0200---0x027F
#define SEG_B 0xB0 //0x0280---0x02FF
#define SEG_C 0xC0 //0x0300---0x037F 

//0x0380---0x0400
__no_init char wokao@0x243;
//=============================
char *send_ptr;
;
;
;
;
;
;
;
//*********************函数声明*************************************
void ACK(void); 

//****************************************************************
void main( void )
{
    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD; 

    //======================MCLK=16MHz=====================================
    DCOCTL = CALDCO_16MHZ;
    BCSCTL1 = CALBC1_16MHZ; //MCLK=DCO=16MHz
    P3DIR &= ~(SDA+SCL); 

    )
    {
        NN=;
        PreState = READ_SDA; 

        while(READ_SCL && NN--)
        {
            NowState = READ_SDA;
            if(PreState && !NowState)
            {
                START_flag = ;
                _DINT();
            }
            if(!PreState && NowState)
            {
                STOP_flag = ;
                _EINT();
            }

            PreState = NowState; 

            if(START_flag)
            {
                START_flag=;
                while(READ_SCL); //START时的SCL高电平状态就等待
                ;gg>;gg--) //接收器件地址
                {
                    while(!READ_SCL); //SCL低电平状态就等待 

                    DEVICE_ADR<<=;
                    if(READ_SDA) //数据的第一个CLK高电平来临
                    DEVICE_ADR |= 0x01; 

                    while(READ_SCL); //SCL高电平状态就等待
                }
                ACK(); //对设备地址ACK应答信
                //-----------以上收到了设备地址,并知晓主机要对从机进行读还是写操作--- 

                ;gg>;gg--) //接收内存单元地址
                {
                    while(!READ_SCL); 

                    WORD_ADR<<=;
                    if(READ_SDA)
                    WORD_ADR |= 0x01; 

                    while(READ_SCL);
                }
                //-----------以上就已经接收到内存单元地址------------
                ACK(); //对内存单元ACK应答信号 

                if(DEVICE_ADR & 0x01) //从机发数据给主机 R/W=1
                {
                    if(DEVICE_ADR==SEG_A+0x01)
                    {
                        send_ptr =(char*)(0x0200 + WORD_ADR);
                    }
                    else if(DEVICE_ADR==SEG_B+0x01)
                    {
                        send_ptr =(char*)(0x0280 + WORD_ADR);
                    }
                    else if(DEVICE_ADR==SEG_C+0x01)
                    {
                        send_ptr =(char*)(0x0300 + WORD_ADR);
                    } 

                    //--------以上是判断出为主机读从机,要把要读的地址单元赋给指针--- 

                    ;gg>;gg--)
                    {
                        while(!READ_SCL);
                        if( *send_ptr & 0x80)
                        _NOP();
                        else
                        {
                            P3DIR |= SDA; //输出0
                        }
                        while(READ_SCL); //SCL为1,就保持SDA输出不变
                        P3DIR &= ~SDA; //SCL为0,就把SDA从新切换到接收状态
                        *send_ptr <<=;
                    }
                    ACK(); //从机数据发送完毕,应答信号
                    _NOP();
                    //------------------以上是从机发数据给主机-----------------
                }
                else //主机写从机 R/W=0
                {
                    ;gg>;gg--) //接收主机要写到该器件内存单元的数据
                    {
                        while(!READ_SCL); 

                        REC_DATA <<=;
                        if(READ_SDA)
                        REC_DATA |= 0x01; 

                        while(READ_SCL);
                    }
                    if(DEVICE_ADR==SEG_A)
                    {
                        send_ptr =(char*)(0x0200 + WORD_ADR);
                        *send_ptr = REC_DATA;
                    }
                    else if(DEVICE_ADR==SEG_B)
                    {
                        send_ptr =(char*)(0x0280 + WORD_ADR);
                        *send_ptr = REC_DATA;
                    }
                    else if(DEVICE_ADR==SEG_C)
                    {
                        send_ptr =(char*)(0x0300 + WORD_ADR);
                        *send_ptr = REC_DATA;
                    }
                    ACK();
                    _NOP();
                    while(!READ_SCL);
                }
            }// if(START_flag) 

        }//while(NN--)
        _EINT();
        _NOP();
    }//while(1)
} 

//****************************************************
void ACK(void)
{
    // while(READ_SCL);
    while(!READ_SCL);
        P3DIR |= SDA; //第9个CLK变高的情况下,SDA输出0
    while(READ_SCL);
        P3DIR &= ~SDA; //第9个CLK变低的情况下,SDA输出1
}

模拟I2C从机的更多相关文章

  1. 模拟I2C从机程序

    ;Slave.asm SCL BIT P1. SDA BIT P1. ;---------------------------- ORG RESET: SETB SCL SETB SDA CALL I ...

  2. S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动

    目录:一. 说明 二. 驱动程序说明及问题 三. 案例一       四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...

  3. 关于模拟I2C的一些问题???

    1.在调试BH1750时发现stm32f103rb单片机用模拟I2C通讯时引脚使用开漏模式能正常读出来数据,使用推挽模式则完全无法通讯,发送地址后从机没有应答? https://blog.csdn.n ...

  4. STM32F10x_模拟I2C读写EEPROM

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

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

    功能: 实现MSP430口线模拟I2C总线协议与24C04通信.                                           ** 描述: 主系统工作时钟为12MHz,I2C工 ...

  6. STM8S 模拟I2C程序

    STM8S的硬件I2C还是存在问题,不敢贸然使用. 于是决定用模拟I2C. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM P ...

  7. C51单片机模拟I2C总线驱动程序设计

    /********************************** I2C总线驱动 ******************************** 模块名:I2C总线驱动 型号:I2C 功能描述 ...

  8. STM32F207 两路ADC连续转换及GPIO模拟I2C给MT9V024初始化参数

    1.为了更好的方便调试,串口必须要有的,主要打印一些信息,当前时钟.转换后的电压值和I2C读出的数据. 2.通过GPIO 模拟I2C对镁光的MT9V024进行参数初始化.之前用我以前公司SP0A19芯 ...

  9. STM32F10x_模拟I2C读写_硬件I2C读写

    STM32F10x_模拟I2C读写EEPROM STM32F10x_硬件I2C读写EEPROM(标准外设库版本) STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

随机推荐

  1. [Redux] Refactoring the Entry Point

    We will learn how to better separate the code in the entry point to prepare it for adding the router ...

  2. C# 二进制替换第一弹 byte 数组替换

    在做通讯相关的数据操作时常常须要用到 byte[]   byte 数组替换操作.比方协义转换相关的 如今提供了几种替换的方法 /// <summary> /// 二进制数据 操作 /// ...

  3. SQLLite 简介

    [1] SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内 ...

  4. img标签块状与内联的博弈

    新手,请前辈们不吝赐教 说到html中img标签是内联还是块状元素,我们首先要知道什么是内联(inline),什么又是块状(block)? 我也在网上查看了一些别人分享的经验,有一个讲到了文档流的概念 ...

  5. MSSQLSERVER未分离LDF删除情况下的MDF附加

    经过网上资料搜索,此方法可以解决. LDF日志不要轻易删除,恢复主数据要用到,如果删除,记得先分离,然后移动到另外的地方. 下面是针对未分离删除日志文件,MDF文件附加,提示找不到日志的问题的解决方法 ...

  6. MyEclipse起步Tomcat报错“A configuration error occurred during…” MyEclipse起步Tomcat报错“A configuration error occurred during…”

  7. Oracle主键自动生成_表and存储过程

    -- Create table create table T_EB_SYS_DN_SEQUENCE_CONFIG ( sequence_id VARCHAR2(36) default sys_guid ...

  8. 查找被锁对象的名称、sid,锁定的类型-1123

    select lk.sid,lk_obj.object_id,obj.object_name,DECODE(LK.LMODE,0,'None',1,'Null',2,'Row-S (SS)',3,'R ...

  9. oracle解析xml(增加对9i版本的支持)

    --方法1  SELECT * FROM  XMLTABLE('$B/DEAL_BASIC/USER_DEAL_INFO' PASSING     XMLTYPE('<?xml version= ...

  10. Python:if-while-for

    #!/usr/bin/python3 #if elif else print("开始猜数字游戏") num = int(input("请输入数字")) stan ...