STM32-串口配置与使用

  • 格式:pdf
  • 大小:127.43 KB
  • 文档页数:5

STM32-串⼝配置与使⽤

1、通讯基础串⾏通讯与并⾏通讯

串⾏通信

设备之间通过少量数据信号线(⼀般是 8 根以下),地线以及控制信号线,按数据位形式⼀位⼀位地传输数据。同⼀时刻只能传输⼀个数据位的数据

并⾏通讯

使⽤ 8、16、32 及 64 根或更多的数据线进⾏传输的通讯⽅式

可同时传输多个数据位的数据全双⼯、半双⼯及单⼯通讯

全双⼯在同⼀时刻,两个设备之间可以同时收发数据

半双⼯两个设备之间可以收发数据,但不能在同⼀时刻进⾏

单⼯

在任何时刻都只能进⾏⼀个⽅向的通讯,即⼀个固定为发送设备,另⼀个固定为接收设备同步通讯、异步通讯

同步通讯

收发设备双⽅使⽤⼀根信号线表⽰时钟信号,在时钟信号的驱动下双⽅进⾏协调,同步数据通讯中通常双⽅会统⼀规定在时钟信号的上升沿或下降沿对数据线进⾏采样

异步通讯

不使⽤时钟信号进⾏数据同步,直接在数据信号中穿插⼀些同步⽤的信号位,或者把主体数据进⾏打包,以数据帧的格式传输数据

某些通讯中需要双⽅约定数据的传输速率,以便更好地同步通讯速率

⽐特率(Bitrate)

每秒传输的⼆进制位数,单位bis/s波特率(Baudrate)

每秒钟传输的码元

通讯中常⽤时间间隔相同的符号来表⽰⼀个⼆进制数字,这样的信号称为码元

常见波特率4800,9600,115200

2、USART串⼝通讯协议层

起始和停⽌信号

串⼝通讯的⼀个数据包从起始信号开始,直到停⽌信号结束。数据包的起始信号由⼀个逻辑 0 的数据位表⽰,⽽数据包的停⽌信号可由 0.5、1、1.5 或 2 个逻辑 1 的数据位表⽰, 只要双⽅约定⼀致即可。有效数据

在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为 5、6、7 或 8 位长

数据校验

在有效数据之后,有⼀个可选的数据校验位。由于数据通信相对更容易受到外部⼲扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验⽅法有奇校验 (odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及⽆校验(noparity)。

奇校验要求有效数据和校验位中“1”的个数为奇数,⽐如⼀个 8 位长的有效数据为: 01101001,此时总共有 4 个“1”,为达到奇校验效果,校验位为“1”,最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。

偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,⽐如数据 帧:11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。0 校验是不管有效数据中的内容是什么,校验位总为“0”,1 校验是校验位总为“1”。U(S)ART

UART:通⽤异步收发器

USART:通⽤同步异步收发器

串⼝通信⼀般以帧格式传输数据,每帧包含起始信号、数据信息、停⽌信息,可选校验信息

Baudrate=fPCLK16∗USARTDIV

中断控制

3、USART初始化结构体

USART初始化结构体

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;

USART_BaudRate⼀般设置2400,9600,19200,115200

USART_WordLengthUSART_WordLength_8b,USART_WordLength_9b

USART_StopBitsUSART_StopBits_1,USART_StopBits_0_5,USART_StopBits_2,USART_StopBits_1_5

USART_ParityUSART_Parity_No,USART_Parity_Even,USART_Parity_Odd

USART_Mode

USART_Mode_Rx,USART_Mode_Tx,可通过逻辑|设定为收发模式

USART_HardwareFlowControlUSART_HardwareFlowControl_None,USART_HardwareFlowControl_RTS,USART_HardwareFlowControl_CTS,USART_HardwareFlowControl_RTS_CTSUSART时钟初始化结构体

使⽤同步模式时需要配置SCLK引脚输出脉冲的属性typedef struct{ uint16_t USART_Clock; //同步模式下SCLK引脚上时钟输出使能控制 uint16_t USART_CPOL; //时钟极性 uint16_t USART_CPHA; //时钟相位 uint16_t USART_LastBit; //最尾位时钟脉冲} USART_ClockInitTypeDef;

USART_ClockUSART_Clock_Disable,USART_Clock_Enable

USART_CPOLUSART_CPOL_Low,USART_CPOL_High

USART_CPHAUSART_CPHA_1Edge,USART_CPHA_2Edge

USART_LastBitUSART_LastBit_Disable,USART_LastBit_Enable

4、USART1串⼝配置

GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;在所有中断前都要设置中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级串⼝时钟使能,GPIO时钟使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟串⼝复位

⼀般系统刚开始配置外设时会先执⾏复位USART_DeInit(USART1);GPIO端⼝模式设置

//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复⽤推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输⼊GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10串⼝参数初始化USART_InitStructure.USART_BaudRate = bound;//串⼝波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//⼀个停⽌位USART_InitStructure.USART_Parity = USART_Parity_No;//⽆奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//⽆硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串⼝1初始化NVIC//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //⼦优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器开启串⼝中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串⼝接受中断使能串⼝USART_Cmd(USART1, ENABLE); //使能串⼝1

5、发送与接收发送数据

发送单个字节

可发送字符或者数字void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch){ /* 发送⼀个字节数据到USART */ USART_SendData(pUSARTx,ch); /* 等待发送数据寄存器为空 */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); }Usart_SendByte(USART1, ch);发送8位的数组void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num){ uint8_t i; for(i=0; i>8; /* 取出低⼋位 */ temp_l = ch&0XFF; /* 发送⾼⼋位 */ USART_SendData(pUSARTx,temp_h); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); /* 发送低⼋位 */ USART_SendData(pUSARTx,temp_l); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);}使⽤printf/putchar⾸先要包含头⽂件#include "stdio.h"重定向int fputc(int ch, FILE *f){ /* 发送⼀个字节数据到串⼝ */ USART_SendData(DEBUG_USARTx, (uint8_t) ch);