stm32学习笔记 串口usart
程序员文章站
2022-04-01 23:37:54
...
usart
并行通信(有好多根线)和串口通信(一根线)
同步通信:收发双方有clk同步信号线约定好的
异步信号:只有一根线,没有clk
防止信号紊乱
1.数据位要确定,有无奇偶校验,停止位长度,波特率
如果要通过串口要接pc机,需要rs232的电平转换芯片,usb为ttl转换芯片
1.使能gpio
2.复用
3.USART_Init
例子:
#include "bsp_uart.h"
#include "stdio.h"
void Uart1_NVIC_init(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitTypeDef NVIC_InitStruct1;
NVIC_InitStruct1.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct1.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct1.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct1.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct1);
}
void Uart1_Configuraction(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct1;
GPIO_InitStruct1.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct1.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct1);
GPIO_InitStruct1.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_IN; //配置浮空输入,
GPIO_InitStruct1.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct1.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitStruct1);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; //设置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位长度
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_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能或者失能指定的 USART 中断
USART_Cmd(USART1, ENABLE); //使能或者失能 USART 外设
}
void USART_sendString(const unsigned char *pt) {
while(*pt) {
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET); //检查指定的 USART 标志位设置与否,确保缓冲区为null
USART_SendData(USART1,*pt);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET); //发送完成
pt++; //指针指向下一行
}
}
int fputc(int c, FILE *fp) { //重写printf的fputc方法
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET); //检查指定的 USART 标志位设置与否,确保缓冲区为null
USART_SendData(USART1,c);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET); //发送完成
return 0;
}
int fgetc(FILE *fp) { //重写printf的fgetc方法,使用scanf
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET); //等待缓冲区内非null
return (int)USART_ReceiveData(USART1);
}
void USART1_IRQHandler(void) {
unsigned char ch;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) {
ch = USART_ReceiveData(USART1);
printf("%c\n",ch + 1); //为什么这里不用清除标志位,读操作时系统自动清除
}
}