06 ADC与I2C应用
上一篇:05 LCD驱动编写
下一篇:07 波形捕获与PWM输出
作者:桂信科黄鹏老师。note部分是我添加的内容
1.ADC 配置,多通道采样
2.I2C驱动代码移植
3.AT24C02 E2PROM应用
4.MCP4017 数字电位器应用
一、模拟输入原理图分析
开发板上一共有三部分电路实现模拟输入。嵌入式中的ADC全名Analog-to-Digital Converter,即模拟-数字转换器,相当于嵌入到单片机里的“电压表”。
IO口 | 模拟输入通道 | 功能 |
---|---|---|
PB15 | ADC2_IN15 | R37可调电阻调压 |
PB12 | ADC1_IN11 | R38可调电阻调压 |
PB14 | ADC1_IN5 | U3数字电阻调压 |
二、CubeMX配置多通道ADC
IN5和IN11都设置为单端输入
由于有两个通道,所以ADC的转换通道数量设置为2
Rank1 中通道设置为 Channel 5
采样周期设置为247.5 Cycles
Rank2 中通道设置为 Channel 11
采样周期设置为247.5 Cycles
注意:采样周期不能设置太小,否则会导致数据错误。
单通道的ADC2_IN15则无需配置,勾上IN15 Single-ended即可。
三、ADC数据读取代码
g_dR37_V,g_dR10_V, g_dR38_V三个变量为三个电阻的分压电压值,可以将这个数值在LCD上显示处理,显示方法参考上一次课的LCD应用内容。
void getAdc(void)
{
uint32_t adc;
HAL_ADC_Start(&hadc2);
HAL_ADC_PollForConversion(&hadc2,2);
adc = HAL_ADC_GetValue(&hadc2);
g_dR37_V = adc*3.3/4096;
HAL_ADC_Stop(&hadc2);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,2);
adc = HAL_ADC_GetValue(&hadc1);
g_dR10_V = adc*3.3/4096;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,2);
adc = HAL_ADC_GetValue(&hadc1);
g_dR38_V = adc*3.3/4096;
HAL_ADC_Stop(&hadc1);
}
四、I2C原理图分析
I2C通信应用于AT24C02数据存储和MCP4017T数字电位器,在PB6和PB7上只能用软件I2C,硬件I2C的引脚是PB7和PB8。
五、CubeMX配置模拟I2C引脚
参照02 CubeMX配置引脚#四、I2C引脚完成该步骤。
六、I2C代码移植
组委会提供的 i2c_hal.c 和 i2c_hal.h 可以直接使用,无需做任何更改,并且驱动代码中使用寄存器方式进行配置,与CubeMX中设置的User Label无关。
七、AT24C02代码编写
AT24C02的代码需要自己编写,编写代码时需要参考数据手册。只需要写两个函数,一个是读数据函数,一个是写数据函数。
设备地址:数据手册P11页 Figure 7
结合原理图可知:读地址为 0xA1,写地址为 0xA0
7.1 读数据函数
参考P12 Figure 11
//根据Random Read写函数
I2CStart();//IIC开始
I2CSendByte(AT_W_ADDR);//发送写地址
I2CWaitAck();//等待ACK
I2CSendByte(address);//发送数据地址
I2CWaitAck();//等待ACK
I2CStart();//IIC开始
I2CSendByte(AT_R_ADDR);//发送读地址
I2CWaitAck();//等待ACK
_bydata = I2CReceiveByte();//读取数据
I2CSendNotAck();//发送NO_ACK
I2CStop();//IIC停止
7.2 写数据函数
参考P12 Figure 11
//根据Byte Write写函数
I2CStart();//IIC开始
I2CSendByte(AT_W_ADDR);//发送写地址
I2CWaitAck();//等待ACK
I2CSendByte(address);//发送数据地址
I2CWaitAck();//等待ACK
I2CSendByte(_bydata);//发送数据
I2CWaitAck();//等待ACK
I2CStop();//IIC停止
7.3 AT24C02应用测试
g_byVal1 = AT24c02_read(0);
AT24c02_write(0, ++g_byVal1);
HAL_Delay(5);
g_byVal2 = AT24c02_read(1);
AT24c02_write(1, ++g_byVal2);
HAL_Delay(5);
g_byVal3 = AT24c02_read(2);
AT24c02_write(2, ++g_byVal3);
八、MCP4017T数字电位器代码编写
驱动方式与AT24C02差不多,同时,编写代码需要参考其数据手册。只需要写两个函数,一个是读电阻值,一个写电阻值。
如原理图和数据手册的功能框图所示,MCP4017的W和B之间相当于数码可调电阻,它与R17串联在一起,测量的是PB14的电压。
由数据手册的P41 、P42所得,MCP4017默认电阻为100kΩ(典型值),档位有0~127个。0表示0欧,127表示100kΩ(相当于要打开的开关位置),所以得出“分辨率”(电阻Rs的阻值)为:100k/127 = 787.4欧姆。
设备地址参考 P36 Figure 5-9
由该图可知,设备读地址为:0x5F;设置写地址为:0x5E。
8.1 读电阻数据函数
参考 P40 Read 1 Byte 时序
步骤:
1)IIC开始 I2CStart();
2)发送读地址 I2CSendByte(MCP_R_ADDR);
3)等待ACK I2CWaitAck();
4) 读取电阻数据 _byResData = I2CReceiveByte();
5)NoACK I2CSendNotAck();
6)IIC停止 I2CStop();
8.2 写电阻数据函数
参考 P40 Write 1 Byte 时序
步骤:
1)IIC开始 I2CStart();
2)发送写地址 I2CSendByte(MCP_W_ADDR);
3)等待ACK I2CWaitAck();
4) 发送电阻数据 I2CSendByte(_byResData);
5)等待ACK I2CWaitAck();
6)IIC停止 I2CStop();
上一篇:05 LCD驱动编写
下一篇:07 波形捕获与PWM输出