摘要
本文章基于国信长天M4开发板,讲述了STM32G431 IIC通信使用步骤,驱动开发板上的24C02存储芯片及可编程电阻MCP4017,祝各位学生蓝桥杯电子比赛取得好成绩!
M4开发板 IIC接口
由上图可以看出,IIC总线使用的是引脚PB6和PB7,总线上挂接了两个设备,分别是存储芯片24C02和可编程电阻MCP4017。
IIC 通信 使用步骤
下面将基于硬件原厂提供的显示屏示例代码:HAL_06_LCD
介绍IIC驱动24C02
和 MCP4017
的使用步骤:
① 新建(或复制) i2c.c
, i2c.h
,并添加到工程
在 工程目录
-> Src
文件夹下,新建文件 i2c.c
, 内容如下:
#include "i2c.h"
#define DELAY_TIME 20
void SDA_Input_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_Output_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_Output( uint16_t val )
{
if ( val )
{
GPIOB->BSRR |= GPIO_PIN_7;
}
else
{
GPIOB->BRR |= GPIO_PIN_7;
}
}
void SCL_Output( uint16_t val )
{
if ( val )
{
GPIOB->BSRR |= GPIO_PIN_6;
}
else
{
GPIOB->BRR |= GPIO_PIN_6;
}
}
uint8_t SDA_Input(void)
{
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
return 1;
}else{
return 0;
}
}
static void delay1(unsigned int n)
{
uint32_t i;
for ( i = 0; i < n; ++i);
}
void I2CStart(void)
{
SDA_Output(1);
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
SDA_Output(0);
delay1(DELAY_TIME);
SCL_Output(0);
delay1(DELAY_TIME);
}
void I2CStop(void)
{
SCL_Output(0);
delay1(DELAY_TIME);
SDA_Output(0);
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
SDA_Output(1);
delay1(DELAY_TIME);
}
unsigned char I2CWaitAck(void)
{
unsigned short cErrTime = 5;
SDA_Input_Mode();
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
while(SDA_Input())
{
cErrTime--;
delay1(DELAY_TIME);
if (0 == cErrTime)
{
SDA_Output_Mode();
I2CStop();
return ERROR;
}
}
SDA_Output_Mode();
SCL_Output(0);
delay1(DELAY_TIME);
return SUCCESS;
}
void I2CSendAck(void)
{
SDA_Output(0);
delay1(DELAY_TIME);
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
SCL_Output(0);
delay1(DELAY_TIME);
}
void I2CSendNotAck(void)
{
SDA_Output(1);
delay1(DELAY_TIME);
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
SCL_Output(0);
delay1(DELAY_TIME);
}
void I2CSendByte(unsigned char cSendByte)
{
unsigned char i = 8;
while (i--)
{
SCL_Output(0);
delay1(DELAY_TIME);
SDA_Output(cSendByte & 0x80);
delay1(DELAY_TIME);
cSendByte += cSendByte;
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
}
SCL_Output(0);
delay1(DELAY_TIME);
}
unsigned char I2CReceiveByte(void)
{
unsigned char i = 8;
unsigned char cR_Byte = 0;
SDA_Input_Mode();
while (i--)
{
cR_Byte += cR_Byte;
SCL_Output(0);
delay1(DELAY_TIME);
delay1(DELAY_TIME);
SCL_Output(1);
delay1(DELAY_TIME);
cR_Byte |= SDA_Input();
}
SCL_Output(0);
delay1(DELAY_TIME);
SDA_Output_Mode();
return cR_Byte;
}
void I2CInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_6;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
在 工程目录
-> Inc
文件夹下,新建文件 i2c.h
, 内容如下:
#ifndef __I2C_H
#define __I2C_H
#include "main.h"
void I2CStart(void);
void I2CStop(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(void);
void I2CSendNotAck(void);
void I2CSendByte(unsigned char cSendByte);
unsigned char I2CReceiveByte(void);
void I2CInit(void);
#endif
双击Keil 开发环境里面的 Application/User
, 打开添加文件对话框,在向上一级
-> Src
中,找到i2c.c
并添加。添加后如下图所示:
② main.c
添加 #include "i2c.h"
在 main.c
适当位置添加 #include "i2c.h"
,添加后如下图所示:
③ 复制24C02 读写代码
将下列代码复制到main.c
的适当位置
//从24C02中读取数据
uint8_t x24c02_read(uint8_t address)
{
unsigned char val;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
val = I2CReceiveByte();
I2CSendNotAck();
I2CStop();
return(val);
}
//向24C02写数据
void x24c02_write(unsigned char address,unsigned char info)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CSendByte(info);
I2CWaitAck();
I2CStop();
}
④ 复制MCP4017 读写程序
将下列代码复制到main.c
的适当位置
//设置可变电阻当前的阻值
void write_resistor(uint8_t value)
{
I2CStart();
I2CSendByte(0x5E);
I2CWaitAck();
I2CSendByte(value);
I2CWaitAck();
I2CStop();
}
//读取可变电阻当前的阻值
uint8_t read_resistor(void)
{
uint8_t value;
I2CStart();
I2CSendByte(0x5F);
I2CWaitAck();
value = I2CReceiveByte();
I2CSendNotAck();
I2CStop();
return value;
}
⑤在main()
中调用 I2CInit()
如下图所示,在main()
函数的适当位置调用 I2CInit();
⑥ 读写24C02芯片内部的数据
uint8_t val = 0;
val = x24c02_read(0); //读取24C02 0地址的数据
x24c02_write(0, val); //向24C02 0 地址写入数据
⑦ 读取/设置MCP4017的电阻值
uint8_t val = 0;
val = read_resistor(); //读取电阻值,真实电阻值要 * 0.7874
write_resistor(20); //设置电阻值为 0.7874 * 20 K
总结
IIC 驱动 24C02和MCP4017 步骤总结如下:
- 创建
i2c.c
,i2c.h
文件,并添加到工程中 main.c
中添加#include "i2c.h"
- 复制
24C02
及MCP4017
的控制代码到main.c
; - 在主函数中调用
I2CInit();
- 读写/控制 24C02 与 MCP4017
如果此文章对你有帮助,欢迎点赞
关注
收藏
转发
.
我是鹏老师