第十届的蓝桥杯的题目自我感觉不是很难,只要把相对应的资源外设配置好就没有多大的问题。如果ADC不会配置的话,这届的题目就可以说是凉了。这届的题目主要就是围绕着ADC去进行配置。
我看有些大佬多用eeprom,我这里没有用到这个也实现了题目要求。也没啥bug,所以我就没有用eeprom了。
这里的硬件框图看出,除了最基本的按键、led、lcd之外,就主要就是ADC的配置了。再看看基本的要求:
这里说明要将ADC模拟电压在lcd上显示出来、led的提示功能、按键的设置功能实现。
对于lcd的设置,要就有两个界面“数据显示界面”和“参数配置界面”。在数据显示界面显示出当前的电压值和当前的状态。参数配置界面上主要由电压的上下限和上限指示灯和下线指示灯组成。
再看看按键,B1主要就是界面切换功能,B2主要就是高亮的设置,B3实现参数的加的功能,B4实现参数减的功能。
题目分析完毕,接下来看看代码实现部分。
1、主函数main
#include "stm32f10x.h"
#include "stdio.h"
#include "led.h"
#include "key.h"
#include "adc.h"
#include "lcd.h"
u32 TimingDelay = 0;
unsigned int adc_but; //adc储存值
unsigned char key_val; //按键存储值
unsigned char chun_chu[40];
unsigned char B1=0; //界面切换
unsigned char B2=0; //高亮切换
float Max=2.4; //初始化上限
float Min=1.2; //初始化下线
unsigned char LD_upper=1; //初始化上限指示灯
unsigned char LD_lower=2; //初始化下线指示灯
void lcd_caozuo(void)
{
if(B1==0) //数据参数显示界面
{
LCD_DisplayStringLine(Line1," Main ");
LCD_DisplayStringLine(Line3," ");
adc_but=adc_sacnf(); //读取电压值
sprintf((char*)chun_chu," Volt:%4.2fV ",(float)adc_but*3.3/4095);
LCD_DisplayStringLine(Line5,chun_chu);
if(adc_but*3.3/4095<Min) //当电压值低于下限时
{
LCD_DisplayStringLine(Line7," Status:Lower ");
}
if(adc_but*3.3/4095>Max) //当电压值高于上限时
{
LCD_DisplayStringLine(Line7," Status:Upper ");
}
if((adc_but*3.3/4095<Max)&&adc_but*3.3/4095>Min) //当电压值处于上限和下限之间时
{
LCD_DisplayStringLine(Line7," Status:Normal ");
}
LCD_DisplayStringLine(Line9," ");
}
if(B1==1) //参数配置界面
{
LCD_DisplayStringLine(Line1," Setting ");
if(B2==0) //不高亮
{
sprintf((char *)chun_chu," Max Volt:%2.1fV ",Max);
LCD_DisplayStringLine(Line3,chun_chu);
sprintf((char *)chun_chu," Min Volt:%2.1fV ",Min);
LCD_DisplayStringLine(Line5,chun_chu);
sprintf((char*)chun_chu," Upper:%2u ",LD_upper);
LCD_DisplayStringLine(Line7,chun_chu);
sprintf((char*)chun_chu," Lower:%2u ",LD_lower);
LCD_DisplayStringLine(Line9,chun_chu);
}
if(B2==3) //第三行高亮
{
LCD_SetBackColor(Yellow);
sprintf((char*)chun_chu," Max Volt:%4.2fV ",Max);
LCD_DisplayStringLine(Line3,chun_chu);
LCD_SetBackColor(White);
sprintf((char*)chun_chu," Min Volt:%4.2fV ",Min);
LCD_DisplayStringLine(Line5,chun_chu);
sprintf((char*)chun_chu," Upper:%2u ",LD_upper);
LCD_DisplayStringLine(Line7,chun_chu);
sprintf((char*)chun_chu," Lower:%2u ",LD_lower);
LCD_DisplayStringLine(Line9,chun_chu);
}
if(B2==5) //第五行高亮
{
sprintf((char*)chun_chu," Max Volt:%4.2fV ",Max);
LCD_DisplayStringLine(Line3,chun_chu);
LCD_SetBackColor(Yellow);
sprintf((char*)chun_chu," Min Volt:%4.2fV ",Min);
LCD_DisplayStringLine(Line5,chun_chu);
LCD_SetBackColor(White);
sprintf((char*)chun_chu," Upper:%2u ",LD_upper);
LCD_DisplayStringLine(Line7,chun_chu);
sprintf((char*)chun_chu," Lower:%2u ",LD_lower);
LCD_DisplayStringLine(Line9,chun_chu);
}
if(B2==7) //第七行高亮
{
sprintf((char*)chun_chu," Max Volt:%4.2fV ",Max);
LCD_DisplayStringLine(Line3,chun_chu);
sprintf((char*)chun_chu," Min Volt:%4.2fV ",Min);
LCD_DisplayStringLine(Line5,chun_chu);
LCD_SetBackColor(Yellow);
sprintf((char*)chun_chu," Upper:%2u ",LD_upper);
LCD_DisplayStringLine(Line7,chun_chu);
LCD_SetBackColor(White);
sprintf((char*)chun_chu," Lower:%2u ",LD_lower);
LCD_DisplayStringLine(Line9,chun_chu);
}
if(B2==9) //第九行高亮
{
sprintf((char*)chun_chu," Max Volt:%4.2fV ",Max);
LCD_DisplayStringLine(Line3,chun_chu);
sprintf((char*)chun_chu," Min Volt:%4.2fV ",Min);
LCD_DisplayStringLine(Line5,chun_chu);
sprintf((char*)chun_chu," Upper:%2u ",LD_upper);
LCD_DisplayStringLine(Line7,chun_chu);
LCD_SetBackColor(Yellow);
sprintf((char*)chun_chu," Lower:%2u ",LD_lower);
LCD_DisplayStringLine(Line9,chun_chu);
LCD_SetBackColor(White);
}
}
}
void key_caozuo(void)
{
key_val=key_scanf();//读取按键值
if(key_val==1) //第一个按键按下
{
switch(B1) //界面切换
{
case 0:B1=1;break;
case 1:B1=0;break;
}
}
if(key_val==2) //第2个按键按下
{
if(B1==1) //于界面配置参数界面有效
{
switch(B2) //高亮设置切换
{
case 0:B2=3;break;
case 3:B2=5;break;
case 5:B2=7;break;
case 7:B2=9;break;
case 9:B2=0;break;
}
}
}
if(key_val==3)
{
if(B1==1) //于界面配置参数界面有效
{
if((Max<3.3)&&(Min>0)&&(Max>Min)) //范围
{
if(B2==3)
{
Max=Max+0.1;
}
if(B2==5)
{
Min=Min+0.1;
}
if(B2==7)
{
if(LD_upper+1!=LD_lower) LD_upper++;
else if(LD_lower-LD_upper==1) LD_upper=LD_upper+2;
if(LD_upper>8)
{
if(LD_lower==1) LD_upper=2;
if(LD_lower!=1) LD_upper=1;
}
}
if(B2==9)
{
if(LD_lower+1!=LD_upper) LD_lower++;
else if(LD_upper-LD_lower==1) LD_lower=LD_lower+2;
if(LD_lower>8)
{
if(LD_upper==1) LD_lower=2;
if(LD_upper!=1) LD_lower=1;
}
}
}
}
}
if(key_val==4)
{
if(B1==1)
{
if((Max<3.3)&&(Min>0)&&(Max>Min))
{
if(B2==3)
{
Max=Max-0.1;
}
if(B2==5)
{
Min=Min-0.1;
}
if(B2==7)
{
if(LD_upper-1!=LD_lower) LD_upper--;
else if(LD_lower-LD_upper==1) LD_upper=LD_upper-2;
if(LD_upper<1)
{
if(LD_lower==8) LD_upper=7;
if(LD_lower!=8) LD_upper=8;
}
}
if(B2==9)
{
if(LD_lower-1!=LD_upper) LD_lower--;
else if(LD_upper-LD_lower==1) LD_lower=LD_lower-2;
if(LD_lower<1)
{
if(LD_upper==8) LD_lower=7;
if(LD_upper!=8) LD_lower=8;
}
}
}
}
}
}
//Main Body
int main(void)
{
SysTick_Config(72000);
STM3210B_LCD_Init();
LCD_Clear(White);
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
led_init();
key_init();
adc_init();
while(1)
{
lcd_caozuo();
key_caozuo();
}
}
//
void SysTick_Handler(void)
{
led_init();
if((float)adc_but*3.3/4095>Max)
{
TimingDelay++;
if(TimingDelay>100)
{
if(LD_upper==1) led_scanf(0,led0);
if(LD_upper==2) led_scanf(0,led1);
if(LD_upper==3) led_scanf(0,led2);
if(LD_upper==4) led_scanf(0,led3);
if(LD_upper==5) led_scanf(0,led4);
if(LD_upper==6) led_scanf(0,led5);
if(LD_upper==7) led_scanf(0,led6);
if(LD_upper==8) led_scanf(0,led7);
}
if(TimingDelay==200)
{
TimingDelay =0;
}
if(TimingDelay<100)
{
if(LD_upper==1) led_scanf(1,led0);
if(LD_upper==2) led_scanf(1,led1);
if(LD_upper==3) led_scanf(1,led2);
if(LD_upper==4) led_scanf(1,led3);
if(LD_upper==5) led_scanf(1,led4);
if(LD_upper==6) led_scanf(1,led5);
if(LD_upper==7) led_scanf(1,led6);
if(LD_upper==8) led_scanf(1,led7);
}
}
if((float)adc_but*3.3/4095<Min)
{
TimingDelay++;
if(TimingDelay>100)
{
if(LD_lower==1) led_scanf(0,led0);
if(LD_lower==2) led_scanf(0,led1);
if(LD_lower==3) led_scanf(0,led2);
if(LD_lower==4) led_scanf(0,led3);
if(LD_lower==5) led_scanf(0,led4);
if(LD_lower==6) led_scanf(0,led5);
if(LD_lower==7) led_scanf(0,led6);
if(LD_lower==8) led_scanf(0,led7);
}
if(TimingDelay==200)
{
TimingDelay =0;
}
if(TimingDelay<100)
{
if(LD_lower==1) led_scanf(1,led0);
if(LD_lower==2) led_scanf(1,led1);
if(LD_lower==3) led_scanf(1,led2);
if(LD_lower==4) led_scanf(1,led3);
if(LD_lower==5) led_scanf(1,led4);
if(LD_lower==6) led_scanf(1,led5);
if(LD_lower==7) led_scanf(1,led6);
if(LD_lower==8) led_scanf(1,led7);
}
}
}
2.adc
#include "adc.h"
void adc_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel=1;
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
ADC_Init(ADC1,&ADC_InitStruct);
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_1Cycles5);
ADC_Cmd(ADC1,ENABLE);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
unsigned int adc_sacnf(void)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
3.led
#include "led.h"
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=led0|led1|led2|led3|led4|led5|led6|led7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStruct);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_SetBits(GPIOC,ledall);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
void led_scanf(unsigned char mode,unsigned int led)
{
if(mode==0)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOC,led);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
else if(mode==1)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_SetBits(GPIOC,led);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
4.key
#include "key.h"
#include "lcd.h"
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
unsigned char key_scanf(void)
{
unsigned char key_but=0;
if(key0==0||key1==0||key2==0||key3==0)
{
Delay_LCD(100);
if(key0==0) key_but=1;
if(key1==0) key_but=2;
if(key2==0) key_but=3;
if(key3==0) key_but=4;
}
return key_but;
}
注:在高亮设置的时候设置完高亮的背景色后要把原有的背景色设置回去, 不然会出现混乱。
代码部分有多参考“撞上电子”的配置。