STM32
STM32单片机串口工作原理是什么?
STM32单片机串口通信的知识点汇总,不看肯定后悔
回帖(1)
2021-12-2 09:24:21
串行通信和并行通信:
单工、半双工、全双工:
同步通信和异步通信:
STM32单片机串口工作原理:
单片机与外设通信示意图:
重要寄存器功能:
源码下载链接:https://taileliekaishi.lanzous.com/iouUKfg475c
工程项目结构:
其中画红色方框部分为重要函数实现功能
uart.c
#include "UART/uart.h"
#include
/**
* 功能:初始化UART
* 参数:None
* 返回值:None
*/
void initUART(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// UART是复用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1时钟
/*********************GPIO Config***************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //发送管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //接收管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
/********************UART Config*****************************/
USART_InitStructure.USART_BaudRate = 115200; //设置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8bits数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //1bit停止位
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); //设置生效
USART_Cmd(USART1, ENABLE); //使能串口外设
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口接收中断
// 需要加上
USART_ClearFlag(USART1, USART_FLAG_TC); //软件清除发送完成标志位
}
/**
* 功能:指定某个UART发送一个字节
* 参数:USARTx:使用的目标串口x为1-3
* byte:待发送字节(建议设置为16位的,不容易丢数据)
* 返回值:None
*/
void sendByte(USART_TypeDef *USARTx, u16 byte)
{
USART_SendData(USARTx, byte); //发送一个字节
// 发送数据的速度远远小于单片机运行的速度,当单片机多次调用这个函数时,上一个字符串还没有发送完成
// 发送完成状态标志位:如果返回0表示发送没有完成,正在进行移位
// 如果是1表明发送完成就跳出while函数
while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC));//等待发送完成
USART_ClearFlag(USARTx, USART_FLAG_TC); //软件清除发送完成标志位
}
/**
* 功能:指定某个串口发送字符串
* 参数:USARTx:使用的目标串口x为1-3
* str:字符串指针
* 返回值:None
*/
// 连续调用上一个函数即可
void sendString(USART_TypeDef *USARTx, char *str)
{
// 字符串以0结尾,不是0就一直发送
while (*str)
{
sendByte(USARTx,*str++);
}
}
/****************************中断服务函数****************************************/
/**
* 功能:串口1中断服务函数
* 参数:None
* 返回值:None
*/
void USART1_IRQHandler(void)
{
}
/**
* 功能:串口2中断服务函数
* 参数:None
* 返回值:None
*/
void USART2_IRQHandler(void)
{
}
/**
* 功能:串口3中断服务函数
* 参数:None
* 返回值:None
*/
void USART3_IRQHandler(void)
{
}
/****************************重定向fputc函数****************************************/
/**
* 功能:使用UART1实现printf函数功能
* 参数:ch:待写入字符 我们无需关心
* f:文件指针 我们无需关心
* 返回值:None
*/
// 重定义函数
// 调用printf函数时会调用fputc函数
int fputc(int ch, FILE *f)
{
/* 将Printf内容发往串口 */
USART_SendData(USART1, (unsigned char)ch);
while (!USART_GetFlagStatus(USART1, USART_FLAG_TC));
USART_ClearFlag(USART1, USART_FLAG_TC);
return (ch);
}
main.c
#include "LED/LED.h"
#include "DELAY/Delay.h"
#include "UART/uart.h"
#include "NVIC/NVIC.h"
int main(void)
{
initLED();
initNVIC(NVIC_PriorityGroup_2);
initUART();
initSysTick();
while (1)
{
printf("taileliekaishin");
//printf("%dn",1234);
toggleLED();
Delay_ms(1000);
}
}
实验结果:
串行通信和并行通信:
单工、半双工、全双工:
同步通信和异步通信:
STM32单片机串口工作原理:
单片机与外设通信示意图:
重要寄存器功能:
源码下载链接:https://taileliekaishi.lanzous.com/iouUKfg475c
工程项目结构:
其中画红色方框部分为重要函数实现功能
uart.c
#include "UART/uart.h"
#include
/**
* 功能:初始化UART
* 参数:None
* 返回值:None
*/
void initUART(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// UART是复用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1时钟
/*********************GPIO Config***************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //发送管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //接收管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
/********************UART Config*****************************/
USART_InitStructure.USART_BaudRate = 115200; //设置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8bits数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //1bit停止位
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); //设置生效
USART_Cmd(USART1, ENABLE); //使能串口外设
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口接收中断
// 需要加上
USART_ClearFlag(USART1, USART_FLAG_TC); //软件清除发送完成标志位
}
/**
* 功能:指定某个UART发送一个字节
* 参数:USARTx:使用的目标串口x为1-3
* byte:待发送字节(建议设置为16位的,不容易丢数据)
* 返回值:None
*/
void sendByte(USART_TypeDef *USARTx, u16 byte)
{
USART_SendData(USARTx, byte); //发送一个字节
// 发送数据的速度远远小于单片机运行的速度,当单片机多次调用这个函数时,上一个字符串还没有发送完成
// 发送完成状态标志位:如果返回0表示发送没有完成,正在进行移位
// 如果是1表明发送完成就跳出while函数
while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC));//等待发送完成
USART_ClearFlag(USARTx, USART_FLAG_TC); //软件清除发送完成标志位
}
/**
* 功能:指定某个串口发送字符串
* 参数:USARTx:使用的目标串口x为1-3
* str:字符串指针
* 返回值:None
*/
// 连续调用上一个函数即可
void sendString(USART_TypeDef *USARTx, char *str)
{
// 字符串以0结尾,不是0就一直发送
while (*str)
{
sendByte(USARTx,*str++);
}
}
/****************************中断服务函数****************************************/
/**
* 功能:串口1中断服务函数
* 参数:None
* 返回值:None
*/
void USART1_IRQHandler(void)
{
}
/**
* 功能:串口2中断服务函数
* 参数:None
* 返回值:None
*/
void USART2_IRQHandler(void)
{
}
/**
* 功能:串口3中断服务函数
* 参数:None
* 返回值:None
*/
void USART3_IRQHandler(void)
{
}
/****************************重定向fputc函数****************************************/
/**
* 功能:使用UART1实现printf函数功能
* 参数:ch:待写入字符 我们无需关心
* f:文件指针 我们无需关心
* 返回值:None
*/
// 重定义函数
// 调用printf函数时会调用fputc函数
int fputc(int ch, FILE *f)
{
/* 将Printf内容发往串口 */
USART_SendData(USART1, (unsigned char)ch);
while (!USART_GetFlagStatus(USART1, USART_FLAG_TC));
USART_ClearFlag(USART1, USART_FLAG_TC);
return (ch);
}
main.c
#include "LED/LED.h"
#include "DELAY/Delay.h"
#include "UART/uart.h"
#include "NVIC/NVIC.h"
int main(void)
{
initLED();
initNVIC(NVIC_PriorityGroup_2);
initUART();
initSysTick();
while (1)
{
printf("taileliekaishin");
//printf("%dn",1234);
toggleLED();
Delay_ms(1000);
}
}
实验结果:
举报
更多回帖