基于stm32与AHT20温湿度传感器的软件模拟I2C通信
- 一、I2C通信协议
- 二、硬件与软件模拟I2C的区别
- 三、AHT20温湿度传感器接stm32的软件I2C
-
- 1、实作内容
- 2、实验代码
- 四、效果
一、I2C通信协议
I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
1、工作原理
连接在总线上的节点设备有两种角色:主机模式和从机模式。同一时刻只能有一个节点处于主机模式,其它节点处于从机模式。总线上数据的传送都是由主机发起。I2C总线是没有片选信 线的,所以也得通过协议来找到对应操作的芯片。主器件用于启动总线传输数据,并产生时钟以开放传送的器件,此时任何被寻址的器件都被认为是从器件,在总线上主和从、发和手的关系是不恒定的,而取决于此时数据传送方向。如果主机要发送数据给器件,则主机首先寻址从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件,然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下,主机负责产生时钟和终止数据传送。
AHT20_i2c.c
#include "bsp_i2c.h"#include "delay.h"uint8_t ack_status=0;uint8_t readByte[6];uint8_t AHT20_status=0;uint32_t H1=0; //Humilityuint32_t T1=0; //Temperatureuint8_t AHT20_OutData[4];uint8_t AHT20sendOutData[10] = {0xFA, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF};void IIC_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); IIC_SCL=1; IIC_SDA=1; }//产生IIC起始信 void IIC_Start(void){ SDA_OUT(); //sda线输出 IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//锁住I2C总线,准备发送或接收数据} //2úéúIICí£?1D?o?void IIC_Stop(void){ SDA_OUT();//sda??ê?3? IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1;//·¢?íI2C×ü???áê?D?o? delay_us(4); }//μè′yó|′eD?o?μ?à′//·μ???μ£o1£??óê?ó|′eê§°ü// 0£??óê?ó|′e3é1|u8 IIC_Wait_Ack(void){ u8 ucErrTime=0; SDA_IN(); //SDAéè???aê?è? IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//ê±?óê?3?0 return 0; } //2úéúACKó|′evoid IIC_Ack(void){ IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0;}//2?2úéúACKó|′e void IIC_NAck(void){ IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0;} //IIC·¢?íò???×??ú//·μ??′ó?úóD?Tó|′e//1£?óDó|′e//0£??Tó|′e void IIC_Send_Byte(u8 txd){ u8 t; SDA_OUT(); IIC_SCL=0;//à-μíê±?ó?aê?êy?Y′?ê? for(t=0;t8;t++) { IIC_SDA=(txd&0x80)>>7;txd1; delay_us(2); //??TEA5767?aèy???óê±??ê?±?D?μ? IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //?á1??×??ú£?ack=1ê±£?·¢?íACK£?ack=0£?·¢?ínACK u8 IIC_Read_Byte(unsigned char ack){ unsigned char i,receive=0; SDA_IN();//SDAéè???aê?è? for(i=0;i8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive1; if(READ_SDA)receive++; delay_us(1); } if (!ack) IIC_NAck();//·¢?ínACK else IIC_Ack(); //·¢?íACK return receive;} void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr){ IIC_Start(); if(device_addr==0xA0) //eepromμ??·′óóú1×??ú IIC_Send_Byte(0xA0 + ((addr/256)1));//·¢?í??μ??· else IIC_Send_Byte(device_addr); //·¢?÷?tμ??· IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF); //·¢?íμíμ??· IIC_Wait_Ack(); IIC_Send_Byte(data); //·¢?í×??ú IIC_Wait_Ack(); IIC_Stop();//2úéúò???í£?1ì??t if(device_addr==0xA0) // delay_ms(10); else delay_us(2);} uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead) //?á??′??÷?ò?áêy?Y{ uint16_t data; IIC_Start(); if(device_addr==0xA0) IIC_Send_Byte(0xA0 + ((addr/256)1))
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!