STM32CubeMX生成Keil工程并实现闪灯与串口输出
STM32CubeMX生成Keil工程并实现闪灯与串口输出
环境搭建
STM32CubeMX 下载链接:https://www.st.com/stm32cubemx
Keil 下载链接:https://www.keil.com/download/product/
Keil 为付费软件,可以在网上寻找注册机激活使用
另外 Keil 需要安装一下 STM32 的 pack 包可以直接在 Keil 的 Pack Installer 中下载
也可以从官网下载:https://www.keil.arm.com/packs 然后双击安装
工程配置
打开 STM32CubeMX 点击新建工程
在打开的窗口中选择选择一下芯片型号,然后在右边选择对应的封装,点击 Start Project
接下来配置始时钟
选择 System Core -> RCC 将 High Speed Clock(HSE)修改为 Crystal/Ceramic Resonator
这里有必要多介绍一下,首先有两个不同的选项 HSE 和 LSE,这两都是配置外部时钟的选项,区别是:
HSE 是高速外部时钟,可接石英/陶瓷谐振器(晶振),或者接外部时钟源,频率范围为4MHz~16MHz
LSE 是低速外部时钟,接频率为32.768kHz的石英晶体
一般开发板上会有外部晶振,所以选择 HSE,其中又有三个选项:Disable 、 BYPASS Clock Source(旁路时钟源) 、Crystal/Ceramic Resonator(石英/陶瓷 晶振)
Disable 就不用多说了,禁用外部时钟,BYPASS Clock Source 意思是接直接从旁路导入时钟信号主要是给有源晶振用的,只需要接入 OSC_IN 引脚即可;Crystal/Ceramic Resonator 意思是需要 STM32 内部的时钟驱动电路配合外部无源晶振需要接 OSC_IN 和 OSC_OUT
然后来到 Clock Configuration 将 HCLK 修改为最大的 72,然后回车,会自动配置其他的参数
然后配置调试模式为 Serial Wire 即 SWD 调试,否则调试引脚可能被复用为其他功能导致无法调试
如果想要点亮一个 LED 灯的话,需要知道 LED 灯在开发板上连接到了哪个引脚,例如我这块板子上是 PC13,那么就需要配置 PC13 引脚为 GPIO_Output,配置时只需要点击右侧芯片上的对应引脚即可
然后如果想要使用 printf 打印什么的话,可以在 Connectivity 选择 USART1/2/3 ,设置 Mode 为 Asynchronous(异步通信),可以在下方的 Configuration -> GPIO Settings 配置使用哪个引脚来进行 USART 通信,也可以在 Configuration -> Parameter Settings 选择波特率等参数(默认 115200 可以不配置)
需要注意的在 Configuration -> NVIC Settings 中使能串口中断
之后就可以来到 Project Manager 页面填写好项目名称及 IDE和版本
然后来到 Code Generator 勾选生成独立的外设文件,最后点击右上角的 GENERATE CODE 即可,生成过程中遇到啥让下载的让他下载即可
来到对应的文件夹,找到 MDK-ARM 双击 .uvprojx 结尾的 keil 工程即可打开
代码编写
点击 Options for Target 勾选上 Usb MicroLIB
在 stm32f1xx_it.c 最后面添加这段代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
HAL_UART_Transmit(&huart1, (uint8_t *)Buffer, 1, 0xffff);
HAL_UART_Receive_IT(&huart1, (uint8_t *)Buffer, 1);
}
}
在 main.c 中添加包含 stdio.h 头文件和这俩函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
在 main.c 中添加全局变量:uint8_t Buffer[1];
在 stm32f1xx_it.c 头部声明全局变量 Buffer:extern uint8_t Buffer[1];
在串口初始化后,while 循环前添加接收中断开启函数
HAL_UART_Receive_IT(&huart1, (uint8_t *)Buffer, 1);
接下来就可以正常在 while 里面写代码,正常使用 printf 格式化字符串输出了
while (1)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//灯亮
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);//灯灭
HAL_Delay(500);
printf("Hello World!\n\n");
}