STM32F10X -- 模拟IIC程序
听说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程序的更多相关文章
- stm32软件模拟IIC读取PX4FLOW光流传感器数据
这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模 ...
- 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)
版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...
- 模拟IIC总线多设备挂载(12864OLED屏幕+GY30光照传感器)
最终效果展示 OLED屏幕和GY30光照传感器(BH1750FVI)都连接在一个IIC(I2C)总线上,所以只需要接4根线即可.获取到的光照强度可以在OLED上实时显示并通过串口打印.IIC是IO模拟 ...
- C51—模拟IIC总线实现EEPROM存取数据
a - 什么是IIC总线 -什么是EEPROM -IIC总线的通信格式 模块化设计注解 整体代码 - 什么是IIC总线 IIC总线是同步通信的一种特殊形式,具有接线口少.控制简单.器件封装形式小.通信 ...
- GPIO模拟IIC接口信号质量分析
信号质量有问题的波形001: 信号质量有问题的波形002: 从上图可以看出,GPIO口模拟的I2C接口,电平都存在半高的情况. 因为I2C的接口是通过GPIO模拟实现的,该时钟信号线SCL内部默认为下 ...
- Chipscope 仿真VmodCAM IIC程序
Chipscope 仿真VmodCAM IIC程序: 目的:熟悉EDK中建立chipscope 注意:zedboard使用digilent USB下载时,chipscope不能和SDK同时使用,否则芯 ...
- lpc1788IO口模拟IIC
#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...
- [15单片机] STC15F104W开发入门及模拟串口程序
STC15F104W开发入门及模拟串口程序 Saturday, 31. March 2018 09:42AM - beautifulzzzz 前言 最近找到一款51内核的SOP8封装的8脚单片机STC ...
- STM32 软件模拟 IIC 代码,标准库、HAL库可用
#ifndef _IIC_H #define _IIC_H #include "stdio.h" #include "stm32f1xx_hal.h" /* 定 ...
随机推荐
- Python的变量参数
- sublime主题安装
网上发现与之前最相近的两款皮肤分别是Theme – Soda与Flatland.这里就记录一下安装与使用方法. 方法一:手动下载安装: 1.下载安装SublimeText2,这个我就不说了.网上的版本 ...
- javascript:12种JavaScript MVC框架之比较
Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember. ...
- 一步步带你做vue后台管理框架(三)——登录功能
系列教程<一步步带你做vue后台管理框架>第三课 github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 ...
- linux fork两次避免僵尸进程的程序(简单)
#include<stdio.h> #include<unistd.h> int main() { pid_t pid,pid1; int status; ) { printf ...
- python 作用域(LEGB)
def fa(a): b = 200 c = 888 def fb(b): print(b) print(a) print(c) print(sum) return fb c = 2 sum = 10 ...
- oracle "记录被另一个用户锁定"
出现的原因是有人对某一条数据进行了修改,oracle会通过这个事务记住这条数据,若修改的人没有进行提交或进行回滚记录,oracle是不允许对这条数据在此进行修改的,在这种情况下你要进行修改数据,则会被 ...
- 【】小技巧】CSS文字两端对齐
需求如下,红框所在的文字有四个字的.三个字的.两个字的,如果不两端对齐可以选择居中对齐,或者右对齐.但是如果要像下面这样两端对齐呢? 我相信以前很多人都这么干过:两个字中间使用 来隔开达到四个字的宽度 ...
- All about Div内显示滚动桥
Div内显示滚动桥看似是一个简单的前端问题,然而实际会发现还是有挺多需要注意的, 本文尝试对div内显示滚动桥的各种主要实现及一些难题进行研究. 横向滚动桥 横向滚动桥比较简单,无需设置宽度,直接ov ...
- 利用PN532读取二代证UID
准备工作 芯片选择 NFC芯片,需要支持ISO14443 Type B协议,比如PN532 阅读ISO 14443 重点阅读如下内容: 7.3.4.1 状态转换图 7.3.5 ~ 7.3.7 REQB ...