听说STM32的IIC硬件做的很鸡肋,所以在这里通过模拟的方式实现IIC协议。此程序能成功对AT24C02操作。

程序中的带参数宏 IIC_DELAY(time)的功能是延时time us,在实际中具体场合具体分析。

宏定义文件--IIC.h

#ifndef _IIC_
#define _IIC_ #include "SysTick.h"
#include "stm32f10x.h"
#include "SystemConfig.h" /* 配置IIC的SDA、SCL两个端口 */
#define IIC_SCL_IO GPIO_Pin_6
#define IIC_SDA_IO GPIO_Pin_7 /* SDA端口动态改变输入输出状态定义 */
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X80000000;} //配置上拉输入
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;} //配置推挽输出 /* IIC 操作定义 */
#define IIC_SDA PBOUT(7)  //定义的STM32位操作
#define READ_SDA PBIN(7)
#define IIC_SCL PBOUT(6)
#define IIC_DELAY(time) delay(time) /* 定义的函数原型 */
void IIC_IOInit(void);
void IIC_Start(void);
void IIC_Stop(void);
unsigned char IIC_Wait_Ack(void);
void IIC_NoAck(void);
void IIC_Ack(void);
void IIC_Send_Byte(unsigned char txd);
unsigned char IIC_Read_Byte(unsigned char ack); #endif

程序源文件IIC.c文件

#include "IIC.h"
/*********************************************************************
** STM32模拟IIC通信
** 文件编码: GBK2312
**********************************************************************/ /*****************************
** 初始化IIC的IO口
**
******************************/
void IIC_IOInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE ); //使能IO口时钟 GPIO_InitStructure.GPIO_Pin = IIC_SCL_IO | IIC_SDA_IO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,IIC_SCL_IO | IIC_SDA_IO); //置位SDA,SCL
} /*****************************
** 起始信号
**
******************************/
void IIC_Start(void)
{
SDA_OUT(); //sda 线输出
IIC_SDA=1;
IIC_SCL=1;
IIC_DELAY(4); IIC_SDA=0;//当时钟线为高时,SDA拉低则起始信号才有效
IIC_DELAY(4); IIC_SCL=0;//钳住 I2C 总线,准备发送或接收数据
} /*****************************
** 停止信号
**
******************************/
void IIC_Stop(void)
{
SDA_OUT();//sda 线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
IIC_DELAY(4); IIC_SCL=1;
IIC_DELAY(1);
IIC_SDA=1;//发送 I2C 总线结束信号
IIC_DELAY(4);
} /*****************************
** 等待应答信号
** 返回值: 1-接收应答失败, 0-为接收成功
******************************/
unsigned char IIC_Wait_Ack(void)
{
unsigned char ucErrTime=0;
SDA_IN(); //SDA 设置为输入
IIC_SDA=1;IIC_DELAY(1);
IIC_SCL=1;IIC_DELAY(1); while(READ_SDA) //判断SDA上是否有低电平发生
{
ucErrTime++;
if(ucErrTime>250) //如果在一段时间内没有接收到应答信号,则发送停止信号
{
IIC_Stop();
return 1;
}
} IIC_SCL=0;//时钟输出 0
return 0;
} /*****************************
** 产生应答信号
**
******************************/
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
IIC_DELAY(2); //数据改变有效 IIC_SCL=1;
IIC_DELAY(2);
IIC_SCL=0;
} /*****************************
** 不产生应答信号
**
******************************/
void IIC_NoAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
IIC_DELAY(2); IIC_SCL=1;
IIC_DELAY(2);
IIC_SCL=0;
} /*****************************
** 发送一个字节的数据
**
******************************/
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t;
SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输,时SDA上的数据改变有效
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
IIC_DELAY(2); //对 TEA5767 这三个延时都是必须的 IIC_SCL=1;
IIC_DELAY(2); //保持数据一段时间 IIC_SCL=0;
IIC_DELAY(2);
}
} /*****************************
** 读一个字节的数据
** 形式参数:ack=1,发送ACK, ack=0,发送NACK
******************************/
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA 设置为输入 for(i=0;i<8;i++ )
{
IIC_SCL=0;
IIC_DELAY(2);
IIC_SCL=1;
receive<<=1; if(READ_SDA)receive++;
IIC_DELAY(1);
}
if (!ack)
IIC_NoAck();//发送 nACK
else
IIC_Ack(); //发送 ACK return receive;
}

STM32F10X -- 模拟IIC程序的更多相关文章

  1. stm32软件模拟IIC读取PX4FLOW光流传感器数据

    这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模 ...

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

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

  3. 模拟IIC总线多设备挂载(12864OLED屏幕+GY30光照传感器)

    最终效果展示 OLED屏幕和GY30光照传感器(BH1750FVI)都连接在一个IIC(I2C)总线上,所以只需要接4根线即可.获取到的光照强度可以在OLED上实时显示并通过串口打印.IIC是IO模拟 ...

  4. C51—模拟IIC总线实现EEPROM存取数据

    a - 什么是IIC总线 -什么是EEPROM -IIC总线的通信格式 模块化设计注解 整体代码 - 什么是IIC总线 IIC总线是同步通信的一种特殊形式,具有接线口少.控制简单.器件封装形式小.通信 ...

  5. GPIO模拟IIC接口信号质量分析

    信号质量有问题的波形001: 信号质量有问题的波形002: 从上图可以看出,GPIO口模拟的I2C接口,电平都存在半高的情况. 因为I2C的接口是通过GPIO模拟实现的,该时钟信号线SCL内部默认为下 ...

  6. Chipscope 仿真VmodCAM IIC程序

    Chipscope 仿真VmodCAM IIC程序: 目的:熟悉EDK中建立chipscope 注意:zedboard使用digilent USB下载时,chipscope不能和SDK同时使用,否则芯 ...

  7. lpc1788IO口模拟IIC

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

  8. [15单片机] STC15F104W开发入门及模拟串口程序

    STC15F104W开发入门及模拟串口程序 Saturday, 31. March 2018 09:42AM - beautifulzzzz 前言 最近找到一款51内核的SOP8封装的8脚单片机STC ...

  9. STM32 软件模拟 IIC 代码,标准库、HAL库可用

    #ifndef _IIC_H #define _IIC_H #include "stdio.h" #include "stm32f1xx_hal.h" /* 定 ...

随机推荐

  1. 2015211230554《Java程序设计》第6周学习总结

    1. 本周学习总结 2. 书面作业 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 克隆方法用于创建对象的拷贝,为了使用clon ...

  2. 201521123040《Java程序设计》第3周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传.参考资料:百度 ...

  3. 201521123035《Java程序设计》第三周学习总结

    本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 书面作业 1.代码 ...

  4. 泛型在Web中的作用

    当我们写网页的时候,常常会有多个DAO,我们要写每次都要写好几个DAO,这样会有点麻烦. 那么我们想要的效果是什么呢??只写一个抽象DAO,别的DAO只要继承该抽象DAO,就有对应的方法了. 要实现这 ...

  5. MyeclipseJRE版本设置

    1.首先添加JDK版本 Window——Preferences——Java——Install JREs——Add——Stand VM——浏览JDK安装版本完成即可(一定是JDK中JRE的安装目录如:D ...

  6. 教你在Java接口中定义方法

    基本上所有的Java教程都会告诉我们Java接口的方法都是public.abstract类型的,没有方法体的. 但是在JDK8里面,你是可以突破这个界限的哦. 假设我们现在有一个接口:TimeClie ...

  7. 页面设计-数据列表 DataGrid

    传统软件项目开发时,针对每个业务单据页面需要每控件一个一个的来设计,同时需要在页面功能中对每个控件的属性进行判定处理,尤其是页面风格布局样式需要花去一大半的时间,并且后续要想修改是非常麻烦繁琐,这样就 ...

  8. cocos2dx 播放gif

    起因 或许有人会说,cocos2dx中直接帧动画就行了用什么GIF. 起因是为游戏内部要用到第三方平台的头像,而第三方平台的头像大多都是用到Gif,所以才会有了这个需求 过程 查了各种文档都没找到.但 ...

  9. js转换字符串为数值的方法

    在js读取文本框或者其他表单数据的时候获得的值是字符串类型的,比如两个文本框a和b,假设获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,由于他们都是字符串形 ...

  10. .h(头文件) .lib(库文件) .dll(动态链接库文件) 之间的关系和作用的区分

    .h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的.附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件.如果要完成源代码的编译和链接,有头文件和lib就够了 ...