一、开发板资源介绍
STM32 ADC是12为逐次比较型,多达18个通道,可测量16个外部和2个内部信号源,各通道的转换可以单次、连续、扫描或间断模式执行,转换结果可以左对齐或右对齐方式存储在16为数据寄存器中。
ADC使用引脚如下图所示,其中红色框里的是竞赛题目中用到的引脚。注意左侧一栏为ADC1的引脚通道,右侧为ADC2的引脚通道。
开发板上有4个电位器,其中R37和R38作用是模拟电压输出,与ADC模拟输入通道连接,即我们可以使用开发板上的通过测量由电位器R37和P38调节的电压大小。
4个电位器的位置如图所示。
到这里我们了解到,电位器R37与PB15相连,使用ADC2通道15;R38与PB12相连,使用ADC1通道11;MCP4017与PB14相连,使用ADC1通道5。
那么这个MCP4017是什么呢?
MCP4017为可编程电阻。使用I2C通讯协议,引脚为PB6,PB7 ,控制的电阻连接PB14。
MCP4017的默认总阻值为100kΩ ,对应0-127个档位,当寄存器为0时,阻值为0;
当寄存器为0x7F时阻值为100k。
也就是说我们可以通过编程控制MCP4017的阻值,进而控制输出电压的大小,然后可由相连的PB14引脚ADC1通道5测量验证。
二、配置工程
1、配置引脚
电位器R37与PB15相连,使用ADC2通道15
R38与PB12相连,使用ADC1通道11;MCP4017与PB14相连,使用ADC1通道5
2、添加文件
赛点资料包里的底层驱动代码文件夹下的i2c_hal.c i2c_hal.h添加到工程里
将以上.c.h复制到工程下对应文件夹中
在KEIL中将.c文件添加进来
别忘了在main.c中添加.h文件以及初始化函数。
三、真题小练习
要求: 使用按键B1通过I2C接口改变MCP4017的阻值,从而改变ADC1-IN15的输入电压,用R38改变ADC1-IN11的输入电压,R37改变ADC2-IN15的输入电压。
用ADC1采集两路电压进行AD转换,用ADC2采集一路电压进行AD转换,转换结果显示在LCD上。
该工程代码可在优快云资源下载 |
1.在main.c中用户添加变量区内设置变量
uint8_t ucLcd[21];
uint8_t ucKEY,ucKEYLong;
uint8_t ucADCTime;//测量时间
uint16_t usAdc[3];//测量结果
uint8_t ucMCP = 0x0f;//电阻阻值
uint8_t ucLCD[21];
float VR37,VR38,VM4017;
uint8_t ucMcp = 0x0f; //MCP值
2.在main.c中用户添加代码区添加以下代码
ADC校准
/*ADC校准,放在初始化里*/
void ADC_Init(void)
{
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
}
ADC功能函数,测量电压值
/*在while中调用*/
void ADC_Proc(void)
{
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK)
VR38 = HAL_ADC_GetValue(&hadc1)*3.3/4095; //测量R38
if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK)
VM4017 = HAL_ADC_GetValue(&hadc1)*3.3/4095; //测量MCP4017
HAL_ADC_Start(&hadc2);
if(HAL_ADC_PollForConversion(&hadc2,10) == HAL_OK)
VR37 = HAL_ADC_GetValue(&hadc2)*3.3/4095; //测量R37
}
通过I2C改变MCP4017的阻值
void MCP_WD(uint8_t value)
{
I2CStart();
I2CSendByte(0x5e);
I2CWaitAck();
I2CSendByte(value);
I2CWaitAck();
I2CStop();
}
按键功能函数
/*通过按键B1改变MCP4017的阻值*/
void KEY_Proc()
{
if(!HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin))
{
HAL_Delay(10);
if(!HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin))
ucKEY =1;
}
if(ucKEY != ucKEYLong)
ucKEYLong = ucKEY;
else
ucKEY = 0;
if(ucKEY == 1)
{
ucMCP += 0x10;
if(ucMCP == 0x8f)//这里的值可以自己设定
ucMCP = 0x0f;
MCP_WD(ucMCP);
}
}
LCD显示函数
void LCD_Proc(void)
{
sprintf((char *)ucLCD,"R37:%.2f B1:%03X",VR37,ucMcp);
LCD_DisplayStringLine(Line4,ucLCD);
sprintf((char *)ucLCD,"R38:%.2f MCP:%.2f",VR38,VM4017);
LCD_DisplayStringLine(Line5,ucLCD);
}
3.在while里调用
在这里有一些学习资料建议,欢迎批评指正【蓝桥杯嵌入式组】HAL库STM32CubeMx学习笔记汇总:学习建议及资料