第二十五讲:串行通讯原理
1.串行通讯和并行通讯的区别
串行通讯:数据位按位传输。优点:占用引脚少。缺点:速度较慢。
并行通讯:数据位同时传输。优点:速度快。缺点:占用引脚多。
2.串行通讯三种方式
单工:数据只能在一个方向上传输。
半双工:数据可以在两个方向上传输,但在同一时刻,数据只能接收或发送。
全双工:数据可以在两个方向上传输,且在同一时刻,数据可以同时接收和发送。
3.串行通信的通信方式
同步通信:带时钟同步信息传输。
异步通信:不带时钟同步通信。
4.stm32的串口通信接口
UART:通用异步收发器
USART:通用同步异步收发器
stm32有3个USART和2个UART,且USART可以转换为UART。
5.UART引脚接线方式
6.UART异步通信特点:
一.全双工异步通信
二.需要调整到精确的波特率,以防传输错误。
三.有数据字长度和停止位。
四.有校验位来检测数据传输是否错误。
五.有多个中断源可以进入中断。
7.stm32串口异步通信参数
起始位:起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。
数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是8位或9位。传输数据时先传送字符的低位,后传送字符的高位。
奇偶校验位:奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。
停止位:停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。
波特率设置:每秒钟传输数据的位数,一般设置为115200。
8.stm32通信基础
一.数据通过发送,接收移位寄存器进行接收和发送数据。
二.波特率的设置由发送,接收器控制来决定,控制器的时钟由总线时钟来配置。其中串口1的时钟为pclk2,其余串口为pclk1,波特率配置可以为小数,但必须为1/16的整数倍。
三.控制器有接收,发送使能位,还有中断标志位。
第二十六讲:stm32串口库函数配置
1.波特率计算方式
2.串口配置一般步骤
3.代码分析
main()函数
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_led.h"
#include <stdio.h>
int main(void)
{
USART_Config();
while(1)
{
}
}
USART头文件
#ifndef __BSP_USART_H
#define __BSP_USART_H
#include "stm32f10x.h"
//串口1-USART1
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
void USART_Config(void);
#endif
USART C文件
#include "bsp_usart.h"
#include <stdio.h>
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin= DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate=DEBUG_USART_BAUDRATE;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_Mode=(USART_Mode_Rx|USART_Mode_Tx);
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_Init(DEBUG_USARTx,&USART_InitStructure);
NVIC_Configuration();
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
USART_Cmd(DEBUG_USARTx, ENABLE);
}
中断服务函数
void DEBUG_USART_IRQHandler(void)
{
uint16_t res;
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE))
{
res=USART_ReceiveData(DEBUG_USARTx);
USART_SendData(DEBUG_USARTx,res);
}
}
第二十七讲:串口通信实验
①:先规定通信协议,当信号以回车键结尾时,则表示信息传输成功。
②:当接收到0x0D时,USART_RX_STA的bit14会置1,当接收到0x0A时,USART_RX_STA的bit15会置1,通过检测这两个位来了解通信是否正常。
main()函数
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_led.h"
#include <stdio.h>
uint8_t Buffer[200]=0;
uint16_t RX_STA;
int main(void)
{
USART_Config();
uint16_t len;
uint16_t i;
while(1)
{
if(RX_STA&0x8000)
{
len=(RX_STA&0x3fff);
for(i=0;i<len;i++)
{
USART_SendData(DEBUG_USARTx,Buffer[i]);
while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_TC)==RESET);
}
RX_STA=0;
}
}
}
中断服务函数
extern uint8_t Buffer[200];
extern uint16_t RX_STA;
void DEBUG_USART_IRQHandler(void)
{
uint8_t res;
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
{
res=USART_ReceiveData(DEBUG_USARTx);
if((RX_STA&0x8000)==0)
{
if((RX_STA&0x4000)==0)
{
if(res==0x0d) RX_STA|=0x4000;
else
{
Buffer[RX_STA&0x3fff]=res;
RX_STA++;
if(RX_STA>199) RX_STA=0;
}
}
else
{
if(res!=0x0A) RX_STA=0;
else RX_STA|=0x8000;
}
}
}
}
解析:先是检验最后一位是否为0x0A,如果是,则直接回到主函数。然后再判断倒数第二位是否为0x0D,如何是,则判断最后一位是否位0x0A,如果不是,则直接重新传输数据,如何是,则结束本次传输。如果倒数第二位也不是0x0D,则继续传输数据。