蓝桥杯嵌入式第十届省赛电压检测仪工程
感受
这套题就显得非常地常规了,完全可以新手入门。有个规律:如果一套题出的非常的连贯,比如第8届,前面做不出来,后面一样做不出来。但第十届就可以说不怎么系统,当然这也有好处,那就是容易打分(按键,LCD,ADC,LED分平行模块打分),如果太过于系统化和整体,就需要检查作品的人酌情打分了。
工程:
链接:https://pan.baidu.com/s/1ro0HqSMNh2sqBkFOq-DRQQ
提取码:yzh1
主要代码
#include "work.h"
#include "usart.h"
typedef struct key
{
u16 keytime;
u8 keystate;
bool state;
bool sflag;
bool lflag;
}Keys;
Keys keys[4] ={0};
#define ReadB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define ReadB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define ReadB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define ReadB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
u8 LEDDT[3]={0};
u8 LEDINDEX[10]={0X00,0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};
static u8 choice = 0 ; //电压上限,电压下限,上限LED,下限LED
bool view =1;
u8 upled =1;
u8 downled=2;
float upval = 2.4f;
float downval = 1.2f;
float val = 0.0f;
u16 ledflasht =0;
u8 valstate = 0;//当前电压状态
u8 adct=0;
__IO u16 adcbuf[3]={0};
void keyscan(){
keys[0].state =ReadB1;
keys[1].state =ReadB2;
keys[2].state =ReadB3;
keys[3].state =ReadB4;
for(int i =0 ;i <4; i++)
{
switch(keys[i].keystate)
{
case 0:
if(!keys[i].state)keys[i].keystate=1;
break;
case 1:
if(!keys[i].state)keys[i].keystate=2;
else keys[i].keystate=0;
break;
case 2:
if(!keys[i].state)
{
keys[i].keytime+=10;
}
else
{
keys[i].sflag=1;
keys[i].keytime=0;
keys[i].keystate = 0;
}
break;
}
}
}
void keyaction()
{
if(keys[0].sflag){ //切换界面
keys[0].sflag=0;
view=!view;
LCD_Clear(Black);
}
else if(keys[1].sflag){ //设置
keys[1].sflag=0;
if(!view)
{
choice++;
choice =choice%4;
}
}
else if(keys[2].sflag){ //加
keys[2].sflag=0;
if(!view)
{
switch(choice)
{
case 0:
upval+=0.3f;
if(upval > 3.3f)upval =3.3f;
break;
case 1:
downval+=0.3f;
if(downval > 3.3f)downval =3.3f;
break;
case 2:{
u8 temp =upled;
if(++upled == 9) upled =1;
if(upled == downled) upled = temp;
}
break;
case 3:
{
u8 temp =downled;
if(++downled == 9) downled =1;
if(upled == downled) downled = temp;
}
break;
}
}
}
else if(keys[3].sflag){
keys[3].sflag=0;
if(!view)
{
switch(choice)
{
case 0:
upval-=0.3f;
if(upval <= 0.0f)upval =0.0f;
break;
case 1:
downval-=0.3f;
if(downval <= 0.0f)downval = 0.0f;
break;
case 2:{
u8 temp =upled;
if(--upled == 0) upled =8;
if(upled == downled) upled = temp;
}
break;
case 3:
{
u8 temp =downled;
if(--downled == 0) downled =8;
if(upled == downled) downled = temp;
}
break;
}
}
}
}
void Led_disPlay(u8 ds)
{
HAL_GPIO_WritePin(GPIOC,0XFF<<8,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,ds<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
int fputc(int ch,FILE * F)
{
HAL_UART_Transmit(&huart1,(u8*)&ch,1,0xffff);
return ch;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2) //10MS
{
keyscan();
keyaction();
}
else if(htim->Instance == TIM4)
{
adct++;
if(valstate==1) //上限指示灯闪烁
{
if(ledflasht++ >= 200){
ledflasht=0;
LEDDT[1]= LEDDT[1]==upled?0:upled;
}
}
else if(valstate ==2)
{
if(ledflasht++ >= 200){
ledflasht=0;
LEDDT[2]= LEDDT[2]==downled?0:downled;
}
}
}
}
void LcdDisplay(void)
{
char temp[50]={0};
if(view) //数据显示界面
{
LCD_DisplayStringLine( Line1, (u8*)(" Main "));
sprintf(temp," Volt:%.2fV ",val);
LCD_DisplayStringLine( Line2, (u8*)temp);
if(valstate == 0) //normal
{
LCD_DisplayStringLine( Line3, (u8*)" Status:Normal ");
}
else if(valstate == 1){ //upper
LCD_DisplayStringLine( Line3, (u8*)" Status:Upper ");
}
else if(valstate == 2) //Lower
{
LCD_DisplayStringLine( Line3, (u8*)" Status:Lower ");
}
LCD_DisplayStringLine( Line4, (u8*)" ");
LCD_DisplayStringLine( Line5, (u8*)" ");
}
else //设置界面
{
LCD_DisplayStringLine( Line1, (u8*)(" Setting "));
sprintf(temp," Max Volt:%.2fV ",upval);
if(choice ==0) LCD_SetBackColor(Green);
LCD_DisplayStringLine( Line2, (u8*)temp);
LCD_SetBackColor(Black);
sprintf(temp," Min Volt:%.2fV ",downval);
if(choice == 1) LCD_SetBackColor(Green);
LCD_DisplayStringLine( Line3, (u8*)temp);
LCD_SetBackColor(Black);
sprintf(temp," Upper:LD%d ",upled);
if(choice == 2) LCD_SetBackColor(Green);
LCD_DisplayStringLine( Line4, (u8*)temp);
LCD_SetBackColor(Black);
sprintf(temp," Lower:LD%d ",downled);
if(choice == 3) LCD_SetBackColor(Green);
LCD_DisplayStringLine( Line5, (u8*)temp);
LCD_SetBackColor(Black);
}
}
void ledscan(void)
{
u8 ds =LEDINDEX[LEDDT[1]]|LEDINDEX[LEDDT[2]];
Led_disPlay(ds);
if(val>=downval && val<=upval) LEDDT[1]=LEDDT[2]=0,valstate=0; //正常状态
else if(val > upval) LEDDT[2]=0,valstate=1; //LEDDT[1]为上限指示灯 valstate:1 超过上限
else LEDDT[1]=0,valstate=2;
}
void readadc(void)
{
if(adct > 50) {
adct =0 ;
val = (adcbuf[1]+adcbuf[0]+adcbuf[2])/3*3.3/4095; //平均滤波
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?