STM32学习过程记录7——IIC协议

发布时间:2024-12-22 16:33

谈判过程记录:详细记录每一项讨论和达成的协议。 #生活技巧# #谈判技巧# #国际商务谈判#

第七课,IIC通信协议

目录

第七课,IIC通信协议

一.IIC的原理

1.硬件原理

2.各种状态

二.IIC的代码实现

0宏定义代码

①初始化IO口,可将两个口都写为输出口。且将两根线电压拉高。

②起始、停止信号的编写

③主机的接收应答信号:

④ACK和NACK的发送

⑤发送一个字节(8位)

⑥接收一个字节(8位)

三.模板!

1.宏定义

2.IIC

一.IIC的原理

1.硬件原理

I2C所使用的数据传输线有两根,一根时钟线SCL,一根信号线SDA。

2.各种状态

①空闲状态:两根线同时为高电平

②起始信号:SCL仍为高,而SDA由高到底

③停止信号:SCL仍为高,而SDA由低到高(前三者可以对比记忆)

④应答信号:(ACK和NACK)应答信号是指,在一次传输数据的过程中,只能传输8位有效位,在第9个周期时,发出一个信号,表明数据信号完全成功接收。可能难以理解,应用正点原子的话,自行体会:

发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。

应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;

应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 

对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,

并且确保在该时钟的高电平期间为稳定的低电平。

如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,

以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

⑤数据的有效性:在时钟到达高电平之前,数据位必须保持稳定(高或低)。也就是说,数据线必须必时钟线先变化,以便时钟线动作的时候能够有稳定的信号可读。

⑥数据的传送:没有过多的说明,按位发送。数据位的传输是边沿触发。

二.IIC的代码实现

0宏定义代码

#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;} //修改SDA线的状态

#define IIC_SCL PCout(12) //输出SCL

#define IIC_SDA PCout(11) //输出SDA

#define READ_SDA PCin(11) //读入SDA

①初始化IO口,可将两个口都写为输出口。且将两根线电压拉高。

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

IIC_SCL=1;

IIC_SDA=1;

②起始、停止信号的编写

起始:

SDA_OUT();//SDA线设为输出模式

IIC_SCL=1;//SCL线确保为高

delay_us(4);

IIC_SDA=0;//SDA变低,产生开始信号

delay_us(4);

IIC_SCL=0;//SCL变低,准备产生数据位的改变

停止:

SDA_OUT();//更改SDA为输出模式

IIC_SCL=0;//★先拉低SCL线,确保SDA能够改变(参照读位的思想)

IIC_SDA=0;

delay_us(4);

IIC_SCL=1;//拉高时钟线

IIC_SDA=1;//产生停止信号

delay_us(4);

③主机的接收应答信号:

//返回1失败,返回0成功

u8 IIC_Wait_Ack(void)

{

u8 ucErrTime=0;

SDA_IN(); //SDA设为输入

IIC_SDA=1;

delay_us(1);

IIC_SCL=1;

delay_us(1);

while(READ_SDA)//检测SDA是否输出0

{

ucErrTime++;

if(ucErrTime>250)

{

IIC_Stop();//超时,停止IIC的传输

return 1;

}

}

IIC_SCL=0;

return 0;

}

④ACK和NACK的发送

void IIC_Ack(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=0;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

void IIC_NAck(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

⑤发送一个字节(8位)

涉及到位操作代码,自己体会

void IIC_Send_Byte(u8 txd)

{

u8 t;

SDA_OUT();

IIC_SCL=0;//拉低时钟线,开始传输

for(t=0;t<8;t++)

{

IIC_SDA=(txd&0x80)>>7;

txd<<=1;

delay_us(2); //发送信号

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

delay_us(2);

}

}

⑥接收一个字节(8位)

返回一个u8

ack = 1时,发送ACK, =0,发送NACK

u8 IIC_Read_Byte(unsigned char ack)

{

unsigned char i,receive=0;

SDA_IN();//SDAÉèÖÃΪÊäÈë

for(i=0;i<8;i++ )

{

IIC_SCL=0;

delay_us(2);

IIC_SCL=1;

receive<<=1;

if(READ_SDA)receive++;

delay_us(1);

}

if (!ack)

IIC_NAck();

else

IIC_Ack();

return receive;

}

三.模板!

1.宏定义

//SDA线模式选择

#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

//操作口

#define IIC_SCL PCout(12)

#define IIC_SDA PCout(11)

#define READ_SDA PCin(11)

//函数声明

#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

#define IIC_SCL PCout(12)

#define IIC_SDA PCout(11)

#define READ_SDA PCin(11)

2.IIC

void IIC_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

//RCC->APB2ENR|=1<<4;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

IIC_SCL=1;

IIC_SDA=1;

}

void IIC_Start(void)

{

SDA_OUT();

IIC_SDA=1;

IIC_SCL=1;

delay_us(4);

IIC_SDA=0;

delay_us(4);

IIC_SCL=0;

}

void IIC_Stop(void)

{

SDA_OUT();

IIC_SCL=0;

IIC_SDA=0;

delay_us(4);

IIC_SCL=1;

IIC_SDA=1;

delay_us(4);

}

u8 IIC_Wait_Ack(void)

{

u8 ucErrTime=0;

SDA_IN();

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;

return 0;

}

void IIC_Ack(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=0;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

void IIC_NAck(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

void IIC_Send_Byte(u8 txd)

{ //1有应答 0无应答

u8 t;

SDA_OUT();

IIC_SCL=0;

for(t=0;t<8;t++)

{

IIC_SDA=(txd&0x80)>>7;

txd<<=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

delay_us(2);

}

}

u8 IIC_Read_Byte(unsigned char ack)//1ACK 0NACK

{

unsigned char i,receive=0;

SDA_IN();

for(i=0;i<8;i++ )

{

IIC_SCL=0;

delay_us(2);

IIC_SCL=1;

receive<<=1;

if(READ_SDA)receive++;

delay_us(1);

}

if (!ack)

IIC_NAck();

else

IIC_Ack();

return receive;

}

网址:STM32学习过程记录7——IIC协议 https://www.yuejiaxmz.com/news/view/540145

相关内容

STM32学习笔记(4):SysTick
【学习笔记】stm32+ESP8266+阿里云+云智能APP
基于STM32的智能家居系统:MQTT、AT指令、TCP\HTTP、IIC技术
基于STM32的家庭健康监测系统
STM32智能照明控制系统设计详解
STM32智能照明控制系统教程
STM32
基于STM32智能照明控制系统设计
全栈智能家居系统设计方案:STM32+Linux+多协议(MQTT、Zigbee、Z
STM32智能除湿系统的设计方案

随便看看