突击蓝桥杯嵌入式(四)——滴答定时器、按键的三行代码消抖、LCD与ADC
1.滴答定时器定时运行
我们利用滴答定时器,让LED每隔1s闪烁一次
//首先我们定义一个变量
__IO uint32_t uwTick_LED_Speed_Ctrl;
//然后写LED闪烁的子函数
int flag = 1;
void LED_Proc(void)
{
if((uwTick - uwTick_LED_Speed_Ctrl)<1000) return; //每隔1s运行一下(1000ms)
uwTick_LED_Speed_Ctrl = uwTick; //迭代
flag = -flag; //翻转电平状态
if(flag == 1) HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
else HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
}
然后我们就能看到LED每个1s闪烁一秒。
2.按键的三行代码
uint8_t Key_Value;
uint8_t Key_Down;
uint8_t Key_Up;
uint8_t Key_Old;
扫描按键,下面以2个按键为例
int Key_Scan()
{
static int key_flag;
if(KEY1_STATE == GPIO_PIN_RESET)
{
key_flag = 1;
}
else if(KEY2_STATE == GPIO_PIN_RESET)
{
key_flag = 2;
}
else
key_flag = 0;
return key_flag;
}
按键功能函数
void KEY_Proc()
{
if((uwTick - uwTick_KEY_Speed_Ctrl)<150) return;//每150ms扫描一次
uwTick_KEY_Speed_Ctrl = uwTick;
Key_Value = Key_Scan();
Key_Down = Key_Value & (Key_Value ^ Key_Old);
Key_Up = ~Key_Value & (Key_Value ^ Key_Old);
Key_Old = Key_Value;
switch(Key_Down)
{
case 1:
//操作1
break;
case 2:
//操作2
break;
default:
break;
}
}
3.LCD的使用
LCD的使用,首先涉及到LCD文件的移植,在我们考试的资料包里,会有一个名为液晶参考程序的文件,其中会有三个文件,分别是:fonts.h、lcd.h和lcd.h。
我们将他们拷贝到我们Cubemx生成根文件的Core中的Inc(h头文件)和Src(c文件)中,如下。
完成之后,我们配置时钟和其他基本配置
注意这里的时钟配置!HSI!!
然后我们生成文件
加入头文件
#include "lcd.h"
#include <stdio.h>
在正式开始驱动屏幕之前,我们要了解一下开发板上这块LCD的基本参数和需要用到的函数。
大家只需要记住,这块LCD总共有10行,每行大概可以容纳20个字符。
还有一个就是sprintf函数的使用,其功能是将你要输入的东西,拷贝到一个字符串中,直接上代码:
下面我们正式开始LCD使用,常用的函数如下:
1.LCD_init //初始化,没什么好说的
2.LCD_Clear(vu16 Color) //以某种颜色清屏,里面填写颜色,如Black
3.LCD_SetBackColor(vu16 Color); //设置背景颜色
4.LCD_SetTextColor(vu16 Color); //设置字体颜色
5.LCD_DisplayStringLine(u8 Line, u8 *ptr) //在某一行写入字符串。输入参数一个是行数,一个是字符串地址
下面我们在屏幕中间显示hello,world,
uint8_t str[20]; //之前先定义一个字符串正好20个
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
sprintf((char *)str," hello,world ");
LCD_DisplayStringLine(Line4,str);
效果如下
4.ADC的使用(单通道)
首先我们的板子上,ADC测量,与电位器R37、R38有关,其中R37对应PB15,R38对应PB12。
我们在LCD上显示这两个引脚的实时电压,首先CUBEMX一般配置我们不必多说,需要注意的就是ADC配置,先选择引脚,在选择ADC中的通道。
PB15同理
如何我们进入代码:
ADC的使用分为以下几个步骤:
1.HAL_ADC_Start(&hadc1); //开启ADC
2.HAL_ADC_PollForConversion(&hadc1,3); //等待ADC采集完成
3.HAL_ADC_GetValue(&hadc1); //获取ADC的值
4.HAL_ADC_Stop(&hadc1); //关闭ADC
我们可以编写一个获取值的函数:
uint16_t get_R37_Value()
{
static uint16_t value;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,3);
value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return value;
}
LCD展示
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC2_Init();
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
sprintf((char *)str," ADCTEXT ");
LCD_DisplayStringLine(Line2,str);
while (1)
{
sprintf((char *)str,"R37 value:%.2f",get_R37_Value() * 3.3 / 4096); //4096是因为我们采用12位ADC
LCD_DisplayStringLine(Line3,(uint8_t *)str);
sprintf((char *)str,"R38 value:%.2f",get_R38_Value() * 3.3 / 4096);
LCD_DisplayStringLine(Line4,(uint8_t *)str);
HAL_Delay(100);
}
}
之后我们就可以看到LCD上显示电压值,转动电位器,电压发生变化。