STM32F2系列驱动开发——模拟I2C通信

来源:本站
导读:目前正在解读《STM32F2系列驱动开发——模拟I2C通信》的相关信息,《STM32F2系列驱动开发——模拟I2C通信》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《STM32F2系列驱动开发——模拟I2C通信》的详细说明。
简介:一、概述
通过STM32的PC14和PC15管脚来模拟I2C通信,读写I2C接口的器件内部寄存器......

一、概述

通过STM32的PC14和PC15管脚来模拟I2C通信,读写I2C接口的器件内部寄存器,具体定义如下:

#define PIN_SCL GPIO_Pin_14

#define PIN_SDA GPIO_Pin_15

延时函数为μs延时,例如Delay(4)表示延时4μs。

二、Static型函数定义

static __inline void TWI_SCL_0(void) { GPIOC->BSRRH = PIN_SCL; }

static __inline void TWI_SCL_1(void) { GPIOC->BSRRL = PIN_SCL; }

static __inline void TWI_SDA_0(void) { GPIOC->BSRRH = PIN_SDA; }

static __inline void TWI_SDA_1(void) { GPIOC->BSRRL = PIN_SDA; }

static __inline u8 TWI_SDA_STATE(void) { return (GPIOC->IDR & PIN_SDA) != 0; }

三、功能函数定义

void TWI_Init(void);

u8 TWI_Start(void);

u8 TWI_Start_SHT(void);

void TWI_Stop(void);

void TWI_SendByte(u8 Data);

u8 TWI_ReceiveByte(void);

void TWI_SendACK(void);

void TWI_SendNACK(void);

u8 TWI_WaitACK(void);

u8 TWI_WriteOneByte(u8 DAddr,u8 Addr,u8 Dat);

u8 TWI_ReadOneByte(u8 Daddr,u8 Addr);

四、功能函数详解

4.1 I2C端口初始化

说明:(1)SDA设置为开漏输出,这是双向数据线常规I/O方式。

(2)SCL设置为推挽输出

void TWI_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC->AHB1ENR |= 1<<2;

RCC->APB1ENR |= 1<<28;

PWR->CR |= 1<<8;

RCC->BDCR &= ~(1<<0);

GPIO_InitStructure.GPIO_Pin = PIN_SDA;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOC,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = PIN_SCL;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOC,&GPIO_InitStructure);

TWI_SDA_1();

TWI_SCL_0();

}

4.2 I2C发送启动函数

u8 TWI_Start(void)

{

TWI_SDA_1();

TWI_SCL_1();

Delay(4);

if(!TWI_SDA_STATE())//SDAÏßΪµÍµçƽÔò×ÜÏß棬Í˳ö

{

return TWI_FAILURE;

}

TWI_SDA_0();

Delay(4);

while(TWI_SDA_STATE())//SDAÏßΪ¸ßµçƽÔò×ÜÏß³ö´í£¬Í˳ö

{

return TWI_FAILURE;

}

TWI_SCL_0();

Delay(4);

return TWI_SUCCESS;

}

4.3 I2C停止函数

void TWI_Stop(void)

{

TWI_SDA_0();

TWI_SCL_0();

Delay(4);

TWI_SCL_1();

Delay(4);

TWI_SDA_1();

}

4.4 向从机发送应答信号

void TWI_SendACK(void)

{

TWI_SDA_0();

TWI_SCL_0();

Delay(4);

TWI_SCL_1();

Delay(4);

TWI_SCL_0();

}

4.5 发送无应答信号

void TWI_SendNACK(void)

{

TWI_SDA_1();

TWI_SCL_0();

Delay(4);

TWI_SCL_1();

Delay(4);

TWI_SCL_0();

}

4.6 等待从机应答信号

u8 TWI_WaitACK(void)

{

TWI_SCL_0();

TWI_SDA_1();

Delay(4);

TWI_SCL_1();

Delay(4);

while(TWI_SDA_STATE())

{

TWI_SCL_0();

return TWI_FAILURE;

}

TWI_SCL_0();

return TWI_SUCCESS;

}

4.7 发送一字节数据函数

void TWI_SendByte(u8 Data)

{

u8 i=8;

while(i--)

{

TWI_SCL_0();

Delay(1);

if(Data&0x80)

{

TWI_SDA_1();

}

else

{

TWI_SDA_0();

}

Data<<=1;

Delay(4);

TWI_SCL_1();

Delay(4);

}

TWI_SCL_0();

}

4.8 接收一字节数据函数

u8 TWI_ReceiveByte(void)

{

u8 i=8;

u8 Data = 0;

TWI_SDA_1();

while(i--)

{

Data <<= 1;

TWI_SCL_0();

Delay(4);

TWI_SCL_1();

Delay(4);

if(TWI_SDA_STATE())

{

Data |= 0x01;

}

}

TWI_SCL_0();

return Data;

}

五 、应用函数

5.1 向从机按地址写数据

u8 TWI_WriteOneByte(u8 DAddr,u8 Addr,u8 Dat)

{

if(!TWI_Start())

return TWI_FAILURE;

TWI_SendByte(DAddr);

TWI_WaitACK();

TWI_SendByte(Addr);

TWI_WaitACK();

TWI_SendByte(Dat);

TWI_WaitACK();

TWI_Stop();

return TWI_SUCCESS;

}

5.2 从从机按地址读数据

u8 TWI_ReadOneByte(u8 Daddr,u8 Addr)

{

u8 Dat;

if(!TWI_Start())

return TWI_FAILURE;

TWI_SendByte(Daddr);

if(!TWI_WaitACK())

{

TWI_Stop();

return TWI_FAILURE;

}

TWI_SendByte(Addr);

TWI_WaitACK();

TWI_Start();

TWI_SendByte(Daddr + 1);

TWI_WaitACK();

Dat = TWI_ReceiveByte();

TWI_SendNACK();

TWI_Stop();

return Dat;

}

5.3 RTC允许设置函数

u8 RTC_WriteTimeOff(void)

{

if(!TWI_WriteOneByte(DEVICE_ADDRESS_WRITE,0x0F,0x0))

{

return TWI_FAILURE;

}

TWI_WriteOneByte(DEVICE_ADDRESS_WRITE,0x10,0x0);

return TWI_SUCCESS;

}

5.4 RTC禁止设置函数

u8 RTC_WriteTimeOff(void)

{

if(!TWI_WriteOneByte(DEVICE_ADDRESS_WRITE,0x0F,0x0))

{

return TWI_FAILURE;

}

TWI_WriteOneByte(DEVICE_ADDRESS_WRITE,0x10,0x0);

return TWI_SUCCESS;

}

5.5 读实时数据寄存器

u8 TWI_ReadDate(S_Time *psRTC)

{

if(!TWI_Start())

return TWI_FAILURE;

TWI_SendByte(DEVICE_ADDRESS_WRITE+1);

if(!TWI_WaitACK())

{

TWI_Stop();

return TWI_FAILURE;

}

psRTC->Second = TWI_ReceiveByte();

TWI_SendACK();

psRTC->Minute = TWI_ReceiveByte();

TWI_SendACK();

psRTC->Hour = TWI_ReceiveByte()&0x7F;

TWI_SendACK();

psRTC->Week = TWI_ReceiveByte();

TWI_SendACK();

psRTC->Day = TWI_ReceiveByte();

TWI_SendACK();

psRTC->Month = TWI_ReceiveByte();

TWI_SendACK();

psRTC->Year = TWI_ReceiveByte();

TWI_SendNACK();

TWI_Stop();

return TWI_SUCCESS;

}

5.6 写实时数据寄存器

u8 TWI_WriteDate(S_Time SetRTC)

{

S_Time *psRTC;

psRTC = &SetRTC;

RTC_WriteTimeOn();

if(!TWI_Start())

return TWI_FAILURE;

TWI_SendByte(DEVICE_ADDRESS_WRITE);

if(!TWI_WaitACK())

{

TWI_Stop();

return TWI_FAILURE;

}

TWI_SendByte(SECOND_REGISTER_ADDRESS);

TWI_WaitACK();

TWI_SendByte(psRTC->Second);

TWI_WaitACK();

TWI_SendByte(psRTC->Minute);

TWI_WaitACK();

TWI_SendByte(psRTC->Hour | 0x80);

TWI_WaitACK();

TWI_SendByte(psRTC->Week);

TWI_WaitACK();

TWI_SendByte(psRTC->Day);

TWI_WaitACK();

TWI_SendByte(psRTC->Month);

TWI_WaitACK();

TWI_SendByte(psRTC->Year);

TWI_WaitACK();

TWI_Stop();

RTC_WriteTimeOff();

return TWI_SUCCESS;

}

六、总结

本文通过STM32F2系列的单片机读写RTC实时时钟芯片SD2405,设计上完全可行,并已在产品上使用。

提醒:《STM32F2系列驱动开发——模拟I2C通信》最后刷新时间 2024-03-14 00:54:11,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《STM32F2系列驱动开发——模拟I2C通信》该内容的真实性请自行鉴别。