你是一名程序员,现在要用stm32f103ze给超声波模块GY_US42改IIC地址,并能够在串口调试助手查看模块的IIC地址,要求使用标准库写一份完整的代码,,完整代码包含IIC发送和接收函数,更改地址函数,mian函数,串口相关函数
时间: 2023-06-20 12:07:50 浏览: 117
STM32模拟IIC与IIC四种实现实现数字光强采集模块GY30(标准库与HAL库)
5星 · 资源好评率100%
好的,以下是我写的完整代码:
```c
#include "stm32f10x.h"
#include "stdio.h"
#define GY_US42_ADDR 0xE0 // GY-US42默认IIC地址
#define NEW_ADDR 0xE2 // 要改为的新IIC地址
void I2C_GPIO_Config(void);
void I2C_Config(void);
void I2C_SendByte(uint8_t addr, uint8_t data);
uint8_t I2C_ReadByte(uint8_t addr);
void GY_US42_SetAddr(uint8_t newAddr);
void USART1_Config(void);
void USART1_SendChar(char c);
void USART1_SendString(char* str);
void delay_ms(uint32_t ms);
int main(void)
{
SystemInit();
I2C_GPIO_Config();
I2C_Config();
USART1_Config();
GY_US42_SetAddr(NEW_ADDR); // 改变GY-US42的IIC地址为NEW_ADDR
while (1)
{
uint8_t addr = I2C_ReadByte(GY_US42_ADDR); // 读取GY-US42的IIC地址
char buf[20];
sprintf(buf, "IIC Addr: 0x%x\r\n", addr);
USART1_SendString(buf);
delay_ms(1000);
}
}
void I2C_GPIO_Config(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_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2C_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
void I2C_SendByte(uint8_t addr, uint8_t data)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
uint8_t I2C_ReadByte(uint8_t addr)
{
uint8_t data;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
data = I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
return data;
}
void GY_US42_SetAddr(uint8_t newAddr)
{
I2C_SendByte(GY_US42_ADDR, 0xA0);
I2C_SendByte(GY_US42_ADDR, 0xAA);
I2C_SendByte(GY_US42_ADDR, 0xA5);
I2C_SendByte(GY_US42_ADDR, newAddr);
}
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void USART1_SendChar(char c)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, c);
}
void USART1_SendString(char* str)
{
while (*str)
{
USART1_SendChar(*str++);
}
}
void delay_ms(uint32_t ms)
{
SysTick->LOAD = 72000 - 1;
SysTick->CTRL = 0x05;
for (uint32_t i = 0; i < ms; i++)
{
while (!(SysTick->CTRL & 0x10000));
}
SysTick->CTRL = 0x00;
}
```
其中,`I2C_GPIO_Config`和`I2C_Config`函数负责配置IIC总线,`I2C_SendByte`和`I2C_ReadByte`函数分别用于发送和接收IIC数据,`GY_US42_SetAddr`函数用于更改GY-US42的IIC地址,`USART1_Config`函数用于配置串口,`USART1_SendChar`和`USART1_SendString`函数分别用于发送单个字符和字符串,`delay_ms`函数用于延时。
在`main`函数中,首先进行各种配置,然后调用`GY_US42_SetAddr`函数将GY-US42的IIC地址更改为`NEW_ADDR`,然后进入一个死循环,每隔一秒读取一次GY-US42的IIC地址并通过串口输出。
阅读全文