目录

  • 一、串口通讯概述
    • 1、广义的串口
    • 2、狭义的串口
    • 3、串口数据定义
    • 4、串口通讯应用
  • 二、STM32串口工程标准库实现
    • 1、串口的初始化
    • 2、串口数据发送.
    • 3、串口的数据接收

一、串口通讯概述

1、广义的串口

  广义的串口是针对并口来说的。串口是指设备之间通过一根数据信号线按数据位形式一位一位地传输数据的通讯端口,同一时刻只能传输一位(bit)数据。并口则是指用多条数据线进行传输的通讯方式,可以同一时刻并排传输多个数据位的数据端口。

2、狭义的串口

  狭义的串口我们就特指COM口,或者称做UART口。硬件上常用的两大电压标准有TTL(只有正电压)和RS232标准(有正负电压),STM32单片机上基本都使用的TTL标准,判别电压为基准供电电压的一半。我们看到的单片机上的串口一般分为两种,一种叫USART,通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter),另一种为UART,通用异步收发器(Universal Asynchronous Receiver and Transmitter),唯一的区别很明显,就是有和没有同步通讯方式。通常硬件至少要有一对Tx和Rx加上一个GND地,有了这三个引脚就可以工作了,其它同步引脚等其它引脚可以不使用。

3、串口数据定义

  完整的侦结构见下图,从一个起始位开始,接着是着多位有效数据,一般常规定义为8位,后面的就效验位,为可以选,最后一个就是停止标志位,也就是说8位有效数据的时候一个完整的帧结构就需要10位。
  波特率是描述串口通讯的速度指标,有很多种,双方约定好就可以正常通讯,我们常用的有9600、115200、921600,定位bps,位每秒。

4、串口通讯应用

  串口是我们使用的最基础的通信方式之一,因为引脚少,连接方便,它经常用来打印log,或作为短距离较少数据的通信方式,也可以替代I2C等偏低速通信方式。


二、STM32串口工程标准库实现

1、串口的初始化

  在STM32工程main的最开始,大while()循环之前,我们的各种外设都需要初始化,如下面串口的初始化代码, 它是用来驱动串口的初始化函数uart1_init(),输入参数为波特率baud_rate,从注释中可以看到,初始化要进行以下操作步骤:
1、使能时钟;
2、自动复用的引脚,
3、配置引脚的初始化状态方式;
4、配置串口的通信属性;
5、使能串口;
6、初始化嵌套向量中断控制器中的相关中断参数,为接收做准备。

//初始化IO 串口1
//bound:波特率
void uart1_init(u32 baud_rate)
{//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//#if EN_USART1_RX NVIC_InitTypeDef NVIC_InitStructure;//#endifRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟//串口1对应引脚复用映射GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1//USART1端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //速度50MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化//USART1 初始化串口属性设置USART_InitStructure.USART_BaudRate = baud_rate;//波特率设置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); //初始化串口1USART_Cmd(USART1, ENABLE);  //使能串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;     //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器}

2、串口数据发送.

  (1) 代码实现发送给串口1较为简单,一句话搞定:

Usart_SendString( USART1, send_data);

  • 参数USART1为串口的名称,它对应着外设的内存地址映射。
  • 参数send_data则是我们要发送的字符串数据,或者说是字符串指针。

   (2) 重定向printf()到USART1:

  • 重定向打印输出到串口1,需要定义fputc(),将打印数据的状态寄存器和数据寄存器映射到串口1,这样串口1就是打印数据口了。

int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}


/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == 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){}
}//重定向printf到USART1
int fputc(int ch, FILE *f)
{   while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   USART1->DR = (u8) ch;      return ch;
}

3、串口的数据接收

   因为单片机串口接收是一个字节一个的接收的,接收到一个字节就会进入到中断服务函数中。我们可以在中断中进行字节判断,如下面的代码实例,也可以接收一段字符后做字符串匹配判断。这里需要注意几点:

  • 中断服务程序的命名是有严格要求的,请注意不要写错,否者写错了也不给报错,很难找到问题原因。
  • 中断服务程序中运行的时间越短越好,也就是说代码,尽量少做判断越精简越好。
u16 num1 = 0;//数据累加计数
char USART_RX1_BUF[HOST_REC_LEN];//接收缓冲字节.// 串口中断服务函数
void USART1_IRQHandler(void)
{       if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//enum{RESET = 0, SET = !RESET} FlagStatus{    USART_RX1_BUF[num1] = (uint8_t)USART_ReceiveData(USART1);// 当接收到的值等于\r\n结尾时截取数据if(num1 > 2 && USART_RX1_BUF[num1-1] == '\r' && USART_RX1_BUF[num1] == '\n'){USART_RX1_BUF[num1+1]='\0';SetUARTFlag(1);//设置UART1标志num1 = 0;return;}//超出长度溢出时截断数据else if(num1 >= LimitSize_1){USART_RX1_BUF[num1]=0x0d;//回车USART_RX1_BUF[num1+1]=0x0a;//换行USART_RX1_BUF[num1+2]='\0';SetUARTFlag(1);//设置UART1标志num1 = 0;}//正常累加,判断异常数据else{if(USART_RX1_BUF[0]!=0)num1 ++;else num1 = 0;}  }   }

STM32 串口通讯及实现相关推荐

  1. stm32串口通讯问题

    stm32串口通讯问题 在串口试验中,串口通讯不正常,则可能会出现以下问题: 1. 配置完成后,串口没有任何消息打印. 原因:1,端口配置有问题,需要重新检查I/O口的配置 2,接线有问题,检查接线是 ...

  2. K210学习笔记(五)——MAIX BIT(K210)与STM32串口通讯

    前言 uart 模块主要用于驱动开发板上的异步串口,可以自由对 uart 进行配置.k210 一共有3个 uart,每个 uart 可以进行自由的引脚映射. 一.MAIX BIT串口使用步骤 1.引脚 ...

  3. STM32 —— 串口通讯

    STM32 -- 串口通讯 什么是串口通讯 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,其通讯协议可分层 ...

  4. STM32—串口通讯详解

    串口通讯目录 物理层 协议层 USART简介 开发板与上位机的连接 代码讲解: 一.初始化结构体 二.NVIC配置中断优先级 三.USART配置函数讲解 四.传输数据的函数: 1.发送一个字节 2.发 ...

  5. 作业—STM32串口通讯

    STM32串口通信 一.基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异 二.STM32的USART窗口通讯程序 1.烧录代码 2.代码 3.效果图 三.c语言程序里全局变量. ...

  6. STM32串口通讯实现——USB转串口

    一.RS232,TTL简介 RS232是个人计算机的通讯接口之一,一般会有两组RS323接口,分别为COM1和COM2,电平标准为+12V为逻辑负,-12为逻辑正. TTL电平为5V为逻辑正,0为逻辑 ...

  7. STM32串口通讯数据丢失原因分析及解决办法

    在进行串口通讯实验时,一时不仔细可能会发现通讯不正常,数据丢失的现象,包括丢失第一个字符,或只收到最后一个字符等等,本文接下来将就这类问题展开讨论. 首先是通过MCU向上位机发送数据: 若程序如下图所 ...

  8. 嵌入式作业(六):STM32串口通讯

    目录 一.基于寄存器与基于固件库的编程方式有什么差异. 二.STM32的USART窗口通讯程序 1.烧录代码的方式 2.代码及效果图 三.C语言程序里全局变量.局部变量.堆.栈等概念 四.stm32的 ...

  9. Stm32串口通讯的几种方式及其优缺点

    1.延时等待 原理:串口发送指令/数据之后,通过延时函数延时一定时间,等待从机的响应. 优点:实现简单,对于快速相应和长度不长的通讯可以使用此方法 缺点:(1)在非实时环境中,由于延时的存在会影响系统 ...

  10. python与STM32串口通讯(踩坑记录)

    1.环境 python端需要安装pyserial包和serial包,安装命令为 pip install pyserial 和 pip install serial.如果安装速度很慢可考虑使用清华镜像源 ...

最新文章

  1. 重要通知:招募200程序员,免费培训金融知识,不限年龄,有意者进!
  2. 虹影图片下载器(Preview)
  3. 九、玩转JavaScript的数组(五)
  4. CSS之position
  5. 闪灯什么意思_车灯闪1下、2下、3下各代表什么意思?关键时刻可以保命
  6. [转]你打算如何提升自己?
  7. nginx服务器开启缓存、反向代理
  8. macos big sur正式版_苹果macOS Big Sur正式版发布
  9. go爬虫和python爬虫_爬虫练手-豆瓣top250(go版以及python版)
  10. ROS笔记(32) MoveIt!关节控制器
  11. mongodb插入时,时间差的问题
  12. C#创建无数据源水晶报表极简教程
  13. .Net读取Excel的数据类型不统一获取空值问题
  14. python判断ip是否可以ping通
  15. c#解压缩文件(zip)
  16. 禁用浏览器的后退按钮
  17. python函数输入参数数量_如何实现Python函数的参数不限个数?
  18. 从项目管理角度如何保证质量
  19. 怎样查看主板支持服务器内存,怎么看主板和内存兼容-怎么查看主板对内存的支持情况 爱问知识人...
  20. leetcode146. LRU Cache

热门文章

  1. 数字听力Numbers Listening
  2. java 企业微信对接_Java对接企业微信
  3. 计算机考试怎么做word,word怎么做弧形文字
  4. 手机上怎么制作电子版证件照
  5. 使用exceljs导出excel表格
  6. 汉王考勤管理软件mysql数据库配置_汉王人脸通考勤管理软件
  7. 移动增值短信平台实施计划方案(珠海报业短信)
  8. Jmeter 使用教程
  9. 雷霆战机单机老版本_雷霆战机单机版
  10. 元器件选型实例(如何选一款合适的 DC-DC )