模拟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. C#系列之值类型和引用类型

    前言 这几天一直在思考这章讨论什么, 在上一章讨论string的时候牵涉到引用类型,那么我们这一章讨论讨论一下,值类型和引用类型. 值类型和引用类型,它们的区别来源于传值方式.有人会认为值类型就存在栈 ...

  2. bt 介绍以及 bt 种子的hash值(特征值)计算

    bt种子的hansh值计算,近期忽然对bt种子感兴趣了(原因勿问) 1. bt种子(概念) bt 是一个分布式文件分发协议,每一个文件下载者在下载的同一时候向其他下载者不断的上传已经下载的数据,这样保 ...

  3. 在Ubuntu 12.10 上安装部署Openstack

    OpenStack系统有几个关键的项目,它们能够独立地安装但是能够在你的云计算中共同工作.这些项目包括:OpenStack Compute,OpenStack Object Storage,OpenS ...

  4. mysql 存储过程项目小结

    1. false :0  true 1 切记 官方文档:http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html BOOL,  ...

  5. 如何进去bios设置

    1.BIOS是英文"Basic Input Output System"的缩略语,直译过来后中文名称就是"基本输入输出系统".其实,它是一组固化到计算机内主板上 ...

  6. 走进 Facebook POP 的世界

    POP: 一个流行的可扩展的动画引擎iOS,它支持spring和衰变动态动画,使其可用于构建现实,基于物理交互.Objective - C API允许快速集成, 对于所有的动画和过渡他是成熟的. 解释 ...

  7. Java编程陷阱-类成员初始化

    原文地址:http://blog.csdn.net/veryitman/article/details/6450523 如果你忽略Java的细节,恐怕你的代码会充满bug,下面讨论关于类成员初始化问题 ...

  8. 如何在单元测试中测试异步函数,block回调这种

    大概有四种方法: runloop 阻塞主进程等待结果 semphaore 阻塞主进程等待结果 使用XCTestExpectation 阻塞主线程等待(我用这个,xcode自带的,为啥不用) 使用第三方 ...

  9. html multiple select option 分组

    普通html方式展示<select name="viewType" style="width: 100%;height: 300px;" multiple ...

  10. clientX 属性.

    Syntax: event.clientX The clientX event attribute returns the horizontal coordinate (according to th ...