PB15----ADC2_IN15,建议改标签为R37
PB12----ADC1_IN11,建议改标签为R38
PB14-----ADC1_IN5,改标签MCP
将通道单使能(single ended)
MCP4017 的功能:
MCP4017 是一种可编程电阻器,通过 I2C 总线可以控制其内部电阻网络的阻值。
它内部有一个电阻网络,通过模拟开关选择不同的电阻值。
其引脚 W(6 引脚)和 B(5 引脚)之间形成一个可变电阻,W 引脚通常连接到一个外部电阻(如 10kΩ),形成一个分压电路。
分压电路:
W 引脚(6 引脚)连接到一个外部电阻(如 10kΩ),B 引脚(5 引脚)接地。
当 STM32 通过 I2C 向 MCP4017 写入值时,MCP4017 会调整 W 和 B 之间的电阻值(RWB)。
PB14 引脚连接到 W 引脚,用于测量分压后的电压值。
分压公式:
分压公式为:
VPB14=VCC×RWB+R17RWB其中:
VCC 是电源电压(如 3.3V)。
RWB 是 W 和 B 之间的电阻值,由 MCP4017 内部调整。
R17 是外部固定电阻(如 10kΩ)。
ADC1的转换数量(number of conversion)设置为2
rank2设为通道11,采样周期(sampling time)改最大
完成
在文件夹中加入i2c头文件源文件,在自建头文件中声明i2c头文件
补充lcd_proc
else if(ui == adc_ui)
{
if((uwTick-lcd_Tick)<100)
return;
lcd_Tick=uwTick;
sprintf(lcd_buf," ADC_test ");
LCD_DisplayStringLine(Line0,(u8*)lcd_buf);
sprintf(lcd_buf," R37_adc:%.2f ",r37_volt);
LCD_DisplayStringLine(Line2,(u8*)lcd_buf);
sprintf(lcd_buf," R38_:%.2f ",r38_volt);
LCD_DisplayStringLine(Line3,(u8*)lcd_buf);
sprintf(lcd_buf," MCP_volt:%.2f ",mcp_volt);
LCD_DisplayStringLine(Line4,(u8*)lcd_buf);
补充led_proc
if(ui!=frq_ui)
led_num = 0;
led_disp(led_num);
编写adc函数
float mcp_volt,r38_volt,r37_volt;
u16 mcp_value,r37_value,r38_value;
u32 adc_Tick;
void adc_proc()
{
if((uwTick-adc_Tick)<100)
return;
adc_Tick=uwTick;
HAL_ADC_Start(&hadc1);
mcp_value=HAL_ADC_GetValue(&hadc1);
HAL_ADC_Start(&hadc1);
r38_value=HAL_ADC_GetValue(&hadc1);
HAL_ADC_Start(&hadc2);
r37_value=HAL_ADC_GetValue(&hadc2);
mcp_volt = 3.3*mcp_value/4096.0;
r37_volt = 3.3*r37_value/4096.0;
r38_volt = 3.3*r38_value/4096.0;
}
声明函数
adc读取到的值的顺序是按rank的顺序
volt需要外部声明,因为lcd要调用他们
若显示出现问题,将value的变量类型改为u32
void mcp_write(u8 mcp)
{
I2CStart();
I2CSendByte(0x5e);
I2CWaitAck();
I2CSendByte(mcp);
I2CWaitAck();
I2CStop();
}
地址为0x5e,与eeprom不同
记得初始化
I2CInit();
如此一来,向mcp写值即可改变mcp_volt的值
显示mcp_num的值,先声明
float mcp_num;
//然后在lcd的adcui中添加这个显示
LCD_SetTextColor(Green);
sprintf(lcd_buf," MCP_value:%.f ",mcp_num);
LCD_DisplayStringLine(Line8,(u8*)lcd_buf);
LCD_SetTextColor(White);
else if(ui == adc_ui)
{
if(key_down==1)
{
ui = pwm_ui;
LCD_Clear(Black);
}
else if(key_down==2) //复位
{
if(mcp_num!=127)
mcp_num = 127;
else
mcp_num = 0;
}
else if(key_up==3) //
{
mcp_num++;
if(mcp_num>127)
mcp_num=127;
}
else if(key_up==4)
{
mcp_num--;
if(mcp_num>127)
mcp_num = 0;
}
else if(key_down == 3||key_down == 4) //下降时开始计时
{
key_long_tick = uwTick;
}
if(uwTick-key_long_tick>800 && key_value == 3) //长按按键三时mcp自增,长按时keyvalue恒为3
{
mcp_num++;
if(mcp_num>127)
mcp_num=127;
}
if(uwTick-key_long_tick>800 && key_value == 4)
{
mcp_num--;
if(mcp_num>127)
mcp_num=0;
}
}
在长按的这里,最好再加上一个标志来区分是否在长按,然后在key_up的时候判断,是否是长按状态还是短按状态,如果是短按的话就是写短按的要求,否则就将标志位设置为短按状态,在key_value == 4 && (uwTick - long_pressed)>800的时候就写长按的要求,并将标志位设置为长按,这样在松手的时候,就不会被扫到key_up了,不然视频中,还是会在长按完后触发短按的条件