一.通信接口
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件。
二.硬件电路
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:
TTL电平:+3.3V或+5V表示1,0V表示0(传输距离近)
RS232电平:-3~-15V表示1,+3~+15V表示0(传输距离近)
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号,抗干扰能力强,传输距离远)
三.串口参数及时序
四.Usart外设
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器,它的同步模式只支持时钟输出而不支持时钟输入,所有USART与UART使用差不多。
USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
自带波特率发生器,最高达4.5Mbits/s,配置波特率
可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
可选校验位(无校验/奇校验/偶校验)
支持同步模式(多了一个时钟控制)、硬件流控制、DMA、智能卡、IrDA、LIN
STM32F103C8T6 USART资源: USART1、 USART2、 USART3
void Serial_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Tx;//发送模式
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_Init(USART2,&USART_InitStructure);
USART_Cmd(USART2,ENABLE);
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART2,(uint16_t)Byte);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);//等待标志位为1结束等待
}
五.HAL库开发
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
//HAL_StatusTypeDef 是枚举类型
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
//UART_HandleTypeDef 句柄(初始化重点是下面两个)
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*外设基地址(stm32f103xe.h)*/
UART_InitTypeDef Init; /*!< UART communication parameters*/
}UART_HandleTypeDef;
typedef struct
{ uint32_t BaudRate; /* 波特率 */
uint32_t WordLength; /* 字长 */
uint32_t StopBits; /* 停止位 */
uint32_t Parity; /* 奇偶校验位 */
uint32_t Mode; /* UART 模式 */
uint32_t HwFlowCtl; /* 硬件流设置 */
uint32_t OverSampling; /* 过采样设置 */
}UART_InitTypeDef
//接收中断
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
//作用:以中断的方式接收指定字节的数据
//形参 1 是 UART_HandleTypeDef 结构体类型指针变量
//形参 2 是指向接收数据缓冲区
//形参 3 是要接收的数据大小,以字节为单位
#include "./BSP/LED/LED.h"
#include "./BSP/USART/USART.h"
#include "./SYSTEM/delay/delay.h"
uint8_t g_rx_buffer[1]; /* HAL库使用的串口接收数据缓冲区 */
uint8_t g_usart1_rx_flag = 0; /* 串口接收到数据标志 */
/*第一步配置串口工作参数 HAL_UART_Init() */
UART_HandleTypeDef g_uart1_handle;/*UART句柄*/
void usart_Init(uint32_t baudrate)
{
g_uart1_handle.Instance=USART1;//寄存器基地址
g_uart1_handle.Init.BaudRate=baudrate;//
g_uart1_handle.Init.WordLength=UART_WORDLENGTH_8B;
g_uart1_handle.Init.StopBits=UART_STOPBITS_1;
g_uart1_handle.Init.Parity=UART_PARITY_NONE;
g_uart1_handle.Init.HwFlowCtl=UART_HWCONTROL_NONE;
g_uart1_handle.Init.Mode=UART_MODE_TX_RX;
HAL_UART_Init(&g_uart1_handle);
//第三步 开启串口异步接收中断
HAL_UART_Receive_IT(&g_uart1_handle,(uint8_t*)g_rx_buffer,1);//开启串口异步接收中断
}
/*第二步配置串口底层初始化 HAL_UART_MspInit() 配置GPIO、NVIC、CLOCK等*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) /* 如果是串口1,进行串口1 MSP初始化 */
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef gpio_init_struct;
gpio_init_struct.Pin = GPIO_PIN_9;
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽式复用输出 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的TX引脚 */
gpio_init_struct.Pin = GPIO_PIN_10;
gpio_init_struct.Mode = GPIO_MODE_AF_INPUT; /* 输入 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的RX引脚 */
//设置优先级,使能中断
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);//开启中断
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
//编写中断服务函数 USARTx_IRQHandler()、 UARTx_IRQHandler()
void USART1_IRQHandler()
{
HAL_UART_IRQHandler(&g_uart1_handle);
HAL_UART_Receive_IT(&g_uart1_handle,(uint8_t*)g_rx_buffer,1);
}
/* 串口数据接收完成回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
g_usart1_rx_flag = 1;
}
}