本文主要是介绍蓝桥杯嵌入式备赛相关知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、介绍
蓝桥杯嵌入式使用的单片机是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.新建工程
2.下载程序引脚配置
3.启用外部晶振,时钟配置
4.生成工程
如果工程路径不是纯英文则会缺少启动文件
三、下载程序配置
1.LED
1.1 原理图
1.2 引脚配置
其中PD2高电平使能锁存器,PC8-15默认给高电平,放置上电初始化LED亮
1.3 添加库文件夹路径,并新建LED库文件
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 头文件添加
1.6 工程调试
2.LCD
2.1 原理图
2.2 将比赛提供的液晶显示工程复制到自己工程文件中
2.3 引脚配置
2.4 工程配置
2.5 工程调试
3.按键
3.1 原理图
3.2 引脚配置
3.3 定时器配置
这里按键选择按下触发定时器进入中断 所以需要配置定时器
使用定时器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;key[i].key_longflag = 0;}else{key[i].key_time++;if(key[i].key_time > 70){key[i].key_longflag = 1;key[i].key_flag = 0;}}}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再次声明
4.pwm
4.1 pwm输出引脚配置
配置PA6、PA7为输出引脚
频率fre=80 000 000 / (PSC+1)/ (ARR+1)
占空比duty=CRR / ARR
4.2 输入捕获引脚配置
原理图
根据题目需求设置捕获引脚即可 第一个一般是模拟输出频率 第二个则是模拟输出电压 R37~R40分别对应硬件板上的四个旋钮
相关配置
选用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);//计时值清0fre1 = (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 工程调试
通过选择R39、R40即可调动频率值
5.ADC
5.1 原理图
5.2 引脚配置
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 工程调试
通过旋转R37~R38即可调动模拟输出电压
6.I2C
6.1 原理图及芯片资料
芯片资料中前面的nK就是芯片大小 我们只需要看第一行即可 第一行中前面四位固定是1010 后面的A0、A1、A2分别对应原理图中的E1、E2、E3 原理图中E1、E2、E3分别接地 所以在设置地址时设置0即可 最后的R/W位即用来配置是读或者写 0则为写入 1为读取 这对后续配置I2C相关工程有很大关系
6.2 引脚i配置
简单的使能PB6、PB7的引脚为输出模式即可
6.3 将比赛提供库函数移植到自己工程文件中
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 工程调试
将上面的频率值分别的高八位和低八位分别写入I2C的指定地址 再将其读取
7.UART
7.1 引脚配置
波特率根据题目设定 一般为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 引脚配置
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
这篇关于蓝桥杯嵌入式备赛相关知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!