配置串口

串口简介

​ 通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART

​ 串行通信一般是以帧格式传输数据,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。USART 就是对这些传输参数有具体规定,参数值都可以自定义设置,以增强它的兼容性。USART 满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。

​ USART 支持同步单向通信和半双工单线通信;还支持局域互连网络 LIN、智能卡(SmartCard)协议与 lrDA(红外线数据协会) SIR ENDEC 规范。USART 支持使用 DMA,可实现高速数据通信。

字符帧格式

一个字符帧发送需要三个部分:起始位+数据帧+停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是我们要发送的 8 位或 9 位数据,数据是从最低位开始传输的;停止位是一定时间周期的高电平。当选择 8 位字长,使用 1 个停止位时的字符帧如下:

串口发送过程

​ 当发送使能位 TE 置 1 之后,发送器开始会先发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往 USART_DR 寄存器写入要发送的数据。在写入最后一个数据后,需要等待 USART 状态寄存器(USART_SR)的 TC 位为 1,表示数据传输完成,如果USART_CR1 寄存器的 TCIE 位置 1,将产生中断。以下是一些重要的标志位。

串口接收过程

​ 如果将 USART_CR1 寄存器的 RE 位置 1,使能 USART 接收,使得接收器在 RX 线开始搜索起始位。在确定到起始位后就根据 RX 线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到 RDR 内,并把 USART_SR 寄存器的 RXNE 位置1,同时如果 USART_CR2 寄存器的 RXNEIE 置 1 的话可以产生中断。以下是一些重要的标志位。

串口的中断控制

STM32F103RCT6串口引脚

STM32F103RCT6 系统控制器有三个 USART 和两个 UART,其中 USART1 和时钟来源于 APB2 总线时钟,其最大频率为 72MHz,其他四个的时钟来源于 APB1 总线时钟,其最大频率为 36MHz。UART 只是异步传输功能,所以没有 SCLK、nCTS 和 nRTS 功能引脚。

配置串口1

static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                    /* 嵌套向量中断控制器组选择 */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                /* 配置USART为中断源 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;         /* 抢断优先级*/NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;           /* 子优先级 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                  /* 使能中断 */NVIC_Init(&NVIC_InitStructure);                               /* 初始化配置NVIC */
}void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//打开串口GPIO的时钟DEBUG_USART_GPIO_APBxClkCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开串口外设的时钟DEBUG_USART_APBxClkCmd(RCC_APB2Periph_USART1, ENABLE);//将USART Tx的GPIO配置为推挽复用模式GPIOA9GPIO_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);//将USART Rx的GPIO配置为浮空输入模式GPIOA10GPIO_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;                        // 配置帧数据字长8或9USART_InitStructure.USART_StopBits = USART_StopBits_1;                            // 配置停止位.5/1/1.5/2USART_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(DEBUG_USARTx, &USART_InitStructure);                                    // 完成串口的初始化配置NVIC_Configuration();                                                          // 串口中断优先级配置USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);                            // 使能串口接收中断USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);                                   // 使能空闲中断USART_Cmd(DEBUG_USARTx, ENABLE);                                               // 使能串口
}

同步模式下的时钟配置

当使用同步模式USART时需要配置 SCLK 引脚输出脉冲的属性,标准库使用一个时钟初始化结构体 USART_ClockInitTypeDef 来设置,该结构体内容也只有在同步模式才需要设置。

typedef struct {uint16_t USART_Clock;        // 时钟使能控制uint16_t USART_CPOL;       // 时钟极性uint16_t USART_CPHA;         // 时钟相位uint16_t USART_LastBit;  // 最尾位时钟脉冲
} USART_ClockInitTypeDef;

一、USART_Clock:同步模式下 SCLK 引脚上时钟输出使能控制,可选禁止时钟输出(USART_Clock_Disable)或开启时钟输出(USART_Clock_Enable);如果使用同步模式发送,一般都需要开启时钟。它设定 USART_CR2 寄存器的 CLKEN 位的值。

二、USART_CPOL:同步模式下 SCLK 引脚上输出时钟极性设置,可设置在空闲时SCLK 引脚为低电平(USART_CPOL_Low)或高电平(USART_CPOL_High)。它设定 USART_CR2 寄存器的 CPOL 位的值。

三、USART_CPHA:同步模式下 SCLK 引脚上输出时钟相位设置,可设置在时钟第一个跳变沿捕获数据(USART_CPHA_1Edge)或在第二个跳变沿捕获数据。它设定 USART_CR2 寄存器的 CPHA 位的值。USART_CPHA 与 USART_CPOL 配合使用可以获得多种模式时钟关系。

四、USART_LastBit:选择在发送最后一个数据位的时候时钟脉冲是否在 SCLK 引脚输出,可以是不输出脉冲 (USART_LastBit_Disable) 、 输出脉冲(USART_LastBit_Enable)。它设定 USART_CR2 寄存器的 LBCL 位的值

串口相关函数

发送函数

void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{uint8_t i;for(i=0; i<num; i++){/* 发送一个字节数据到USART */Usart_SendByte(pUSARTx,array[i]);}/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET){}
}/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{uint8_t temp_h, temp_l;/* 取出高八位 */temp_h = (ch&0XFF00)>>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);
}///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口 */USART_SendData(DEBUG_USARTx, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);      return (ch);
}///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{/* 等待串口输入数据 */while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(DEBUG_USARTx);
}

接收函数

//将串口接收到的数据发送出去
//在stm32f01x_it.c中编写中断服务函数
//串口中断服务函数
void USART1_IRQHandler(void)
{uint8_t ucTemp;uint8_t buf_rx[20];uint8_t i = 0;if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) //如果收到一个数据{     ucTemp = USART_ReceiveData(USART1);                //就将这个数据传给ucTempUSART_SendData(USART1,ucTemp);                  //将接收到的数据发送出去}
}//将串口接收一帧的数据并发送出去
//在stm32f01x_it.c中编写中断服务函数
//串口中断服务函数
uint8_t buf_rx[20];
uint8_t i = 0,j = 0;
void DEBUG_USART_IRQHandler(void)
{uint8_t ucTemp;if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)   //如果收到一个数据{     if(i < 20)                                               //无论发过来多少,只接收20个数据buf_rx[i++] = USART_ReceiveData(USART1);            //就将这个数据传给buf_rx}    if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)      //接收到一帧数据{j++;USART1->SR;USART1->DR;printf("接收中断次数 %d\r\n",i);printf("空闲中断次数 %d\r\n",j);i = 0;printf("1帧 %s\r\n",buf_rx);memset(buf_rx,0,sizeof(buf_rx));}
}

STM32之串口相关配置相关推荐

  1. 浅谈STM32 USART串口中断配置函数USART_ITConfig()的编程思路

    void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) 函数参数列表中,USAR ...

  2. STM32 —— STM32 的串口通信

    STM32 -- STM32 的串口通信 STM32的串口通信接口有两种,分别是:UART(通用异步收发器).USART(通用同步异步收发器).而对于大容量 STM32F10x 系列芯片,分别有 3 ...

  3. stm32串口_【单片机】STM32串口基本配置

    1  时钟使能(用到哪个串口和GPIO要把相应的时钟开启): 2 串口复位:(一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作.) 3 GPIO口配置: 4 串口参数配置: 5 根据需要开启 ...

  4. STM32 定时器中断相关知识及配置

    实验工具:MDK5,STM32F103ZET6开发板 使用固件库编程 上一次学习的是利用定时器4,CH2通道产生PWM波来控制LED灯的闪烁,具体可以参考鱼撞烟花,在最后有代码连接. 这次学习定时器的 ...

  5. STM32串口通信配置(USART1+USART2+USART3+UART4) (转)

    一.串口一的配置(初始化+中断配置+中断接收函数) 1 /*====================================================================== ...

  6. STM32串口通信配置(USART1+USART2+USART3+UART4)

    一.串口一的配置(初始化+中断配置+中断接收函数) 1 /*====================================================================== ...

  7. 【嵌入式】openmv与stm32的串口通信

    参考:(文中部分图/文字/代码来自以下文章,部分内容由于时间久远已经找不到原作者,可联系注明或删除) PYTHON串口数据打包发送STM32接收数据解析 openmv中文文档 这里以openmv循迹代 ...

  8. STM32 USART串口DMA 接收和发送的源码详解!

    硬件平台:STM32F103ZET6: 开发环境:KEIL 4: 先说说应用通讯模式,串口终端的工作方式和迪文屏差不多,终端被动接受MCU发的指令,终端会偶尔主动发送一些数据给MCU(像迪文屏的触摸信 ...

  9. 【STM32】串口收发主要程序代码分析

    文章目录 数据发送与接收 串口状态 开启串口响应中断 获取相应中断状态 main.c usart.c usart.h 串口设置的一般步骤可以总结为如下几个步骤: 串口时钟使能,GPIO 时钟使能 串口 ...

最新文章

  1. 解决mysql建立的数据库名字不能带大写字母
  2. vc6.0绿色完整版 适用于xp win7 win8 win10
  3. 云原生生态周报 Vol. 14 | K8s CVE 修复指南
  4. gdi画平滑直线_石膏几何体不会画?那是你没有画过这些,学会画石膏很简单,收藏...
  5. oracle事务默认自动提交吗_干货|事务
  6. 如何在SQL Server中创建SQL依赖关系图
  7. 大数据如何助力农业发展
  8. asp和php关系,php和asp对象的等价关系_PHP教程
  9. 计算机二级ms高级应用选择题,计算机二级考试MS-OFFICE高级应用选择题及答案
  10. ConcurrentLinkedQueue since java1.5
  11. 视频教程-MATLAB图像处理-Matlab
  12. 35.伪造请求超时的ICMP数据包
  13. cad 2019 mac安装破解详细图文教程
  14. 美国电脑程序员需要考证吗
  15. Java 接入 cachecloud 入门
  16. 玩游戏计算机缺失msvcp140,游戏缺少msvcp140.dll错误提示怎么办解决方法
  17. 匈牙利算法(简单易懂)
  18. 计算机科学中的数学第一章答案,翻译《计算机科学与数学》第一章第四节:我们的公理...
  19. 关于研发项目计划排期与项目需求延期的想法
  20. 百度地图点击marker换图标的两种方式

热门文章

  1. 怎么桌面没有计算机图标,电脑桌面图标没有了怎么回事? 电脑桌面图标没有了的解决办法...
  2. 怎么自定义windows系统的性能监视器的属性
  3. 基于控件核心技术探讨---金阳光自动化测试Android(2)---2013年5月
  4. 新建一个文件夹出现多个文件夹
  5. 初学c语言数据类型——变量
  6. linux 获取当前目录
  7. NAND FLASH学习笔记之nand flash基础(一)
  8. 优化join or情形
  9. HDU2048神、上帝以及老天爷 (错排公式)
  10. 90后美女学霸:出身清华姚班,成斯坦福AI实验室负责人高徒