模拟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. Mysql重要配置参数的整理2

    http://ssydxa219.iteye.com/category/209848 下面开始优化下my.conf文件(这里的优化只是在mysql本身的优化,之前安装的时候也要有优化) cat /et ...

  2. 多路复用的server模型

    多路复用I/O之server模型  主要是关于select()这个函数: 其原型是:int select(int n,fd_set *read_fds,fd_set *write_fds,fd_set ...

  3. Note | Javascript权威指南[第六版] 第1章:Javascript概述

       JavaScript是一门高端的.动态的.弱类型的编程语言,非常适合面向对象和函数式的编程风格.JavaScript的语法源自Java,它的一等函数(first-class function)来 ...

  4. Call Directory Extension 初探

    推荐序 本文介绍了 iOS 10 中的 Call Directory Extension 特性,并且最终 Demo 出一个来电黑名单的 App. 作者:余龙泽,哈工大软件工程大四学生,之前在美图公司实 ...

  5. iOS 手机淘宝加入购物车动画分析

    1.最终效果 仿淘宝动画 2.核心代码 _cartAnimView=[[UIImageView alloc] initWithFrame:CGRectMake(_propView.frame.size ...

  6. Springmvc中@RequestParam传值中文乱码解决方案(转)

    @RequestMapping(value={"/list"},method=RequestMethod.GET) @ResponseBody public DeviceList ...

  7. Java-Android 之输入提示框

    Android的文本提示框有两种方式: main.xml文件 <?xml version="1.0" encoding="utf-8"?> < ...

  8. Android开发手记(32) 使用摄像头拍照

    在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面. 我们要添加如下权限: <uses-permission android:na ...

  9. oracle命令的缩写原型单词方便记忆总结

    $ORACLE_HOME/bin下的utilities解释 Binary              First Available        Description adapters        ...

  10. 使用charles proxy for Mac来抓取手机App的网络包

    之前做Web项目的时候,经常会使用Fiddler(Windows下).Charles Proxy(Mac下)来抓包,调试一些东西:现在搞Android App开发,有时候也需要分析手机App的网络请求 ...