1.1 通信
(1)分类:
按照数据传输的方式:串行通信、并行通信;
串行通信:
并行通信:
按照通信的数据同步方式:异步通信、同步通信;
异步通信:1.字符帧(8位数据位+1位校验位+1位起始位+1位停止位);2.校验方法:奇校验、偶校验、0校验、1校验、无校验;3.发、收设备的时钟要尽可能保持一致,但允许一定误差。
同步通信:发送方时钟对接收方时钟进行直接控制。
按照数据的传输方向:单工通信、半双工通信、全双工通信
单工通信:数据传输只沿一个方向,不能实现反向传输。
半双工通信:数据传输可以沿2个方向,但是需要分时进行(RS485)。
全双工通信:数据传输可以同时双向进行(RS232)。
(2)通信速率
通信速率,常指比特率(Bitrate)是衡量通信性能的重要参数。比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。
(3)RS232通信:
接口:公头、母头
接线:RXD、TXD、GND
电平转换芯片:TTL电平(单片机)--> RS232电平
通信协议:96-N-8-1(96:波特率9600,可以大于;N:不校验;8:数据传输位数;1:停止位)
1.2 STM32F1 USART
(1)USART
USART即通用同步异步收发器,它能够灵活地与外部设备进行全双工数据交 换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求。UART即通用异步收发器,它是在 USART 基础上裁剪掉了同步通信功能,同步和异步主要看其时钟 是否需要对外提供。
(2)结构框图
p1:功能引脚。
p2:数据寄存器功能。
p3:控制器单元。
p4:波特率生成模块。
2.USART串口通信配置
2.1通用定时器PWM输出配置步骤
(1)添加库文件:stm32f10x_usart.c/stm32f10x_usart.h;
(2)使能串口时钟及 GPIO 端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
(3)GPIO 端口模式设置,设置串口对应的引脚为复用功能
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出引脚TXD
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入引脚RXD
GPIO_Init(GPIOA,&GPIO_InitStructure);
(4)初始化串口参数,包含波特率、字长、奇偶校验等参数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
typedef struct
{
uint32_t USART_BaudRate; //波特率
uint16_t USART_WordLength; //字长
uint16_t USART_StopBits; //停止位
uint16_t USART_Parity; //校验位
uint16_t USART_Mode; //USART 模式
uint16_t USART_HardwareFlowControl; //硬件流控制
} USART_InitTypeDef;
(5)使能串口
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
(6)设置串口中断类型并使能
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalStat e NewState);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断
USART_ITConfig(USART1,USART_IT_TC, ENABLE);
(7)设置串口中断优先级,使能串口中断通道
(8)编写串口中断服务函数
USART1_IRQHandler uint16_t
USART_ReceiveData(USART_TypeDef* USARTx);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
2.2 配置流程
2.2.1 添加STM32驱动文件
2.2.2 初始化USART函数
2.2.3 USART中断服务函数
2.3.4 主函数
3.硬件设计
3.1 USB转串口:程序下载,通过CH340C模块
3.2 RS232
3.3 RS485
4.软件设计
4.1 功能描述
本章所要实现的功能是:STM32F1 通过 USART1 实现与 PC 机对话,STM32F1 的 USART1 收到 PC 机发来的数据后原封不动的返回给 PC 机显示。同时使用 DS0指示灯不断闪烁提示系统正常运行。
4.2 软件实现
(1)初始化 USART1,并使能串口接收中断等
#include "USART.h"
u8 USATR1_RX_BUF[USART1_RECIEVE_DATA_LEN]; //定义接收数据数组
u16 USART1_RX_STA=0; //识别接收数据长度,是否接收到0x0D、0x0;15:接收完成标志,14:接收到0x0D,0-13:接收到的有效数据
// ------------------------------1.USART初始化-----------------------------------
/* ---------------------------------函数声明-------------------------------------
*函数名称:USART1_Iint(u32 baud_rate)
*输入参数:u32 baud_rate:波特率
*返回参数:无
*功 能:初始化usart1
*作 者:lph
*日 期:2024/03/28
------------------------------------------------------------------------------ */
void USART1_Iint(u32 baud_rate)
{
//1.使能串口时钟及 GPIO 端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//2.GPIO 端口模式设置,设置串口对应的引脚为复用功能
GPIO_InitTypeDef GPIO_InitStructure;
//2.1 TXD端口初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出引脚TXD
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//2.2 RXD端口初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入引脚RXD
GPIO_Init(GPIOA, &GPIO_InitStructure);
//3.初始化串口参数,包含波特率、字长、奇偶校验等参数
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_InitStructure.USART_BaudRate=baud_rate;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
//4.使能串口
USART_Cmd(USART1, ENABLE);
//5.设置串口中断类型并使能
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//6.设置串口中断优先级,使能串口中断通道
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
(2)编写 USART1 中断服务函数
// -----------------------------2.USART中断服务函数------------------------------
/* ---------------------------------函数声明-------------------------------------
*函数名称:USART1_IRQHandler(void)
*输入参数:无
*返回参数:无
*功 能:usart1中断服务函数
*作 者:lph
*日 期:2024/03/28
------------------------------------------------------------------------------ */
void USART1_IRQHandler(void)
{
u8 ReceiveDate=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE)==SET) //判断是否为要发送的串口
{
ReceiveDate = USART_ReceiveData(USART1);
if((USART1_RX_STA&0x8000)==0) //是否接收完成
{
if(USART1_RX_STA&0x4000) //接收到0x0d
{
if(ReceiveDate!=0x0a)
{
USART1_RX_STA=0;
}
else
{
USART1_RX_STA |= 0x8000; //接收完成
}
}
else //未接收到0x0D
{
if(ReceiveDate == 0x0d) //接收到0x0d
{
USART1_RX_STA |= 0x4000;
}
else
{
USATR1_RX_BUF[USART1_RX_STA&0x3fff]=ReceiveDate;
USART1_RX_STA++;
if(USART1_RX_STA>(USART1_RECIEVE_DATA_LEN-1)) //当接收到数据长度大于设定的数据长度时,认为接收错误
{
USART1_RX_STA=0;
}
}
}
}
USART_SendData(USART1, ReceiveDate);
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET); //判断数据是否发送完成
}
}
(3)编写主函数
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "system.h"
#include "LED.h"
#include "SysTick.h"
#include "USART.h"
/* 主函数main() --------------------------------------------------------------*/
int main()
{
// 自定义变量
u8 i=0;
u16 len=0;
u16 t=0;
// 初始化
SysTick_Iint(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断分组
LED_Init();
USART1_Iint(115200);
while(1)
{
i++;
if(i%20==0)
{
if((USART1_RX_STA&0x8000)==1)
{
len = USART1_RX_STA&0x3ffff;
for(t=0;t<len;t++)
{
USART_SendData(USART1, USATR1_RX_BUF[t]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
}
USART1_RX_STA=0;
}
LED1 = !LED1;
delay_ms(100);
}
}
}