蓝桥杯 嵌入式设计与开发项目模拟试题
前言:由于刚学习不久,该赛题对于本人来说还是有一定难度的(还是太菜了),与那些真正的大佬相比,还是有差距。因此,笔者也是想通过写博客进行对赛题总结,进而达到提升自己的目的,同时也想把笔者的一些想法分享给大家。若有不当之处,敬请指正
一、赛题要求
1 基本要求
1.1 使用国信长天嵌入式竞赛实训平台,完成本试题要求的程序设计与调试。
1.2 程序设计与调试过程中,可参考本试题配套提供的“资源数据包”。
1.3 程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的.axf文件。
说明:
- .axf文件外严格按照要求命名,勿上传任何其它无关文件。
- .axf文件是由Keil编译后生成的,可以在工程文件相应的输出文件夹中查找。
- 不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。
2 硬件框图
3 功能简述
3.1 基本功能
- 通过竞赛板上电位器R37输出模拟电压信号,经微控制器内部AD采集处理后,通过液晶屏实时显示。
- 通过串口接收上位机指令,执行指令,并返回数据。
- 支持按键扫描功能,可识别当前各个按键状态。
- LED亮灭受控。
3.2 初始化状态说明
指示灯LD1-LD8全部处于熄灭状态。
3.3 串口通信功能 - 串口基本配置
使用竞赛板USART2完成全部串口通信功能.
通信波特率配置为9600bps。 - LED亮灭控制指令
指令格式:“LDn:0”、“LDn:1”或“LDn:2”
指令解析:编号为n的LED指示灯点亮或熄灭,n的范围是1-8。0表示熄灭,1表示点亮,2控制指示灯状态翻转。
指令举例:
“LD1:0”,控制指示灯LD1熄灭。
“LD1:1”,控制指示灯LD1点亮。
“LD2:2”,控制指示灯LD2亮灭状态翻转。
指令回复:
本条指令不需要回复任何内容。 - 按键状态查询
指令格式:“Bn?”
指令解析:查询编号为n的按键状态。n的范围是1-4;
指令举例:“B1?”
指令回复:
“B1:P”或“B1:R”,其中P表示B1按键处于按下的状态,R表示B1按键处于释放的状态。 - 模拟电压查询指令
指令格式:“ADC?”
指令解析:查询当前微控制器采集到的实时电压值。
指令举例:“ADC?”
指令回复:
“ADC:3.02V”,表示当前采集到的电压值为3.02V,电压值保留小数点后两位有效数字。 - 未知指令
当设备收到收到未知的错误指令时,返回“error”。 - 通信指令要求
请严格按照上述1-5条中要求设计串口交互过程,注意指令格式、大小写等设计细节。
3.4 液晶显示功能 - 显示信息项
通过液晶屏幕显示按键状态、LED指示灯状态和ADC采集数据3个信息项,显示格式与位置如下图所示。
- 显示格式要求
显示背景色(BackColor):黑色。
显示前景色(TextColor):白色。
请严格按照图示要求设计各个信息项的名称和行列位置。
LED指示灯状态以一个16进制编码的数字表示(A、B、C、D、E、F字符大写,高位为0时显示),图示中的给出0A表示板上指示灯从LD8到LD1的状态为:灭-灭-灭-灭-亮-灭-亮-灭。
按键状态用P或R表示,P表示按键处于按下状态,R表示处于释放状态。如果
ADC采集数值需要保留小数点后2位有效数字,显示单位为伏特(V)。
3.5 按键功能
- 按键B1短按键操作:所有LED指示灯熄灭。
- 按键B1长按键操作(按下时长超过800ms):所有LED指示灯状态翻转。
3.6 程序性能要求
- 各类串口配置、查询指令响应时间要求:≤300ms。
- 各类操作执行后,液晶屏幕实时更新时间要求:≤300ms。
- 程序设计应保证按键操作、串口通讯操作后,不出现无响应、死机等严重故障。
- 程序设计应保证各类功能要求在执行操作期间互不影响。
二、代码及分析
难点
1.串口模块包含两部分:LED亮灭的控制、串口查询部分
2.LED在以十六进制显示LCD显示部分
代码
1.main.c代码
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "lcd.h"
#include "usart.h"
#include "led.h"
#include "lcd_window.h"
#include "adc.h"
#include "key.h"
u8 Rxbuffer[20];
u8 RxCounter;
u8 LED_Flag,ADC_Flag,B_Flag;
u8 LED_n[8],LED_Mode[8];
u8 number,n;
u8 L1,L2,L3,L4,L5,L6,L7,L8;
u32 LED_Number;
u8 KEY1_sum,KEY2_sum,KEY3_sum,KEY4_sum;
u8 B1_Flag,B2_Flag,B3_Flag,B4_Flag;
float ADC_VAL;
u8 other_Flag;
char ch[2]={'R','P'};
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SysTick_Config(SystemCoreClock/1000);
STM3210B_LCD_Init();
LCD_Clear(Black);
LCD_SetTextColor(White);
LCD_SetBackColor(Black);
usart_Init();
LED_Init();
adc_Init();
KEY_Init();
while(1)
{
LED_Control();
usart_Control();
KEY_Control();
lcd_window();
}
}
在开始写代码之前,我实现写好延时函数,以及把资料里面的lcd代码加入工程,先进行测试板子是否正常的运行;
2、usart.c代码
#include "usart.h"
#include "stm32f10x.h"
#include "stdio.h"
#include "adc.h"
extern u8 Rxbuffer[20];
extern u8 LED_Flag,ADC_Flag,B_Flag;
extern u8 RxCounter;
extern float ADC_VAL;
extern u8 other_Flag;
extern u8 B1_Flag,B2_Flag,B3_Flag,B4_Flag;
extern char ch[2];
void usart_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
/* Configure USARTy Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USARTy */
USART_Init(USART2, &USART_InitStructure);
/* Enable USARTy Receive and Transmit interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
/* Enable the USARTy */
USART_Cmd(USART2, ENABLE);
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void usart_sendata(uint8_t *str)
{
u8 index=0;
do
{
USART_SendData(USART2,str[index]);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
index++;
}while(str[index]!=0);
}
void USART2_IRQHandler(void)
{ u8 temp;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
/* Read one byte from the receive data register */
temp= USART_ReceiveData(USART2);
if(temp=='\n')
{ //LED_Flag=1;
RxCounter=0;
/* Disable the USARTy Receive interrupt */
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
}
else
{
Rxbuffer[RxCounter]=temp;
switch(Rxbuffer[0])
{
case 'L':LED_Flag=1;
B_Flag=0;
ADC_Flag=0;
break;
case 'B':B_Flag=1;
LED_Flag=0;
ADC_Flag=0;
break;
case 'A':ADC_Flag=1;
B_Flag=0;
LED_Flag=0;
break;
default: other_Flag=1;
break;
}
RxCounter++;
}
}
}
void usart_Control(void)
{
u8 str[20];
ADC_VAL=ADC_read();
if(ADC_Flag==1)
{
ADC_Flag=0;
sprintf(str,"ADC:%.2f V \n",ADC_VAL);
usart_sendata(str);
}
if(B_Flag==1)
{
B_Flag=0;
switch(Rxbuffer[1]-0x30)
{ case 1: sprintf(str,"B1:%c \n",ch[B1_Flag]);
usart_sendata(str);
break;
case 2:sprintf(str,"B2:%c \n",ch[B2_Flag]);
usart_sendata(str);
break;
case 3:sprintf(str,"B3:%c \n",ch[B3_Flag]);
usart_sendata(str);
break;
case 4:sprintf(str,"B4:%c \n",ch[B4_Flag]);
usart_sendata(str);
break;
default:break;
}
}
if(other_Flag==1)
{
other_Flag=0;
usart_sendata("error \n");
}
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
这里就是进行LED,ADC,Bn查询,我通过按每个查询指令的第一字母进行分类了,通过switch进行进行了判定,使其相应的标志位置位, 同时也满足了其他情况发送‘error’的要求。其次,由于查询指令没有指定结束符,当时我就是这里想了很久,想到没有题目指定结束符,应该怎样才能进行控制,经过多次尝试修改,最终发现,在代码里面就用 ‘\n’ 作为结束符,而在串口发送指令时,仍然按照题目要求的指令形式进行发送指令是可以满足实现题目要求的。
3.adc.c代码
#include "adc.h"
#include "stm32f10x.h"
void adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
// ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
float ADC_read(void)
{
float ADC_V;
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET) ;
ADC_V=ADC_GetConversionValue(ADC1)*3.30/0xfff;
return ADC_V;
}
4.led.c代码
#include "stm32f10x.h"
#include "led.h"
#include "stm32f10x_it.h"
extern u8 Rxbuffer[20];
extern u8 LED_Flag;
extern u8 LED_n[8],LED_Mode[8];
extern u8 L1,L2,L3,L4,L5,L6,L7,L8;
extern u8 number,n;
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin =LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void LED_Control(void)
{
GPIO_Write(GPIOC,0Xff00); //全灭
GPIO_SetBits(GPIOD,GPIO_Pin_2);//
GPIO_ResetBits(GPIOD,GPIO_Pin_2);//这三句代码我想应该可写为 GPIOC->ODR=0xFFFF 初始化全灭
if(LED_Flag)
{
number=(Rxbuffer[2]-0x30)-1; //这三句代码我想了很久,因为每个LED灯有3种模式,有8个led灯。
LED_n[number]=Rxbuffer[2]-0x30; //所以定义用两个数组:LED_n[8],LED_Mode[8];
LED_Mode[number]=Rxbuffer[4]-0x30;
}
if(LED_n[0]==1)
{switch(LED_Mode[0])
{
case 0:LED_Flag=0;
GPIO_SetBits(GPIOC,LED1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L1=0;
break;
case 1: LED_Flag=0;
GPIO_ResetBits(GPIOC,LED1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L1=1;
break;
case 2:delay_ms(200);
GPIO_ResetBits(GPIOC,LED1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_SetBits(GPIOC,LED1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L1=1;
break;
default:break;
}
}
if(LED_n[1]==2)
{switch(LED_Mode[1])
{
case 0:LED_Flag=0;
GPIO_SetBits(GPIOC,LED2);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L2=0;
break;
case 1: LED_Flag=0;
GPIO_ResetBits(GPIOC,LED2);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L2=1;
break;
case 2:delay_ms(200);
GPIO_ResetBits(GPIOC,LED2);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_SetBits(GPIOC,LED2);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L2=1;
break;
default:break;
}
}
if(LED_n[2]==3)
{switch(LED_Mode[2])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED3,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L3=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED3,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L3=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED3,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED3,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L3=1;
break;
default:break;
}
}
if(LED_n[3]==4)
{switch(LED_Mode[3])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED4,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L4=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED4,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L4=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED2,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED2,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L4=1;
break;
default:break;
}
}
if(LED_n[4]==5)
{switch(LED_Mode[4])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED5,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L5=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED5,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L5=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED5,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED5,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L5=1;
break;
default:break;
}
}
if(LED_n[5]==6)
{switch(LED_Mode[5])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED6,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L6=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED6,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L6=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED6,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED6,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L6=1;
break;
default:break;
}
}
if(LED_n[6]==7)
{switch(LED_Mode[6])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED7,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L7=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED7,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L7=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED7,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED7,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L7=1;
break;
default:break;
}
}
if(LED_n[7]==8)
{switch(LED_Mode[7])
{
case 0:LED_Flag=0;
GPIO_WriteBit(GPIOC,LED8,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L8=0;
break;
case 1: LED_Flag=0;
GPIO_WriteBit(GPIOC,LED8,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L8=1;
break;
case 2:delay_ms(200);
GPIO_WriteBit(GPIOC,LED8,Bit_RESET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_WriteBit(GPIOC,LED8,Bit_SET);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
L8=1;
break;
default:break;
}
}
}
3.LED亮灭的16进制的LCD上显示,我定义一个数组led_array[][2]
led_array.h
#ifndef __LED_ARRAY_H
#define __LED_ARRAY_H
char LED_Array[][2]= //LED灯状态数组
{
"00","01","02","03","04","05","06","07",
"08","09","0A","0B","0C","0D","0E","0F",
"10","11","12","13","14","15","16","17",
"18","19","1A","1B","1C","1D","1E","1F",
"20","21","22","23","24","25","26","27",
"28","29","2A","2B","2C","2D","2E","2F",
"30","31","32","33","34","35","36","37",
"38","39","3A","3B","3C","3D","3E","3F",
"40","41","42","43","44","45","46","47",
"48","49","4A","4B","4C","4D","4E","4F",
"50","51","52","53","54","55","56","57",
"58","59","5A","5B","5C","5D","5E","5F",
"60","61","62","63","64","65","66","67",
"68","69","6A","6B","6C","6D","6E","6F",
"70","71","72","73","74","75","76","77",
"78","79","7A","7B","7C","7D","7E","7F",
"80","81","82","83","84","85","86","87",
"88","89","8A","8B","8C","8D","8E","8F",
"90","91","92","93","94","95","96","97",
"98","99","9A","9B","9C","9D","9E","9F",
"A0","A1","A2","A3","A4","A5","A6","A7",
"A8","A9","AA","AB","AC","AD","AE","AF",
"B0","B1","B2","B3","B4","B5","B6","B7",
"B8","B9","BA","BB","BC","BD","BE","BF",
"C0","C1","C2","C3","C4","C5","C6","C7",
"C8","C9","CA","CB","CC","CD","CE","CF",
"D0","D1","D2","D3","D4","D5","D6","D7",
"D8","D9","DA","DB","DC","DD","DE","DF",
"E0","E1","E2","E3","E4","E5","E6","E7",
"E8","E9","EA","EB","EC","ED","EE","EF",
"F0","F1","F2","F3","F4","F5","F6","F7",
"F8","F9","FA","FB","FC","FD","FE","FF",
};
#endif
这里共有256个,下标为0-255。这里通过L1, L2, L3, L4, L5, L6, L7, L8在led.c中来计算下标,当某个LED点亮,则Ln=1,反之为0。计算下标的方式,就是通过2进制转化为十进制的方法:
LED_Number=L8*(1<<7)+L7*(1<<6)+L6*(1<<5)+L5*(1<<4)+L4*(1<<3)+L3*(1<<2)+L2*(1<<1)+L1; //下标
这条语句在接下来的lcd_window.c中。
4.lcd_window.c
#include "stm32f10x.h"
#include "lcd_window.h"
#include "stdio.h"
#include "lcd.h"
#include "led_array.h"
#include "adc.h"
extern u8 L1,L2,L3,L4,L5,L6,L7,L8;
extern u32 LED_Number;
extern float ADC_VAL;
extern u8 B1_Flag,B2_Flag,B3_Flag,B4_Flag;
extern char ch[2];
void lcd_window(void)
{
u8 str[20];
LED_Number=L8*(1<<7)+L7*(1<<6)+L6*(1<<5)+L5*(1<<4)+L4*(1<<3)+L3*(1<<2)+L2*(1<<1)+L1; //求倍数
ADC_VAL=ADC_read();
sprintf(str," ADC:%.2f V",ADC_VAL);
LCD_DisplayStringLine(Line1,str);
sprintf(str," B1 : %c",ch[B1_Flag]);
LCD_DisplayStringLine(Line3,str);
sprintf(str," B2 : %c",ch[B2_Flag]);
LCD_DisplayStringLine(Line4,str);
sprintf(str," B3 : %c",ch[B3_Flag]);
LCD_DisplayStringLine(Line5,str);
sprintf(str," B4 : %c",ch[B4_Flag]);
LCD_DisplayStringLine(Line6,str);
sprintf(str," LED:");
LCD_DisplayStringLine(Line7,str);
LCD_DisplayChar(Line7,215,LED_Array[LED_Number][0]);//这里是取单个字母
LCD_DisplayChar(Line7,200,LED_Array[LED_Number][1]);
}
5.key.c
#include "key.h"
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "led.h"
extern u8 KEY1_sum,KEY2_sum,KEY3_sum,KEY4_sum;
extern u8 B1_Flag,B2_Flag,B3_Flag,B4_Flag;
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PA.00 pin as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void KEY_Control(void)
{
if(KEY1==0)
{
delay_ms(10);
if(KEY1==0)
{
KEY1_sum++;
if(KEY1_sum==1)
{
B1_Flag=1;
GPIO_SetBits(GPIOC,LED_ALL);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
}
if(KEY1_sum>=16)
{
B1_Flag=1;
GPIO_ResetBits(GPIOC,LED_ALL);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
GPIO_SetBits(GPIOC,LED_ALL);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(200);
}
}
}
else
{
KEY1_sum=0;
B1_Flag=0;
}
if(KEY2==0)
{
delay_ms(10);
if(KEY2==0)
{
KEY2_sum++;
if(KEY2_sum==1)
{
B2_Flag=1;
}
}
}
else
{
KEY2_sum=0;
B2_Flag=0;
}
if(KEY3==0)
{
delay_ms(10);
if(KEY3==0)
{
KEY3_sum++;
if(KEY3_sum==1)
{
B3_Flag=1;
}
}
}
else
{
KEY3_sum=0;
B3_Flag=0;
}
if(KEY4==0)
{
delay_ms(10);
if(KEY4==0)
{
KEY4_sum++;
if(KEY4_sum==1)
{
B4_Flag=1;
}
}
}
else
{
KEY4_sum=0;
B4_Flag=0;
}
}
三、总结
此次题目对本人来说得到了很大的提高,也认识到自己的不足,希望可以不断的练习,总结经验,得到提升。该赛题还是有一定难度,但是只要不断的去尝试,总能得出答案,正如:代码是调出来的,不是写出来的。一起加油吧!