模拟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. 两层Fragment嵌套,外层Fragment切换时内层Fragment不显示内容

    尊重他人劳动成果,转载请说明出处:http://blog.csdn.net/bingospunky/article/details/46847269 需求 在搭界面有这么样一个需求:须要两层的Frag ...

  2. android 50 进程优先级

    程序在磁盘叫程序,程序加载到内存运行起来叫进程,优先级5个级别,内存不足的时候会杀掉低级别进程. Active Process:最上面用户可以操作的. Visible Process:可见进程,部分可 ...

  3. Qt 学习之路:线程和 QObject

    前面两个章节我们从事件循环和线程类库两个角度阐述有关线程的问题.本章我们将深入线程间得交互,探讨线程和QObject之间的关系.在某种程度上,这才是多线程编程真正需要注意的问题. 现在我们已经讨论过事 ...

  4. 覆盖equals的时候总要覆盖hashCode

    import java.util.HashMap; public class Student { private String name ; private String id; public Stu ...

  5. GRADLE 构建最佳实践

    随着谷歌对Eclipse的无情抛弃和对Android Studio的日趋完善,使用gradle构建Android项目已经成为开发者的一项必会良技.那么,问题来了,采用什么样的姿势才能让项目开发构建过程 ...

  6. android开发之调试技巧 分类: android 学习笔记 2015-07-18 21:30 140人阅读 评论(0) 收藏

    我们都知道,android的调试打了断点之后运行时要使用debug as->android application 但是这样的运行效率非常低,那么我们有没有快速的方法呢? 当然有. 我们打完断点 ...

  7. 实践过配置成功的VNC安装配置

    VNC安装步骤说明那个 1.安装图形界面    #yum install tigervnc-server tigervnc  2.启动VNCServer #vncserver 对应的关闭图形界面的命令 ...

  8. 关于黑名单IP的设置

    最近在做一个项目的时候,需要做一个自动的黑名单设置,也就是将一天内重复出错的超过一定次数的手机号,和IP给加入黑名单里面,下次请求的时候先判断是否在黑名单里. 这个是获取IP地址的方法 private ...

  9. 快速打出System.out.println("");

    sysout---->Alt+/--->System.out.println():

  10. listview的动态加载数据问题

    1:调用adapter.notifyDataSetChanged()却不起作用 原因可能有一下几点 1.数据源没有更新,调用notifyDataSetChanged无效. 2.数据源更新了,但是它指向 ...