打开主菜单

谷雨文档中心 β

更改

NBDK-L4:基础实验教程

添加21,701字节2019年2月26日 (二) 11:45
实验10-串口打印
== 实验11-串口中断 ==
上一章中,已经给大家简单的展示了如何去配置一个串口,并且格式化输出数据。这一章给大家带来串口中断实验,顾名思义,此实验是使用中断的方式去接收和打印串口数据。
 
=== STM32L476 UART简介 ===
USART主要功能:
 
•全双工异步通信
 
•NRZ标准格式(标记/空格)
 
•可配置的过采样方法16或8,以提供速度和速度之间的灵活性
 
时钟容差
 
•通用可编程发送和接收波特率高达10 Mbit / s时
 
时钟频率为80 MHz,过采样为8
 
•双时钟域允许:
 
- USART功能和从停止模式唤醒
 
- 独立于PCLK重新编程的便捷波特率编程
 
•自动波特率检测
 
•可编程数据字长(7,8或9位)
 
•可编程数据顺序,具有MSB优先或LSB优先移位
 
•可配置的停止位(1或2个停止位)
 
•同步模式和时钟输出,用于同步通信
 
•单线半双工通信
 
•使用DMA进行持续通信
 
•使用集中式DMA将接收/发送的字节缓冲在保留的SRAM中
 
•发送器和接收器的独立使能位
 
•独立的信号极性控制,用于发送和接收
 
•可交换Tx / Rx引脚配置
 
•调制解调器和RS-485收发器的硬件流控制
 
•通信控制/错误检测标志
 
•奇偶校验控制:
 
- 传输奇偶校验位
 
- 检查接收数据字节的奇偶校验
 
•带有标志的14个中断源
 
•多处理器通信
 
如果地址不匹配,USART进入静音模式。
 
•从静音模式唤醒(通过空闲线路检测或地址标记检测)
 
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 硬件设计 ===
选择STM32L4引脚PA9和PA10作为串口,当我们将拨码开关SW1拨到USB一端时,此串口通过CH340芯片转成USB接口,用于同PC端做一些串口数据通信。
[[文件:NBDK-SCH-UART-USB.png|边框|居中|无框|707x707像素]]
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 实验准备 ===
# 使用miniUSB线及10pin排线,通过Jlink仿真器连接PC端和开发板。
# 使用miniUSB线,连接PC与开发板USB接口。
# 将SW1拨到USB端,SW2拨到MCU。
# 使用Keil打开基础实验的实验11-串口中断。
# 使用Xshell打开miniUSB虚拟出的COM口
# 下载程序,并完成功能测试。
 
=== 实验验证 ===
下载完成后,我们打开miniUSB虚拟出的COM口,可以看到串口周期性的打印计数值。
[[文件:NBDK-XSHELL-UARTPRINTF.png|边框|居中|无框|759x759像素]]
 
=== 源码详解 ===
本节中的源码说明,仅针对此例程中的重要功能,详细的源码介绍请大家参照代码后的注释。
 
==== stm32l4xx_hal_conf.h ====
此文件位于“实验10-串口打印\Inc”路径中,主要用途是选择使能此例程使用到的库文件。
 
此例程我们主要给大家展示STM32L4的串口功能,所以我们宏定义中打开UART相关的。
 
在这边大家也许会有疑问,我们这个实验不是串口中断吗,为什么要打开DMA宏定义,这个其实是stm32l4xx_hal_uart.c这个库文件的问题,在这个库文件中,它并有像我们用户使用串口那样去区分是使用串口中断还是DMA,所以只要我们使用到串口的宏定义,在不修改串口库文件的情况下,就必须打开DMA的宏定义,否则编译出错。<syntaxhighlight lang="c" line="1" start="103">
// 使能的宏
#define HAL_MODULE_ENABLED // 芯片
#define HAL_FLASH_MODULE_ENABLED // Flash
#define HAL_PWR_MODULE_ENABLED // 电源
#define HAL_RCC_MODULE_ENABLED // 时钟
#define HAL_CORTEX_MODULE_ENABLED // NVIC
 
#define HAL_GPIO_MODULE_ENABLED // GPIO
#define HAL_DMA_MODULE_ENABLED // DMA
#define HAL_UART_MODULE_ENABLED // UART
</syntaxhighlight>
 
==== main.c ====
main函数,我们的例程由此处开始执行,首先调用HAL_Init()函数初始化我们的模块,接着调用SystemClock_Config()函数初始化此例程用到的时钟,具体有哪些时钟被初始化,在gyu_util.c部分有详细说明。
 
接下来我们初始化串口,并且打印欢迎语"Uart ISR demo"。
 
在while()循环中,我们判断STM32L4是否接收到串口助手发送的串口数据,如果接收到数据,则回显打印到串口助手。
 
<syntaxhighlight lang="c++" line="1" start="38">
int main(void)
{
uint16_t msgLen = 0;
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
// 重置所有外设、flash界面以及系统时钟
HAL_Init();
 
// 配置系统时钟(包含振荡器、系统时钟、总线时钟等等)
SystemClock_Config();
// 初始化串口USART1
MX_USART1_UART_Init();
// 初始化USART1中断isrCfg结构
HAL_UARTISR_Init();
printf("Uart ISR demo"); // 展示printf函数
//
while (1)
{
// 轮训是否存在串口数据
if(HAL_UART_Poll())
{
msgLen = HAL_UART_RxBufLen(); // 读取当前接收缓存区中有效的数据长度
// 超过100字节长度的部分不读取
if(msgLen > APP_BUF_LEN)
{
msgLen = APP_BUF_LEN;
}
msgLen = HAL_UART_Read(app_buf,msgLen); // 读取缓冲区数据
HAL_UART_Write(app_buf,msgLen); // 通过串口TX打印显示
}
}
}
</syntaxhighlight>
==== gyu_util.c ====
请参照实验01中的介绍。
 
基础实验中的其他例程,大部分都是使用的相同的时钟配置函数,有特殊的时钟使用,将会在对应例程的源码详解中做针对性说明。
==== gyu_usart_isr.c ====
串口初始化函数,初始化串口协议<syntaxhighlight lang="c++" line="1" start="47">
void MX_USART1_UART_Init(void)
{
// 配置串口参数
huart1.Instance = USART1; // UART寄存器基础地址,定义为USART1的
huart1.Init.BaudRate = 115200; // 串口波特率为115200
huart1.Init.WordLength = UART_WORDLENGTH_8B; // 串口数据位为8位
huart1.Init.StopBits = UART_STOPBITS_1; // 串口停止位为1位
huart1.Init.Parity = UART_PARITY_NONE; // 串口无校验位
huart1.Init.Mode = UART_MODE_TX_RX; // 串口模式,TX和RX作用
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 串口无流控制
huart1.Init.OverSampling = UART_OVERSAMPLING_16; // 16位过采样
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; // 1位过采样禁能
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; // 没有串口高级功能初始化
// 串口初始化
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__); // 如果初始化失败,进入错误处理任务
}
}
</syntaxhighlight>
== 实验12-串口DMA ==
串口打印实验,给大家展示的是如何配置STM32L476一个有效的硬件串口功能,并且顺带给大家介绍了如何去配置一个格式化打印函数printf()。
 
=== STM32L476 UART简介 ===
USART主要功能:
 
•全双工异步通信
 
•NRZ标准格式(标记/空格)
 
•可配置的过采样方法16或8,以提供速度和速度之间的灵活性
 
时钟容差
 
•通用可编程发送和接收波特率高达10 Mbit / s时
 
时钟频率为80 MHz,过采样为8
 
•双时钟域允许:
 
- USART功能和从停止模式唤醒
 
- 独立于PCLK重新编程的便捷波特率编程
 
•自动波特率检测
 
•可编程数据字长(7,8或9位)
 
•可编程数据顺序,具有MSB优先或LSB优先移位
 
•可配置的停止位(1或2个停止位)
 
•同步模式和时钟输出,用于同步通信
 
•单线半双工通信
 
•使用DMA进行持续通信
 
•使用集中式DMA将接收/发送的字节缓冲在保留的SRAM中
 
•发送器和接收器的独立使能位
 
•独立的信号极性控制,用于发送和接收
 
•可交换Tx / Rx引脚配置
 
•调制解调器和RS-485收发器的硬件流控制
 
•通信控制/错误检测标志
 
•奇偶校验控制:
 
- 传输奇偶校验位
 
- 检查接收数据字节的奇偶校验
 
•带有标志的14个中断源
 
•多处理器通信
 
如果地址不匹配,USART进入静音模式。
 
•从静音模式唤醒(通过空闲线路检测或地址标记检测)
 
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 硬件设计 ===
选择STM32L4引脚PA9和PA10作为串口,当我们将拨码开关SW1拨到USB一端时,此串口通过CH340芯片转成USB接口,用于向电脑上打印一些调试信息。
[[文件:NBDK-SCH-UART-USB.png|边框|居中|无框|707x707像素]]
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 实验准备 ===
# 使用miniUSB线及10pin排线,通过Jlink仿真器连接PC端和开发板。
# 使用miniUSB线,连接PC与开发板USB接口。
# 将SW1拨到USB端,SW2拨到MCU。
# 使用Keil打开基础实验的实验10-串口打印。
# 使用Xshell打开miniUSB虚拟出的COM口
# 下载程序,并完成功能测试。
 
=== 实验验证 ===
下载完成后,我们打开miniUSB虚拟出的COM口,可以看到串口周期性的打印计数值。
[[文件:NBDK-XSHELL-UARTPRINTF.png|边框|居中|无框|759x759像素]]
 
=== 源码详解 ===
本节中的源码说明,仅针对此例程中的重要功能,详细的源码介绍请大家参照代码后的注释。
 
==== stm32l4xx_hal_conf.h ====
此文件位于“实验10-串口打印\Inc”路径中,主要用途是选择使能此例程使用到的库文件。
 
此例程我们主要给大家展示STM32L4的串口功能,所以我们宏定义中打开UART相关的。<syntaxhighlight lang="c" line="1" start="103">
// 使能的宏
#define HAL_MODULE_ENABLED // 芯片
#define HAL_FLASH_MODULE_ENABLED // Flash
#define HAL_PWR_MODULE_ENABLED // 电源
#define HAL_RCC_MODULE_ENABLED // 时钟
#define HAL_CORTEX_MODULE_ENABLED // NVIC
 
#define HAL_GPIO_MODULE_ENABLED // GPIO
#define HAL_DMA_MODULE_ENABLED // DMA
#define HAL_UART_MODULE_ENABLED // UART
</syntaxhighlight>
 
==== main.c ====
main函数,我们的例程由此处开始执行,首先调用HAL_Init()函数初始化我们的模块,接着调用SystemClock_Config()函数初始化此例程用到的时钟,具体有哪些时钟被初始化,在gyu_util.c部分有详细说明。
 
接下来我们初始化串口UASRT1。
 
在while()循环中,我们每隔100ms通过格式化输出"TimeCount = xx:xx:xx"。
 
<syntaxhighlight lang="c++" line="1" start="34">
int main(void)
{
uint32_t hour = 0;
uint32_t minute = 0;
uint32_t second = 0;
 
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
// 重置所有外设、flash界面以及系统时钟
HAL_Init();
 
// 配置系统时钟(包含振荡器、系统时钟、总线时钟等等)
SystemClock_Config();
// 初始化串口USART1
MX_USART1_UART_Init();
//
while (1)
{
// 模拟时钟计时,这边的1s实际只是100ms
HAL_Delay(100); // 100ms延时
printf("TimeCount = %02d:%02d:%02d\r\n",hour,minute,second); // 格式化输出"TimeCount = xx:xx:xx"
 
// 时分秒计数
second++;
if(second == 60)
{
second = 0;
minute++;
}
if(minute == 60)
{
minute = 0;
hour++;
}
if(hour == 24)
{
hour = 0;
}
}
}
</syntaxhighlight>
==== gyu_util.c ====
请参照实验01中的介绍。
 
基础实验中的其他例程,大部分都是使用的相同的时钟配置函数,有特殊的时钟使用,将会在对应例程的源码详解中做针对性说明。
==== gyu_usart.c ====
== 实验13-TFT显示屏 ==
510
个编辑