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" /* 定 ...
随机推荐
- 工厂模式 and 单例模式
工厂模式:使用工厂类使创建类与使用类分离,从而提高代码的易维护性,可扩展性等 工厂模式分位简单工厂模式和工厂方法模式 使用简单工厂模式的步骤: 1.创建父类及其子类 父类中有[ ...
- 存储过程重置SEQUENCE值从新开始。
CREATE OR REPLACE PROCEDURE RESET_SEQUENCE( v_SeqName IN VARCHAR2, v_sqlcode OUT NUMBER, v_sqlerrm O ...
- python实现裴波那契数列
def Fib(n): ''' 假定序号为0或者1,返回1,序号为2时返回2 ''' before = 1 after = 1 for i in range(n): before, after = a ...
- 枚举类TimeUnit
枚举类TimeUnit 全路径为 java.util.concurrent.TimeUnit TimeUnit 主要用于通知基于时间的方法如何解释给定的计时参数 举例如下 如果 lock 不可用,则以 ...
- String,StringBuffer,StringBuilder的区别及其源码分析
String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结: 1.先来分析一下这三个类之间的关系 乍一看它们都是用于处理字符串的java类,而 ...
- PuTsangTo
一. 跳跃与移动的优化与完善 先给上一次的内容做一次补救,也就是上一次中还留存的,由于键盘按键事件的第一次回调与后续回调之间会间隔个小半秒带来的跳跃落地后动作延迟的情况. 最终的键盘按下回调的处理代码 ...
- 最小覆盖_KEY
最小覆盖(cover)..线段树 [题目描述] 给定 N 个区间[Li,Ri],需要你按照顺序选出一个区间序列使得[1,M]完全被覆盖.并且在选出来的序列中,某个区间[a,b]之前必须保证[1,a]都 ...
- Linux学习——shell编程之正则表达式和字符处理命令
shell编程之正则表达式 一 正则表达式 1 什么是正则表达式 正则表达式用于描述字符排列和匹配模式的一种语法规则.它主要用于字符串的模式分隔.匹配.查找及替换操作. 2 shell编程之正则表达式 ...
- class DELPHICLASS TObject
class DELPHICLASS TObject 1.自己猜想:delphi,是windows平台的快速应用程序开发工具Rapid Application Development 简称RAD. ...
- FZU 1919 -- K-way Merging sort(记忆化搜索)
题目链接 Problem Description As we all known, merge sort is an O(nlogn) comparison-based sorting algorit ...