蓝桥杯嵌入式备赛相关知识点

目录

一、介绍

二、初始化Cubemx

1.新建工程

2.下载程序引脚配置

3.启用外部晶振,时钟配置

4.生成工程

三、下载程序配置

1.LED

2.LCD

3.按键

4.pwm

5.ADC

6.I2C

7.UART

8.RTC


一、介绍

​ 蓝桥杯嵌入式使用的单片机是STM32G431RBT6,内核ARM Cortex - M4,MCU+FPU,170MHz/213DMIPS,高达128KB Flash,32KB SRAM,其余的外设就不多介绍了,参照数据芯片数据手册

​ CT117E-M4开发板资源:微控制器STM32G431RBT6、一路USB转串口、2.4寸TFT-LCD、4个功能按键、1个复位按键、8个LED、一个E2PROM(AT24C02)、一个可编程电阻(100K)、2路信号发生器、2个分压电位器、2个扩展接口、一个CMSIS DAP Link调试器

二、初始化Cubemx

1.新建工程

5fb498c2c5224447bf2036ea23fb5221.png

2.下载程序引脚配置

c90d2003fe5b4b1a8ea1603c773055fd.png

3.启用外部晶振,时钟配置

23dc035b2268452693ed3f8e344f60f3.png

96747e3fc33b43a996ae4bf14170dee4.png

4.生成工程

如果工程路径不是纯英文则会缺少启动文件

fa56dee196fa4a4ea5b04ed558e15ec4.png

三、下载程序配置

1.LED

1.1 原理图

880ace5d5d01465cacc36071102d5e45.png

1.2 引脚配置

其中PD2高电平使能锁存器,PC8-15默认给高电平,放置上电初始化LED亮

9f2a45d19f4a4776b8ce24d9a68b782a.png

1.3 添加库文件夹路径,并新建LED库文件

13f49e3002274548928a49436a4fdd74.png

1.4 相关代码

LED.c

#include "led.h"

void LED_Disp(uchar dsLED)
{
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); // 所有PC引脚置高
    HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET); // 将传入的dsLED位数置低,为了使对应的LED亮
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); // 锁存器置高使能,记住PC的引脚电平
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); // 锁存器置地,锁住PC的引脚电平
}

LED.h

#ifndef _LED_H_
#define _LED_H_

#include "main.h"
void LED_Disp(uchar dsLED);

#endif

1.5 头文件添加

cb74f03fa7d848f583b8b48ff88e94fc.png

1.6 工程调试

55856cba1a4c4db58415705e8d6a4426.png

2.LCD

2.1 原理图

89e1c291d87e4cffbe12436764ffb49f.png

2.2 将比赛提供的液晶显示工程复制到自己工程文件中

fe7b6be64c594992b9209173415a001a.png

b1e41c07d06c464d9b1efa3210c9db00.png

afd1f4fbfb7044eba412ffc15b56fb1b.png

2.3 引脚配置

7bb4737f4d1d4f55bca3aff8344de9a3.png

2.4 工程配置

67abd0142fb74399850aea514221efe5.png

2.5 工程调试

793528d6ec8342efa5e354827d72d32e.png

3.按键

3.1 原理图

cbc81dec3827499f9706c9d572e92d77.png

3.2 引脚配置

f0fa0c5c7c2f4e7eb8daba3aa83c97be.png

3.3 定时器配置

这里按键选择按下触发定时器进入中断 所以需要配置定时器

dec013f1d600402ba6e94bdb9d6db84d.png

使用定时器4(通用定时器,使用外部晶振),分频系数为80(从0开始则为80-1),则每1s
1M次,定时评率为为10000,对应1s 1M/10000次,频率为10ms每次,一定记得开启NVIC使能中断

3.4 相关代码

interrupt.c

#include "interrupt.h"
#include "stdio.h"

struct keys key[4] = {0,0,0,0,0};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//中断回调函数
{
	if(htim->Instance == TIM4)//判断是否来自于定时器4
	{
		key[0].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[1].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_status = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		for(int i = 0;i < 4;i++)
		{
			switch(key[i].judge_status)
			{
				case 0:
					if(key[i].key_status == 0)
					{
						key[i].judge_status = 1;
						key[i].key_time = 0;
					}
					break;
				case 1:
					if(key[i].key_status == 0)
					{
						key[i].judge_status = 2;
					}
					else
					{
						key[i].judge_status = 0;
					}
					break;
				case 2:
					if(key[i].key_status == 1)
					{
						key[i].judge_status = 0;
						if(key[i].key_time < 70)
						{
							key[i].key_flag = 1;
						}
					}
					else
					{
						key[i].key_time++;
						if(key[i].key_time > 70)
						{
							key[i].key_longflag = 1;
						}
					}
					break;
			}
		}
	}
}

interrupt.h

#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_

#include "stdbool.h"
#include "main.h"

struct keys
{
	uint8_t judge_status;
	bool key_flag;
	bool key_status;
	bool key_longflag;
	uint8_t key_time;
};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

#endif

3.5 工程调试

在interrupt.h定义的结构体须在main.c中用extern再次声明

2e453ac2ad974644b32e84705ea2431b.png

4.pwm

4.1 pwm输出引脚配置

配置PA6、PA7为输出引脚

49edd71159704a20b5586074e09cbf2a.png

c5aa702f57cb4f72bf934ff0b0d1303f.png

频率fre=80 000 000 / (PSC+1)/ (ARR+1)

占空比duty=CRR / ARR

4.2 输入捕获引脚配置

原理图

根据题目需求设置捕获引脚即可 第一个一般是模拟输出频率 第二个则是模拟输出电压 R37~R40分别对应硬件板上的四个旋钮

42b5123295dc4659bae9737a20207c6a.png

相关配置

78ea42571678424daf59c360f17759b5.png

选用PB4, PA15为定时器通道CH1
配置预分频,重装载值(设为最大,防止溢出),启用中断

4.3 相关代码

interrupt.c

#include "interrupt.h"

unsigned int Cnta1 = 0,Cnta2 = 0;
unsigned int fre1 = 0,fre2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)//获取频率
	{
			Cnta1 = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//得到计时值
			__HAL_TIM_SetCounter(htim,0);//计时值清0
			fre1 = (80000000/80)/Cnta1;//获得频率

			HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);//打开定时器
	}
	if(htim->Instance == TIM3)
	{
			Cnta2 = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SetCounter(htim,0);
			fre2 = (80000000/80)/Cnta2;
		
			HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
	}
}

interrupt.h

#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_

#include "main.h"

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);

#endif

4.4 工程调试

246e0f99e0de47eab3f95efc16c9b685.png

39b60aa3a3d142449783bf874f77d052.png

通过选择R39、R40即可调动频率值

5.ADC

5.1 原理图

9d44c0d9454e4ee08f9436a84dbc4279.png

5.2 引脚配置

0b3eec65eb1f420fbdea05f86d900bb7.png

5.3 相关代码

adc1.c

#include "adc1.h"

double getADC(ADC_HandleTypeDef *pin)
{
	unsigned int adc;
	HAL_ADC_Start(pin);
	adc = HAL_ADC_GetValue(pin);
	return adc*3.3/4096;
}

adc1.h

#ifndef __ADC1_H_
#define __ADC1_H_

#include "main.h"

double getADC(ADC_HandleTypeDef *pin);

#endif

5.4 工程调试

393c740560f64ca88e96cfd4753766f4.png

通过旋转R37~R38即可调动模拟输出电压

6.I2C

6.1 原理图及芯片资料

0f911214d89144a59cda57ae2386e346.png

af691b6f1c3a4fcdab4da3b5b62ddbc6.png

芯片资料中前面的nK就是芯片大小 我们只需要看第一行即可 第一行中前面四位固定是1010 后面的A0、A1、A2分别对应原理图中的E1、E2、E3 原理图中E1、E2、E3分别接地 所以在设置地址时设置0即可 最后的R/W位即用来配置是读或者写 0则为写入 1为读取 这对后续配置I2C相关工程有很大关系

6.2 引脚i配置

7817faa941b048ad8e808d6437eb6804.png

简单的使能PB6、PB7的引脚为输出模式即可

6.3 将比赛提供库函数移植到自己工程文件中

5fa90bb5817144089536a895fde428e1.png

49141b1282c14a1caed8ecaf6779aae3.png

6.4 相关代码

在复制过来的工程I2C-hal.c底部编写以下函数

unsigned char I2C_Read(unsigned char addr)
{
	unsigned char data;
	I2CStart();
	I2CSendByte(0xa0);//0是写 1是读
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	data = I2CReceiveByte();
	I2CSendAck();
	I2CStop();
	return data;
}

void I2C_Write(unsigned char addr,unsigned char data)
{
	I2CStart();
	I2CSendByte(0xa0);//0是写 1是读
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(data);
	I2CWaitAck();
	I2CStop();
}

头文件中定义

unsigned char I2C_Read(unsigned char addr);
void I2C_Write(unsigned char addr,unsigned char data);

6.5 工程调试

6961f2b48d00495f9531b987b4d133b5.png

将上面的频率值分别的高八位和低八位分别写入I2C的指定地址 再将其读取

7.UART

7.1 引脚配置

1a45c046916c4338948c9f7b0c245cc1.png

波特率根据题目设定 一般为9600 同时需要开启中断

7.2 相关代码

//发送字符测试
char temp[20];串口调试
sprintf(temp,"fre1 = %d\r\n",fre1);
HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);

//接收字符函数
char rx_Alldata[30];
uint8_t rx_data;
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	rx_Alldata[rx_pointer++] = rx_data;
	HAL_UART_Receive_IT(&huart1,&rx_data,1);
}

7.3 工程调试

void uart_rx_process()
{
	if(rx_pointer>0)
	{
		if(rx_pointer == 22)
		{
			sscanf(rx_Alldata,"%4s:%4s:%12s",car_type,car_data,car_time);
		}
		else
		{
			char temp[20];
			sprintf(temp,"Error");
			HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);
		}
		rx_pointer = 0;
		memset(rx_Alldata,0,30);
	}
}

须在头文件中包含string,h 

8.RTC

8.1 引脚配置

8112427f9d5d4b289409522ddfe44882.png

8.2 相关代码

RTC_TimeTypeDef rtc_time;
RTC_DateTypeDef rtc_date;

void RTC_Rorcess()
{
	HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN);
}

8.3 工程调试

char text[20];
sprintf(text, "%02d-%02d-%02d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
LCD_DisplayStringLine(Line7, (uint8_t *)text);
sprintf(text, "%04d-%02d-%02d-%d",rtc_date.Year ,rtc_date.Month,rtc_date.Date,rtc_date.WeekDay );
LCD_DisplayStringLine(Line8, (uint8_t *)text

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值