蓝桥杯嵌入式
新建CubeMX工程
电路板简介
主控芯片:STM32G431RBT6
程序下载调试需要连接 CN2
接口(调试器的USB 转串口功能默认与STM32G431RBT6 微控制器 USART1连接)
基础CubeMX配置
-
配置下载调试器接口 SYS—>[debug] Serial Wire
-
开启时钟——外部高速时钟 RCC—>[High~] Crystal/Ceramic Resonator
-
配置时钟树——官方要求80MHz
-
文件配置
- 项目名称
- 路径(不要有中文)
- Project—>[Toolchain/IDE] MDK-ARM + V5.32
- Code—>第一个格选第二个 第二个格勾上第一个
-
点击生成[GENERATE CODE]
新建Keil u5 基本设置
- 魔法棒—>Target—>[ARM Compliler]use 6
- Debug–>[Use] CMSIS-DAP–>Settings–>[flash Dowload] √Reset and Run
自动补全
- 功能栏【Edit】—>Configuration—>【Text Completion】√ Symbols after—>OK
复位键
- Debug–>[Use] CMSIS-DAP–>Settings–>[flash Dowload] √Reset and Run
用户自己编写的代码注意写在区域里,不然重新生成 CubeMX 会没了
LED
单个led 常亮/闪烁
PD2锁存器控制LED的打开关闭
573锁存器:PD2高电平使能锁存器,可以 保留D1~D8八个引脚的状态(只有在锁存器使能情况下才保存);并且让Q1~Q8一直输出此状态(无论使能锁存器还是不使能锁存器,都输出原先的状态)
新建文件存LED.c 和 LED.h文件
在LED.h文件中——防止头文件main.c 被重复编译
#ifndef __LED_H
#define __LED_H
#include "main.h"
void LED_Control(uint8_t ledcter);
#endif//内容都写在里面
在LED.c文件 #include “LED.h”
User文件夹中添加一下新建文件
- Src文件夹 存.c 文件
- Inc文件夹 存.h 文件
在led.c中写函数void
void LED_Control(uint8_t ledctrl)
{
HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);//先关闭led的引脚
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,ledctrl<<8,GPIO_PIN_RESET);//1111 1111 0000 0000
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
//
}
在.h文件也要声明函数名
在mian.c函数中
-
在user~~include中 声明 LED的.h头文件
-
在user code begin pv新建定义参数 +使用led的函数
-
在主循环while中 声明使用led函数
-
/* USER CODE BEGIN PV */ uint8_t ledctrl = 0; uint32_t ledTick = 0; void LED_Process(void) { if(uwTick - ledTick < 100) return; ledTick = uwTick; ledctrl ^= 0x01; //这个变量为滴答定时器 LED_Control(ledctrl); }
闪灯要定义 32位大小的参数 ### 单向流水灯 运用 ```cpp /* USER CODE BEGIN PV */ uint8_t ledcnt_100ms = 0; uint8_t ledFlag = 0;//标志位 void SysTick_Handler(void) //1ms { //运用中断函数 HAL_IncTick(); ledcnt_100ms++; if(100 == ledcnt_100ms) { ledFlag = 1; ledcnt_100ms = 0; } } void LED_Process(void) { if(1 == ledFlag) { static uint8_t ledState = 1; //静态化赋值 相当于初始化一次,之后的值也是它 //初始化ledState==1; //进入case 1;ledState==2,break跳出Switch之后 //ledState==2再进入case 2 以此类推 ledFlag = 0; switch(ledState) { case 1: { LED_Control(0x01);ledState = 2;break; } case 2: { LED_Control(0x02);ledState = 3;break; } case 3: { LED_Control(0x04);ledState = 4;break; } case 4: { LED_Control(0x08);ledState = 5;break; } case 5: { LED_Control(0x10);ledState = 6;break; } case 6: { LED_Control(0x20);ledState = 7;break; } case 7: { LED_Control(0x40);ledState = 8;break; } case 8: { LED_Control(0x80);ledState = 1;break; } //0x01--0x80 十六进制转化为二进制 } } }//最后在main函数中 while{}内声明LED_Process( ); /*=============================用嘀嗒时钟=============================*/ uint32_t ledTick = 0; void LED_Process(void) { if(uwTick - ledTick < 200) return; ledTick = uwTick; static uint8_t ledState = 1; if(1 == ledFlag) { ledFlag = 0; switch(ledState) { case 1: { LED_Control(0x01);ledState = 2;break; } case 2: { LED_Control(0x02);ledState = 3;break; } case 3: { LED_Control(0x04);ledState = 4;break; } case 4: { LED_Control(0x08);ledState = 5;break; } case 5: { LED_Control(0x10);ledState = 6;break; } case 6: { LED_Control(0x20);ledState = 7;break; } case 7: { LED_Control(0x40);ledState = 8;break; } case 8: { LED_Control(0x80);ledState = 1;break; } //0x01--0x80 十六进制转化为二进制 } } }
KEY
定时器
定时器的概念、
PWM 3种模式 |
---|
PWM模式 : 同一定时器中,不同的通道下,输出的频率固定,占空比可变 |
PWM输出比较模式 : 同一定时器下,不同通道能够产生频率不同,占空比不同,甚至相位也不同的方波 |
PWM捕获模式 : PWM比较模式是输出不同频率或者占空比,这个是捕获就是反过来已知波形图而去计算对应占空比和频率 |
名词 | 描述 |
---|---|
PWM | 脉冲宽度调制,对模拟电路进行控制,应用于电机的控制、灯光的亮度调节、功率控制等 |
周期 | 一个完整PWM波形所持续的时间 |
占空比 | 有效电平持续时间(Ton)与周期时间(Period)的比值 |
方波 | 跟占空比差不多,一般用百分数表示,占空比0.5就是方波50% |
PWM频率 | 是指每秒钟信号从高电平到低电平再回到高电平的次数 |
定时器 | 用途 |
---|---|
TIM1、TIM8 | 高级定时器:具有通用功能以外、还具有死区控制的互补信号输出、紧急刹车关断输入等功能 |
TIM6、TIM7 | 基础定时器:定时、计数功能 |
其余 | 通用计时器:具备多路独立的捕获和比较通道,可以完成定时/计数、输入捕获、输出比较等功能。 |
计算公式 |
---|
占空比计算公式:Duty = (Ton / Period)× 100% period = (计数值 + 1)× (分频 + 1)/ 时钟频率 Duty = (正周期时间 / (总计数值 + 1 ))× 100% |
-
tim6 和 tim7是基础定时器——定时、计数功能
在CubeMX中记得开启定时器
√ Activated 【NVIC Settings】 √ Enable
//例如:每过100ms获取一次时间
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint16_t Time_10ms_count = 0;
if(htim == &htim6)
{
Time_10ms_count++;
if(100 == Time_10ms_count)
{
Time_10ms_count = 0;
LCD_display_function();//显示函数
}
}
}
-
TIM-IC捕获
测频率支路设置成
直接捕获模式
,而测脉宽的支路设置成间接模式
书写细节
模块化
-
新建一个 .h文件 存放(#include ~~)类函数。 其他文件只需要#include “此文件名” 就好了
#include “string.h” //c语言三件套
#include “stdio.h”
#include “stdlib.h” -
写函数分区更明朗
-
在main.c 中声明函数要带extern (减少报错,可有可无,我的程序需要)
例如:extern void Hardware_Init(void);
-
被调用的函数要放在前面写 才能被调用成功,因为调用函数是从上往下调用
例如
void beitiaoyong(void); void tiaoyong(void) { beitiaoyong(void); }
原理图怎么看
R(电阻) C(电容—隔直通交) L(电感—隔交通直)U(集成块)
芯片:GND(地)VCC(电源)AVDD、DVDD
跳线帽:起控制使能的作用。相当于一个开关,拔掉相当于断开开关