一、硬件框图
二、功能描述
1.1基本功能
1) 测量竞赛板上电位器 R37 输出的模拟电压信号 VR37,并通过液晶屏实现数据展示。
2) 通过 LED 指示灯实现超出上限、低于下限的提醒功能。
3) 通过按键实现阈值范围和输出提醒指示灯的设置功能。
4) 通过 E2PROM 实现参数的断电存储功能。
1.2显示功能
1) 数据显示界面
数据显示界面包含三个显示要素:界面名称、采集的实时电压数据和状态。
备注:
1.上述界面供设计参考,选手可根据试题要求对界面进行设计,界面需包含试题要求的全部显示要素 。
2.
电压单位为伏特,数据保留小数点后两位有效数字。
3.
状态(Status):超过上限(Upper)、低于下限(Lower)和正常(Normal)。
2) 参数配置界面
参数配置界面包含五个显示要素:界面名称、电压的上限值、电压的下限值、电压超过上限的提醒指示灯、电压低于下限的提醒指示灯。
备注:
1.上述界面供设计参考,选手可根据试题要求对界面进行设计,界面需包含试题要求的全部显示要素 。
2.
电压上、下限值设置范围为 0-3.3V,设备应具备错误设置的保护功能。
3.
电压提醒指示灯设置范围为 LD1 到 LD8,设备应禁止将上、下限指示灯设置为同一个指示灯
1.3按键功能
1) B1:定义为“设置”按键,按下此按键,切换选择数据显示界面和参数设置界面,按键工作流程如下图所示:
备注
:从参数设置界面退出,返回到数据显示界面时,将参数保存到 E2PROM
存储器。
2) B2:定义为“选择”按键,在参数设置界面按下此按键,切换选择参数项(电压的上限值、电压的下限值、电压超过上限的提醒指示灯、低于下限的提醒指示灯),被选择的参数项“高亮”显示。
按键工作流程如下图所示:
3) B3:定义为“加”按键。
进行电压参数设置时,当前选择的电压参数加 0.3V。
进行 LED 提醒指示灯参数设置时,LED 指示灯序号加 1。
4) B4:定义为“减”按键。
进行电压参数设置时,当前选择的电压参数减 0.3V。
进行 LED 提醒指示灯参数设置时,LED 指示灯序号减 1。
备注:
1.B2、B3、B4 仅在设置界面下有效。
2.
参数设置功能需保护数据边界,电压参数可设置范围 0-3.3V,LED提醒指示灯可设置范围 LD1-LD8。
1.4 LED 指示灯功能
1) R37 输出电压值超过电压上限值时(V
R37
>V
上限
),上限提醒指示灯以 0.2 秒为间隔闪烁,下限指示灯熄灭。
2) R37 输出电压值低于电压下限值时(V
R37
<V
下限
),下限提醒指示灯以 0.2 秒为间隔闪烁,上限指示灯熄灭。
3) R37 输出电压值介于上限和下限电压之间时(V
下限
≤V
R37
≤V
上限
),上限、下限提醒指示灯熄灭。
4) 竞赛板上除当前用做超出上限、低于下限提醒功能的指示灯外,其它指示灯应处于熄灭状态。
3.5初始状态说明
1) 设备重新上电时,应从 E2PROM 中载入上、下限提醒指示灯、上限电压、下限电压参数。
2) 默认输出提醒指示灯。
超过上限提醒指示灯:LD1
低于下限提醒指示灯:LD2
3) 默认电压阈值参数。
电压的上限值:2.4V
电压的下限值:1.2V
三、模块代码实现
1、STM32CubeMX引脚配置
各个模块代码和配置在下面几节有,就不贴出来了。
第六届蓝桥杯嵌入式开发经验分享(决赛—电压测量与互补 PWM 信号输出)-CSDN博客
第六届蓝桥杯嵌入式开发(省赛—电压测量监控设备)-CSDN博客
第七届蓝桥杯嵌入式开发(省赛—模拟液位检测告警系统)-CSDN博客
第八届蓝桥杯嵌入式开发(省赛—模拟升降控制器)_蓝桥杯第8届嵌入式-CSDN博客
2、功能实现
(1)显示功能
显示功能分为数据显示界面和数据设置界面
void show(void)
{
//设置界面
if(set == 1)
{
LCD_DisplayStringLine(Line1,(uint8_t *)" Setting ");
char text[30];
if(select == 0)
{
LCD_SetBackColor(Green);
sprintf(text," Max Volt: %.1fV ",max);
LCD_DisplayStringLine(Line2,(uint8_t *)text);
LCD_SetBackColor(White);
}
else
{
sprintf(text," Max Volt: %.1fV ",max);
LCD_DisplayStringLine(Line2,(uint8_t *)text);
}
if(select == 1)
{
LCD_SetBackColor(Green);
sprintf(text," Min Volt: %.1fV ",min);
LCD_DisplayStringLine(Line3,(uint8_t *)text);
LCD_SetBackColor(White);
}
else
{
sprintf(text," Min Volt: %.1fV ",min);
LCD_DisplayStringLine(Line3,(uint8_t *)text);
}
if(select == 2)
{
LCD_SetBackColor(Green);
sprintf(text," Upper: %s ", LED[led_upper]);
LCD_DisplayStringLine(Line4,(uint8_t *)text);
LCD_SetBackColor(White);
}
else
{
sprintf(text," Upper: %s ", LED[led_upper]);
LCD_DisplayStringLine(Line4,(uint8_t *)text);
}
if(select == 3)
{
LCD_SetBackColor(Green);
sprintf(text," Lower: %s ", LED[led_lower]);
LCD_DisplayStringLine(Line5,(uint8_t *)text);
LCD_SetBackColor(White);
}
else
{
sprintf(text," Lower: %s ", LED[led_lower]);
LCD_DisplayStringLine(Line5,(uint8_t *)text);
}
}
else//显示界面
{
char text[30];
LCD_DisplayStringLine(Line1,(uint8_t *)" Main ");
led_n = 0;
double VR37 = getADC(&hadc2);
if(VR37 > max)
{
led_code(led_upper);
up = true;
sta = 0;
}
else if(VR37 < min)
{
led_code(led_lower);
low = true;
sta = 1;
}
else
{
low = false;
up = false;
sta = 2;
LED_Display(0);
}
sprintf(text," Volt: %.2fV ",VR37);
LCD_DisplayStringLine(Line3,(uint8_t *)text);
sprintf(text," Status: %s ", Status[sta]);
LCD_DisplayStringLine(Line4,(uint8_t *)text);
}
}
(2)按键功能
void key_proc(void)
{
if(key[0].key_flag)
{
key[0].key_flag = false;
set = !set;
LCD_Clear(White);
//保存数据
if(set==0)
{
eeprom_write(0,led_upper);//上限指示灯
HAL_Delay(10);
eeprom_write(1,led_lower);//下限指示灯
HAL_Delay(10);
eeprom_write(2,max*10);//上限电压
HAL_Delay(10);
eeprom_write(3,min*10);//下限电压
HAL_Delay(10);
}
}
if(set == 1)
{
//B2
if(key[1].key_flag)
{
key[1].key_flag = false;
if(++select >= 4) select = 0;
}
//B3
if(key[2].key_flag)
{
key[2].key_flag = false;
switch(select)
{
case 0:
{
max += 0.3;
if(max > 3.3) max = 3.3;
}
break;
case 1:
{
min += 0.3;
if(max < min)
{
min = max;
}
if(min > 3.3) min = 3.3;
}
break;
case 2:
{
if(++led_upper > 7)led_upper = 0;
if(led_upper == led_lower)
{
led_upper++;
if(led_lower>=7) led_upper=0;
}
}
break;
case 3:
{
if(++led_lower>7)led_lower = 0;
if(led_upper == led_lower)
{
led_lower++;
if(led_upper>=7) led_lower=0;
}
}
break;
}
}
//B4
if(key[3].key_flag)
{
key[3].key_flag = false;
switch(select)
{
case 0:
{
max -= 0.3;
if(max < 0.0) max = 0.0;
}
break;
case 1:
{
min -= 0.3;
if(max < min)
{
min = max;
}
if(min < 0.0) min = 0.0;
}
break;
case 2:
{
if(--led_upper < 0)led_upper = 7;
if(led_upper == led_lower)
{
led_upper--;
if(led_lower <= 0) led_upper=7;
}
}
break;
case 3:
{
if(--led_lower < 0)led_lower = 7;
if(led_upper == led_lower)
{
led_lower--;
if(led_upper <= 0) led_lower=7;
}
}
break;
}
}
}
else
{
key[1].key_flag = false;
key[2].key_flag = false;
key[3].key_flag = false;
}
}
(3)LED 指示灯功能
//获取ADC后做判断
double VR37 = getADC(&hadc2);
if(VR37 > max)
{
led_code(led_upper);
up = true;
sta = 0;
}
else if(VR37 < min)
{
led_code(led_lower);
low = true;
sta = 1;
}
else
{
low = false;
up = false;
sta = 2;
LED_Display(0);
}
}
3、main函数
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC2_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim4);
LCD_Init();
I2CInit();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Clear(White);
LCD_SetBackColor(White);
LCD_SetTextColor(Blue2);
LED_Display(0);
led_upper = eeprom_read(0); //上限指示灯
led_lower = eeprom_read(1); //下限指示灯
max = eeprom_read(2)/10.0; //上限电压
min = eeprom_read(3)/10.0; //下限电压
while (1)
{
key_proc();
show();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
有不对或不恰当的地方,请您批评指正,主打一个听劝;也可以一起讨论讨论,互相学习,共同进步,比心比心。