目录
一. 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理。
四、USB/TTL转232模块(以CH340芯片模块为例)的工作原理
二. 安装 stm32CubeMX,配合Keil,使用HAL库(或标准库)方式,设置USART1 波特率为115200,1位停止位,无校验位,完成下列任务:
三. 在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察串口输出波形,并分析时序状态正确与否,计算波特率实际为多少。
一. 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理。
串口协议和RS-232标准
串口协议和RS-232标准通常用于实现计算机与其他设备之间的通信。其中,RS-232是一种在单一线路上进行全双工通信的接口标准。
一、串口协议
串口通信协议是一种基于比特流进行通信的协议,通过串行线路(如RS-232、RS-485等)进行数据传输。在串口通信中,数据以比特流的形式逐个传输,每个比特流都是由二进制数据组成的。
二、RS-232标准
RS-232是一种在单一线路上进行全双工通信的接口标准。它定义了数据传输的电压范围、信号线布局、接口电气特性等。在RS-232标准中,逻辑1和逻辑0分别对应负电压和正电压,电压范围为-3V至-15V和3V至15V。
三、RS-232电平与TTL电平的区别
RS-232电平和TTL电平是两种不同的电信号标准,它们的主要区别在于电压范围和噪声容限。
- 电压范围:RS-232标准中,逻辑1的电压范围为-3V至-15V,逻辑0的电压范围为3V至15V。而TTL电平的输出低电平小于0.8V,高电平大于2.4V,输入低电平小于1.2V,高电平大于2.0V。
- 噪声容限:RS-232的噪声容限为2V,即要求接收器能识别高于+3V的信号作为逻辑“0”,低于-3V的信号作为逻辑“1”。而TTL电平的输入低电平噪声容限为(0.8-0)/2=0.4V,高电平噪声容限为(5-2.4)/2=1.3V。
此外,RS-232接口使用一根信号线和一根信号返回线与地线构成共地的传输形式,这种共地传输容易产生共模干扰,所以抗噪声干扰性弱。
四、USB/TTL转232模块(以CH340芯片模块为例)的工作原理
USB/TTL转232模块是一种常见的串口转换设备,它可以将USB信号转换为TTL电平信号,或者将TTL电平信号转换为USB信号。以CH340芯片模块为例,它是一种常见的USB转TTL/RS-232转换器。
CH340芯片内部集成了USB总线转换器和TTL/RS-232接口电路,可以将USB信号转换为TTL/RS-232电平信号,也可以将TTL/RS-232电平信号转换为USB信号。在进行USB转TTL/RS-232转换时,CH340芯片通过内部电路将USB信号转换为TTL/RS-232电平信号,然后通过相应的引脚输出。同时,也可以通过相应的引脚输入TTL/RS-232电平信号,然后通过CH340芯片将其转换为USB信号输出。
二. 安装 stm32CubeMX,配合Keil,使用HAL库(或标准库)方式,设置USART1 波特率为115200,1位停止位,无校验位,完成下列任务:
1)STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
2)在完成以上任务基础,继续扩展功能:当上位机给stm32发送一个字符“#”后,stm32暂停发送“hello windows!”;发送一个字符“*”后,stm32继续发送;
通过stm32cubemax生成文件:
1.设置rcc
设置sys
设置usart1
设置nvic
生成文件
打开生成的文件
打开文件main函数文件开始定义全局函数
char c;//指令 0:停止 1:开始
char message[]="hello Windows\n";//输出信息
char tips[]="CommandError\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送
main函数中的while循环里面添加传输代码
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(1000);
}
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>
void SystemClock_Config(void);
char c;//指令 0:停止 1:开始
char message[]="hello Windows\n";//输出信息
char tips[]="CommandError\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
//设置接受中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
//当flag为1时,每秒发送一次信息
//当flag为0时,停止
while (1)
{
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(1000);
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='0'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='1'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
/* USER CODE END 4 */
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
修改main文件为
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>
void SystemClock_Config(void);
char c;//指令 0:停止 1:开始
char message[]="hello Windows\n";//输出信息
char tips[]="CommandError\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
//设置接受中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
//当flag为1时,每秒发送一次信息
//当flag为0时,停止
while (1)
{
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(1000);
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='0'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='1'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
/* USER CODE END 4 */
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
配置烧录
使用串口调试助手展示结果
三. 在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察串口输出波形,并分析时序状态正确与否,计算波特率实际为多少。
设置魔法棒
点开仿真图像
ps:注意在观察图像之前需要修改代码,因为按照源代码的思路当没有传入启动信号观察不到端口的传输情况。
示波器显示图像usart1:
波特率:UART通信协议进行一个字节数据的传输时就是在信号线上产生八个高低电平的组合,数据传送速率用波特率来表示,即每秒钟传送的二进制位数。
已知:1位停止位,无校验位
1字符包含 1(起始位)+8(数据位)+0(校验位)+1(停止位)=10bit
计算得115200