使用GPIO引脚模拟SDA和SCL总线实现软件模拟IIC通信,IIC的具体通信协议层和物理层链接:IIC

#ifndef __BSP_IIC_H
#define __BSP_IIC_H #include "stm32f10x.h" #define SCL_PORT GPIOA
#define SCL_PIN GPIO_Pin_2
#define SCL_MOOD GPIO_Mode_Out_OD
#define SCL_SPEED GPIO_Speed_50MHz #define SDA_PORT GPIOA
#define SDA_PIN GPIO_Pin_3
#define SDA_MOOD GPIO_Mode_Out_OD
#define SDA_SPEED GPIO_Speed_50MHz #define SDA_1() GPIO_SetBits(SDA_PORT, SDA_PIN)
#define SDA_0() GPIO_ResetBits(SDA_PORT, SDA_PIN) #define SCL_1() GPIO_SetBits(SCL_PORT, SCL_PIN)
#define SCL_0() GPIO_ResetBits(SCL_PORT, SCL_PIN) #define SDA_READ GPIO_ReadInputDataBit(SDA_PORT, SDA_PIN) /* ACK原型为acknowledge,意为:报告已收到 */
void Delay(void);
void IIC_START(void);
void IIC_STOP(void);
void IIC_ACK(void);
void IIC_NACK(void);
uint8_t IIC_ReadACK(void);
void IIC_SendByte(uint8_t data) ;
uint8_t IIC_ReadByte(void);
void IIC_GPIO_Config(void); #endif /* __BSP_IIC_H */


void Delay(void)
{
uint8_t i; /* 
下面的时间是通过逻辑分析仪测试得到的。
工作条件:CPU主频72MHz ,MDK编译环境,1级优化 循环次数为10时,SCL频率 = 205KHz
循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us
循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us
*/
for (i = 0; i < 10; i++);
} /* SCL高电平时期SDA产生下降沿表示起始信号 */
void IIC_START(void)
{
SDA_1();
SCL_1();
Delay(); SDA_0();
Delay();
SCL_0();
Delay();
} /* SCL高电平时期SDA产生上升沿表示停止信号 */
void IIC_STOP(void)
{
SDA_0();
SCL_1();
Delay(); SDA_1();
Delay();
/* 停止信号后SDA和SCL都为高电平 */
} /* SCL高电平时期 SDA保持低电平代表 应答信号 */
void IIC_ACK(void)
{
SDA_0();
Delay();
SCL_1();
Delay(); SCL_0();
Delay();
SDA_1();
/* 随后释放SDA总线 */
} /* SCL高电平时期 SDA保持高电平代表 非应答信号 */
void IIC_NACK(void)
{
SDA_1();
Delay();
SCL_1();
Delay(); SCL_0();
/* SDA已经为高电平,无需释放 */
} /* CPU产生一个SCL时钟,读取应答 ACK:0 NACK:1*/
/* 因为SDA平时为高电平,所以没有收到应答时,SDA还为高电平,即读取到 1 为非应答 */
uint8_t IIC_ReadACK(void)
{
uint8_t k;
/* 释放SDA总线 */
SDA_1();
Delay();
/* SCL为高电平时,才会读取有效数据 */
SCL_1();
Delay(); /* 读取信号 */
if(SDA_READ==1)
k=1;
else
k=0;
/* 收到信号后SCL要拉低 */
SCL_0();
Delay();
return k;
} /* 发送一个字节,先发送高位 */
void IIC_SendByte(uint8_t data)
{
uint8_t n=0x01;
int i;
SCL_0();
Delay();
for(i=7;i>=0;i--)
{
if(n&(data>>i))
{
SDA_1();
Delay();
SCL_1();
Delay();
}
else
{
SDA_0();
Delay();
SCL_1();
Delay();
}
SCL_0();
Delay();
}
/* 发送完一个字节后释放SDA总线 */
SDA_1();
Delay(); } /* 读取一个字节,在CPU产生的SCL高电平时期读取 */
uint8_t IIC_ReadByte(void)
{
// uint8_t i,data=0;
// for(i=0;i<8;i++)
// {
// SCL_1();
// Delay();
// if(SDA_READ)
// {
// data++; /* 利用自增实现对最低位写 1 */
// }
// data<<=1;
// SCL_0();
// Delay();
//
// }
// return data;
// uint8_t i; uint8_t temp = 0; for(i=0;i<8;i++)
{
temp<<=1; SCL_1();
Delay(); if( SDA_READ==1 )
{
temp += 1;
} SCL_0();
Delay();
} return temp;
} /* 配置SCL和SDA对应的GPIO引脚,模式都为开漏输出 */
void IIC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Pin = SCL_PIN;
GPIO_InitStruct.GPIO_Mode = SCL_MOOD;
GPIO_InitStruct.GPIO_Speed = SCL_SPEED;
GPIO_Init(SCL_PORT, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = SDA_PIN;
GPIO_InitStruct.GPIO_Mode = SDA_MOOD;
GPIO_InitStruct.GPIO_Speed = SDA_SPEED;
GPIO_Init(SDA_PORT, &GPIO_InitStruct); /* 给一个停止信号,使IIC总线上所有设备处于复位 */
IIC_STOP(); }

STM32—IIC通信(软件实现底层函数)的更多相关文章

  1. 半吊子的STM32 — IIC通信

    半双工通信模式:以字节模式发送(8位): 两线式串行总线,SDA(数据信号)和SCL(时钟信号)两条信号线都为高电平时,总线为空闲状态:起始时,SCL稳定为高电平,SDA电平由高向低跳变:停止时,SC ...

  2. STM32 IIC双机通信—— HAL库硬件IIC版

    参考传送门 关于IIC的原理这里我就不多说了,网上有很多很好的解析,如果要看我个人对IIC的理解的话,可以点击查看,这里主要讲一下怎样利用STM32CubeMx实现IIC的通讯,经过个人实践,感觉HA ...

  3. 基于51单片机IIC通信的PCF8591学习笔记

    引言 PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入.一个输出和一个串行I2C 总线接口.3 个地址引脚A0.A1 和A2 用于编程硬件地址,允许将最多8 个器件连接 ...

  4. 基于51单片机IIC通信的AT24C02学习笔记

    引言 最近在学习几种串行通信协议,感觉收获很多,这篇文章是学习IIC总线协议的第一篇文章,以后还会再写一篇关于PCF8591 IIC通信的ADDA转换芯片的文章. 关于IIC总线 IIC 即Inter ...

  5. Stm32串口通信(USART)

    Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...

  6. STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...

  7. 【Java】Java socket通信使用read,readline函数的阻塞问题

    Socket通信是Java网络编程中比较基础的部分,其原理其实就是源ip,源端口和目的ip,目的端口组成的套接字通信.其底层还设及到了TCP协议的通信. Java中的Socket通信可以通过客户端的S ...

  8. STM32 对内部FLASH读写接口函数(转)

    源:STM32 对内部FLASH读写接口函数 因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序. ...

  9. STM32 串口通信使用奇偶校验

    STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...

随机推荐

  1. MySQL中的字段拼接 concat() concat_ws() group_concat()函数

    1.concat()函数 2.concat_ws()函数 3.group_concat()函数 操作的table select * from test_concat order by id limit ...

  2. Parrot os 安装vmtools

    1.更新源(这步个人觉得官方源还可以,没网上说的那么慢) vim /etc/apt/sources.list.d/parrot.list linux命令 ,按i进入修改模式,修改结束,之后先按esc, ...

  3. 2012年第三届蓝桥杯C/C++程序设计本科B组省赛 取球博弈

    2012年第三届蓝桥杯C/C++程序设计本科B组省赛 取球博弈 题目描述 **取球博弈 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并 ...

  4. Jmeter之代理元件&代理配置

    一 jmeter代理服务器添加及网页代理配置 1.1 打开jmeter,添加代理HTTP代理服务器,再添加一个线程组,放在代理服务器的下面. 1.2 代理服务器设置 端口默认8888,目标控制器选择t ...

  5. webview和H5交互

    由于H5的灵活多变,动态可配的特点,也为了避免冗长 的审核周期,H5页面在app上的重要性正日益突显. iOS应用于H5交互的控件主要是UIWebView及WKWebView WKWebView是14 ...

  6. postgresql 使用游标笔记

    游标介绍:游标是一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务端的sql语句,或是批处理.存储过程.触发器中的数据处理请求. 游标的优点在于它允许应用程序对查询语 ...

  7. [期望DP][纪中]【2010集训队出题】彩色圆环

    彩色圆环 感谢名单 十分感谢 JA_Ma 为我讲解了 \(T1\) 的 期望DP 的思想和推论. 十分感谢 SSL_LYF 为我解答了 \(T1\) 的 期望DP 的概率的大小问题. 十分感谢 SSL ...

  8. Spring Boot(一):如何使用Spring Boot搭建一个Web应用

    Spring Boot Spring Boot 是Spring团队旗下的一款Web 应用框架 其优势可以更快速的搭建一个Web应用 从根本上上来讲 Spring Boot并不是什么新的框架技术 而是在 ...

  9. 《Node+MongoDB+React 项目实战开发》已出版

    前言 从深圳回长沙已经快4个月了,除了把车开熟练了外,并没有什么值得一提的,长沙这边要么就是连续下一个月雨,要么就是连续一个月高温暴晒,上班更是没啥子意思,长沙这边的公司和深圳落差挺大的,薪资也是断崖 ...

  10. 第二篇 -- Qt Designer界面介绍

    1. Qt Designer创建界面 2. Qt Designer全局