串口简介
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力。
简单双向串口通信有两根通信线(发送端TX和接收端RX),TX与RX要交叉连接。当只需单向的数据传输时,可以只接一根通信线。当电平标准不一致时,需要加电平转换芯片。
STM32 |
USB-TTL |
|
5V |
|
VCC(和 5V 或 3V3 短接) |
|
3V3 |
RX |
TDX |
TX |
RXD |
GND |
GND |
串口参数: |
|
- 波特率:串口通信的速率
- 起始位:标志一个数据帧的开始,固定为低电平
- 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
- 校验位:用于数据验证,根据数据位计算得来
- 停止位:用于数据帧间隔,固定为高电平
使用串口输出到电脑
使用串口时记得勾选 Use MicroLIB:
在 User 文件夹(或其他文件夹)下,新建两个文件:serial.c 和 serial.h(或其它名字,serial 取串口之意),并添加到「组」中。
基操之重写 printf 和 sprintf
HAL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <stdio.h> int fputc(int ch,FILE *f) { uint8_t c[1]={ch}; HAL_UART_Transmit(&huart1,c,1,2); return ch; }
#include <stdarg.h> #define DATA_MAX 256 uint8_t TxBuf[DATA_MAX]; void XXX_Printf(char *format,...) { va_list arg; va_start(arg,format); vsprintf((char*)TxBuf,format,arg); va_end(arg); HAL_UART_Transmit(&huart2,TxBuf,strlen((const char*)TxBuf),0xffff); }
|
标准库
serial.h:
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef _SERIAL_H #define _SERIAL_H #include "stm32f10x.h" #include <stdio.h> #include <stdarg.h>
void Serial_Init(uint32_t baud); void Serial_SendByte(uint8_t Byte); void Serial_SendString(char *str); void Serial_Printf(char *format,...); #endif
|
serial.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include "serial.h"
void Serial_Init(uint32_t baud) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; 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_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); USART_InitTypeDef USART_InitStruture; USART_InitStruture.USART_BaudRate=baud; USART_InitStruture.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStruture.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; USART_InitStruture.USART_Parity=USART_Parity_No; USART_InitStruture.USART_StopBits=USART_StopBits_1; USART_InitStruture.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&USART_InitStruture); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 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); USART_Cmd(USART1,ENABLE); }
void Serial_SendByte(uint8_t byte) { USART_SendData(USART1,byte); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); }
void Serial_SendString(char *str) { uint8_t i; for(i=0;str[i]!='\0';i++) { Serial_SendByte(str[i]); } }
int fputc(int ch,FILE *f){ Serial_SendByte(ch); return ch; }
|
示例程序 main.c:
1 2 3 4 5 6 7 8 9 10
| #include "stm32f10x.h" #include "serial.h" int main(void){ Serial_Init(115200); printf("Hello World!"); while(1){ } }
|
测试: