教你手写IIC协议(看完这篇你就会手动写啦,保姆级讲解) | 您所在的位置:网站首页 › 教你如何手写立体字体视频 › 教你手写IIC协议(看完这篇你就会手动写啦,保姆级讲解) |
前几篇关于IIC协议理论方面的文章
1.嵌入式stm32 复习(工作用)—IIC通讯协议 原理部分 2020.2.16 添加链接描述 2.嵌入式stm32 复习(工作用)—手写IIC协议之前应该掌握知识点 2020.2.19 添加链接描述 先上完整模拟iic代码,基本上复制粘贴就能用!!!iic.c文件 #include "iic.h" #define SDA_IN() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x80000000;} #define SDA_OUT() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x30000000;} #define IIC_SCL PBout(6) #define IIC_SDA PBout(7) #define SDA_READ PBin(7) void IIC_Init(void) { RCC->APB2ENR|=1CRL|=0x33000000; IIC_SCL=0; IIC_SDA=0; } void IIC_Start(void) { SDA_OUT(); IIC_SCL=1; IIC_SDA=1; sleep_us(4); IIC_SDA=0; sleep_us(4); IIC_SCL=0; } void IIC_SendByte(u8 dat) { u8 i=0; SDA_OUT(); IIC_SCL=0; for(i=0;i SDA_OUT(); IIC_SCL=0; IIC_SDA=0; sleep_us(4); IIC_SCL=1; sleep_us(1); IIC_SDA=1; sleep_us(4); } u8 IIC_Wait_Ask(void) { u8 time=0; SDA_IN(); IIC_SDA=1; sleep_us(1); IIC_SCL=1; sleep_us(1); while(SDA_READ){ time++; if(time>=200){ IIC_Stop(); return 1; } } IIC_SCL=0; return 0; } void IIC_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; sleep_us(1); IIC_SCL=1; sleep_us(1); IIC_SCL=0; } u8 IIC_ReadByte(void) { u8 i=0; u8 tmp=0; SDA_IN(); for(i=0;i IIC_SDA=(dat>>7)&0x01; sleep_us(2); IIC_SCL=1; sleep_us(2); IIC_SCL=0; dat IIC_Stop(); return 1; } } IIC_SCL=0; return 0;//这部分代码个人感觉是这个代码的重点吧!!! //首先我们应该知道怎么样才能识别到SDA(数据线)上的低电平呢? //这部分代码的逻辑就是:如果单片机等待这个应答信号,迟迟未等到的话,总不能一直等待下去,那样的话就会卡死在这个while循环当中,事实这样是不可以的。 //那么我们应该限制一个时间段,如果系统等待的时间超过这个时间段的话,比如代码中的200,那么我们直接停止传输IIC,并且返回传输失败标志1; //如果系统等待的时间小于这个时间段的话,那么就代表数据传输成功。此时将SCL(时钟线)拉到低电平,并且返回传输成功标志0。 iic.c部分 iic产生应答信号部分 IIC_SCL=0; SDA_OUT();//与IIC协议中的发送数据方式一样,区别就在于SDA模式不同。此时产生应答信号SDA为输出模式。同理,在读取数据过程中SDA(数据线)为输入模式。 //根据时序图可知,在产生应答信号之前,时钟线是处于低电平状态。 IIC_SDA=0; sleep_us(1);//此时SDA(数据线)为低电平。并且延时一段时间。 IIC_SCL=1; sleep_us(1); IIC_SCL=0;//由时序图可知,此时应该让SCL(时钟线)产生第九个时钟周期。所以先将SCL(时钟线)拉高,然后延时一段时间,然后再将SCL(时钟线)拉低即成功产生应答信号。 iic.c部分 iic读取数据部分 u8 tmp=0;//设置一个读取数据的缓存区。 SDA_IN();//设置SDA(数据线)为输入模式。 for(i=0;i |
CopyRight 2018-2019 实验室设备网 版权所有 |