文章目录
前言
串口通信与I2C通信一直是历届蓝桥杯嵌入式程序设计的重要考点.
- 串口通信的考点为不定长数据的接收与处理.
- I2C通信的考点为读写eeprom与数字电位器.
一.串口通信
1.串口通信的基本操作
串口通信的基本操作为:
- 打开串口接收与串口发送
- 在cubemx中进行串口相关的配置
- 初始化时打开串口接收至空闲中断
- 在中断回调函数中进行数据处理,串口发送等工作的代码书写
2.CubeMx中的配置
常规配置如下所示:
然后我们打开串口收发的DMA模式.
最后别忘了到NVIC控制器中使能串口中断并将其抢占优先级拉满.
3.串口收发的代码书写
//设置接收/发送缓存器
char uart_rx[50]=" " ;
char uart_tx[50]="" ;
//在while前打开串口接收至空闲中断,且用的是DMA模式
//第一个参数填入串口的操作句柄
//第二个参数填入接收缓存区的首地址
//第三个参数填入接收缓存区的大小(最大接收限度)
//注:当接收一半或接收至空闲时,都会触发接收事件回调中断
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,(uint8_t*)uart_rx,sizeof(uart_rx));
//重定义接收事件回调中断函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
//首先判断是否是串口1触发的中断
if(huart->Instance==USART1)
{
//数据处理部分
//串口发送
//第一个参数填入串口的操作句柄
//第二个参数填入发送缓存区的大小
//第三个参数填入发送内容的大小(不含任何的'\0')
HAL_UART_Transmit_DMA(&huart1,(uint8_t*)uart_tx,strlen(uart_tx));
//接收缓存区清零以用于下次接收
for (u8 i=0;i<sizeof(uart_rx);i++)
{
uart_rx[i] = '\0';
}
//再次打开串口接收至空闲中断
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,(uint8_t*)uart_rx,sizeof(uart_rx));
}
}
二.I2C通信
1.I2C通信的基本操作
由于官方提供了软件I2C的示例代码,因此我们只需找到eeprom和数字电位器的手册打开找到时序图部分,看着时序图书写我们的读/写函数即可.
eeprom通信地址的确定
AT24C02在I2C通信中的地址.
其中A2-A0对应E3-E1,都是0,最后一位(LSB)是读写控制位.
查阅AT24C02的文档后得知最后一位为1是读取eeprom,为0则是写入eeprom.
由此可以确定板载的eeprom的I2C通信地址为1010_000x,写的时候是0xa0,读的时候是0xa1.
数字电位器通信地址的确定
由文档可知,数字电位器的I2C通信地址为0x5e(写)或0x5f(读).
数字电位器的原理
我们通过I2C写入的操作,控制R_WB的电阻,从而控制R_WB两端的电压值.计算公式为:
上式中的R_AB是标称值.
其可以是5千欧,10千欧,50千欧和100千欧.
I2C示例工程移植
将此处的.h/.c文件移植入bsp内即可.
2.根据时序图书写对应外设的读写函数
AT24C02的写时序图
//i2c_hal.h文件中声明该函数
void Write_AT24C02(uint8_t addr,uint8_t data);
//i2c_hal.c文件中定义该函数
void Write_AT24C02(uint8_t addr,uint8_t data)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
AT24C02的读时序图
//i2c_hal.h文件中声明该函数
uint8_t Read_AT24C02(uint8_t addr);
//i2c_hal.c文件中定义该函数
uint8_t Read_AT24C02(uint8_t addr)
{
uint8_t data;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
data = I2CReceiveByte();
I2CSendNotAck();
I2CStop();
return data;
}
MCP4017的写时序图
//i2c_hal.h文件中声明该函数
void Write_MCP4017(uint8_t data);
//i2c_hal.c文件中定义该函数
void Write_MCP4017(uint8_t data)
{
I2CStart();
I2CSendByte(0x5e);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}