datasheet

STM32小白入门(第12天)-------I2C协议

2019-07-10来源: eefocus关键字:STM32  I2C协议

一、概述



二、信号概念


三、AT24C02(EEPROM电可擦除ROM)--配合单片机存贮掉电前需要保存的数据,类似单片机的硬盘


1、写时序



2、读时序



思考题2:在24c02控制时钟的时候,为什么要进行5us的延时,小于5us延时或许大于5us的延时是否可以,示例代码如下:


        //设置SCL高电平

SCL=1;

delay_us(5);

//设置SCL低电平

SCL=0;

delay_us(5);

回答:大于5us是可以的,如果使用5ms是可以的。但是延时是不能低于1.2us,详细描述如下图。





3、起始信号和停止信号



//sda输入输出模式切换函数

void OLED_SDA_Mode(GPIOMode_TypeDef IOMode)

{

//PB9初始化设置 

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin   =  OLED_SDA_PIN; //9号引脚

GPIO_InitStructure.GPIO_Mode  = IOMode;     //输出模式/输入模式

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       //推挽输出,驱动LED需要电流驱动

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz

GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP; //上拉

GPIO_Init(OLED_GPIO_PORT, &GPIO_InitStructure); //初始化GPIOB,把配置的数据写入寄存器

}

/**********************************************

//IIC Start

**********************************************/

void IIC_Start(void)

{

//保证SDA引脚为输出模式

OLED_SDA_Mode(GPIO_Mode_OUT);

OLED_SCLK = 1;

OLED_SDA_W = 1;

/*注:原版代码是没有加延时的,这里一定要延时,因为M4是高速芯片,3.3MHz通信速率,所以一个时钟周 期约为0.3us,有与我们处理器是168MHz,执行一条指令比这个时间快很多所以我们需要加至少1us的延时,

但是在频率较低的处理器中我们可以不加延时

*/

delay_us(1);

OLED_SDA_W = 0;    //数据线先拉低,时钟线后拉低,即为启动信号

delay_us(1);

OLED_SCLK = 0;

delay_us(1);

}

 

/**********************************************

//IIC Stop

**********************************************/

void IIC_Stop(void)

{

//保证SDA引脚为输出模式

OLED_SDA_Mode(GPIO_Mode_OUT);

OLED_SCLK = 1;    //时钟线先拉高,数据线后拉高,即为停止信号

OLED_SDA_W = 0;

delay_us(1);

OLED_SDA_W = 1;

delay_us(1);

}

uint8_t IIC_Wait_Ack(void)

{

uint8_t ack=0;

//保证SDA引脚为输入模式

OLED_SDA_Mode(GPIO_Mode_IN);

OLED_SCLK = 1;

delay_us(1);

//有应答为低电平,无应答为高电平

if(OLED_SDA_R) //无应答

{

ack=1;

IIC_Stop();

}

else //有应答

ack=0;

OLED_SCLK = 0;

delay_us(1);

return ack;

}

/**********************************************

// IIC Read byte

**********************************************/

uint8_t i2c_recv_byte(void)

{

uint8_t byte=0;


uint32_t i=0;

//保证SDA引脚为输出模式

i2c_sda_mode(GPIO_Mode_OUT);


//设置为低电平

SCL=0;

SDA_W=0;


delay_us(5);


//保证SDA引脚为输入模式

i2c_sda_mode(GPIO_Mode_IN);


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

{

//设置时钟为高电平,告诉从机,可以对SDA引脚进行控制

SCL=1;

delay_us(5);


//读取SDA引脚的电平

if(SDA_R)

byte|=1<<(7-i);



//设置时钟为低电平,告诉从机,不可以对SDA引脚进行控制

SCL=0;

delay_us(5);

}


return byte;

}

void at24c02_read(uint8_t addr,uint8_t *pbuf,uint32_t len)    //从机读取数据

{

uint32_t ack=0;

//发送起始信号

i2c_start();

//发送寻址地址

i2c_send_byte(0xA0);

 

 

//等待应答

ack=i2c_wait_ack();

if(ack)

{

printf("i2c ack device address failrn");

return ;

}

printf("i2c ack device address okrn");

 

//发送24c02的数据存储地址

i2c_send_byte(addr);

 

//等待应答

ack=i2c_wait_ack();

if(ack)

{

printf("i2c ack word address failrn");

return ;

}

printf("i2c ack word address okrn");

//再一次发送起始信号

i2c_start();

//发送寻址地址,读访问操作

i2c_send_byte(0xA1);

//等待应答

ack=i2c_wait_ack();

if(ack)

{

printf("i2c ack device address_r failrn");

return ;

}

printf("i2c ack device address_r okrn");

len=len-1;

while(len--)

{

*pbuf++=i2c_recv_byte();

i2c_ack(0);

}

*pbuf=i2c_recv_byte();

i2c_ack(1);

//发送停止信号

i2c_stop();

printf("i2c ack read data okrn");

}

/**********************************************

// IIC Write byte

**********************************************/

 

void Write_IIC_Byte(unsigned char IIC_Byte)

{

unsigned char i;

 

//保证SDA引脚为输出模式

OLED_SDA_Mode(GPIO_Mode_OUT);

OLED_SCLK = 0;

delay_us(1);

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

{

if(IIC_Byte&(1<<(7-i)))  MSB

OLED_SDA_W = 1;

else 

OLED_SDA_W = 0;

delay_us(1);

OLED_SCLK = 1;

delay_us(1);

OLED_SCLK = 0;

delay_us(1);

}

}


关键字:STM32  I2C协议

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic467305.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32——硬件和软件I2C协议
下一篇:STM32小白入门(第16天)-------红外

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32开发笔记71: 解决FreeRTOS任务的内存分配问题

单片机型号:STM32F091RCT6在使用FreeRTOS进行程序设计时,遇到任务不能运行的问题,具体程序如下: DebugOutput("启动USB通讯线程...rnrn"); osThreadDef(usbTask, StartUsbTask, osPriorityNormal, 0, 128); usbTaskHandle = osThreadCreate(osThread(usbTask), NULL); DebugOutput("启动雷达红外通讯线程...rnrn"); osThreadDef(irdaTask, St
发表于 2019-07-13

STM32开发笔记72: 使用命名空间解决类名冲突问题

单片机型号:STM32L053R8T6在程序设计中,使用了两个类,这两个类都有引脚定义并同名,程序如下:#ifndef E32_400T20S_H_#define E32_400T20S_H_ #include "io.h"#include "mini_uart.h" #ifdef __cplusplusextern "C"{ class CM0:public CIO_Output{public: CM0(void);}; class CM1:public CIO_Output{public: CM1(void);}; 
发表于 2019-07-13

STM32开发笔记73: C++中子类调用父类同名函数的处理方法

单片机型号:STM32L053R8T61、问题父类有1方法:Enable_RS485,如下所示:class CUart{public: uint8_t u8_UartNumber; //端口号1-8 uint32_t u32_BaudRate; //波特率 uint8_t u8_Parity; //效验位 CC0 C0; //485控制引脚C0 CC1 C1; //485控制引脚C1 UART_HandleTypeDef hUART; uint8_t u8_UartReceiveBuffer[1];public: CUart(uint8_t
发表于 2019-07-13

STM32开发笔记74: STM32L0低功耗唤醒后的时钟选择

本文介绍STM32L0系列单片机低功耗唤醒后的时钟选择。参看已有的低功耗例程,发现都使能了HSI时钟,一致没有深究其中的具体原因,今天把它搞明白了,现记录如下:先看一下,使能低功耗的函数:void CTarget::EnableLowPower(void){ HAL_PWREx_EnableUltraLowPower(); HAL_PWREx_EnableFastWakeUp(); __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); DisableAllIO();}第1句使能超低功耗,第2句使能快速唤醒,第3句选择唤醒后的主始终,第4句将所有IO引脚设置为低功耗状态
发表于 2019-07-13

STM32开发笔记75: 使用STM32CubeMX点亮一个LED

今天调试在自己的程序框架下调试RTC始终不成功,只要初始化RTC就进入死机状态。现在重温一下STM32CubeMX的使用方法,看STM32CubeMX生成的程序是否有RTC初始化不成功的问题。本日志从工程的建立讲到点亮一个LED。1、启动STM32CubeMX,我现在使用的版本是5.2.1。2、File-New Project,选择相应的芯片类型。3、双击相应的芯片类型后,进入配置界面。进行SYS配置,选中Debug Serial Wire,由于我习惯于使用FreeRTOS所以在我的项目中Timebase Source都选择定时器。4、进行RCC设置。5、时钟设置如下:6、在芯片引脚图中,将连接LED的引脚设置
发表于 2019-07-13
STM32开发笔记75: 使用STM32CubeMX点亮一个LED

STM32开发笔记76: 初始化RTC后死机的原因

项目开发中只要初始化RTC,则系统死机。其初始化步骤可参考日志:STM32开发笔记44:RTC驱动程序的移植。按照日志STM32开发笔记75: 使用STM32CubeMX点亮一个LED使用STM32CubeMX直接生成程序则运行正常。分析原因在于,少移植了2个函数:HAL_RTC_MspInit和HAL_RTC_MspDeInit。这两个函数的实现非常简单,可以靠STM32CubeMX直接生成。void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc){  __HAL_RCC_RTC_ENABLE();   HAL_NVIC_SetPriority(RTC_IRQn
发表于 2019-07-13

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved