(ADC)ADC,MCP,长按

引脚配置

(ADC)ADC,MCP,长按_第1张图片

PB15----ADC2_IN15,建议改标签为R37

PB12----ADC1_IN11,建议改标签为R38

PB14-----ADC1_IN5,改标签MCP

将通道单使能(single ended)

知识点

  1. MCP4017 的功能:

    • MCP4017 是一种可编程电阻器,通过 I2C 总线可以控制其内部电阻网络的阻值。

    • 它内部有一个电阻网络,通过模拟开关选择不同的电阻值。

    • 其引脚 W(6 引脚)和 B(5 引脚)之间形成一个可变电阻,W 引脚通常连接到一个外部电阻(如 10kΩ),形成一个分压电路。

  2. 分压电路:

    • W 引脚(6 引脚)连接到一个外部电阻(如 10kΩ),B 引脚(5 引脚)接地。

    • 当 STM32 通过 I2C 向 MCP4017 写入值时,MCP4017 会调整 W 和 B 之间的电阻值(RWB)。

    • PB14 引脚连接到 W 引脚,用于测量分压后的电压值。

  3. 分压公式:

    • 分压公式为:

      VPB14​=VCC​×RWB​+R17​RWB​​

      其中:

      • VCC​ 是电源电压(如 3.3V)。

      • RWB​ 是 W 和 B 之间的电阻值,由 MCP4017 内部调整。

      • R17​ 是外部固定电阻(如 10kΩ)。

 

参数配置

ADC1的转换数量(number of conversion)设置为2

rank2设为通道11,采样周期(sampling time)改最大

完成

ADC

在文件夹中加入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

MCP

 

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了,不然视频中,还是会在长按完后触发短按的条件

 

你可能感兴趣的:(蓝桥杯笔记,c语言,stm32,蓝桥杯)