文章目录

  • 一、通信接口
    • 1.串行通信:
    • 2.串行通信的通信方式
    • 3.STM32的串口通信接口
    • 4.UART异步通信方式特点
    • 5.流控
  • 二、库函数
    • 1.硬件时钟
    • 2、硬件配置
    • 3.串口配置的一般步骤
  • 三、test
  • 四、重定向printf
    • #pragma import(__use_no_semihosting_swi)
    • test

一、通信接口

UART

处理器与外部设备通信的两种方式:

  • 并行通信

    • 传输原理:数据各个位同时传输。
    • 优点:速度快
    • 缺点:占用引脚资源多
  • 串行通信

    • 传输原理:数据按位顺序传输。
    • 优点:占用引脚资源少
    • 缺点:速度相对较慢

1.串行通信:

按照数据传送方向,分为:

  • 单工:

​ 数据传输只支持数据在一个方向上传输

  • 半双工:

​ 允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;

  • 全双工:

​ 允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。

2.串行通信的通信方式

  • 同步通信:带时钟同步信号传输。

    • SPI,IIC通信接口
  • **异步通信:**不带时钟同步信号。

    • UART(通用异步收发器),单总线

3.STM32的串口通信接口

UART:通用异步收发器

USART:通用同步异步收发器

uart和usart的区别UART与USART都是单片机上的串口通信,他们之间的区别如下:首先从名字上看:UART:universal asynchronous receiver and transmitter通用异步收/发器USART:universal synchronous asynchronous receiver and transmitter通用同步/异步收/发器从名字上可以看出,USART在UART基础上增加了同步功能,即USART是UART的增强型,事实也确实是这样。但是具体增强到了什么地方呢?其实当我们使用USART在异步通信的时候,它与UART没有什么区别,但是用在同步通信的时候,区别就很明显了:大家都知道同步通信需要时钟来触发数据传输,也就是说USART相对UART的区别之一就是能提供主动时钟

UART异步通信方式引脚连接方法:

-RXD:数据输入引脚。数据接受。

-TXD:数据发送引脚。数据发送。

4.UART异步通信方式特点

全双工异步通信。

小数波特率发生器系统,提供精确的波特率。

可配置的16倍过采样或8倍过采样,因而为速度容差与时钟容差的灵活配置提供了可能。

可编程的数据字长度(8位或者9位);

可配置的停止位(支持1或者2位停止位);

可配置的使用DMA多缓冲器通信。

单独的发送器和接收器使能位。

检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志

多个带标志的中断源。触发中断。

其他:校验控制,四个错误检测标志。

5.流控

数据在两个串口之间进行通讯,常常会出现丢失数据的现象,比如当接收端数据缓冲区满了,而发送端还有数据发送过来,本质原因是速度不匹配,处理能力不匹配。

流控就是为了解决这个速度匹配的问题,它的含义非常简单,当接收端处理数据处理不过来时,就向发送端发送不在接收信息,当发送端接收到这个信号之后,就会停止发送,直到收到可以继续发送信号在继续发送。

流控的方式有两种,一种是硬件流控,一种是软件流控

二、库函数

1、很多模块默认出厂设置硬件参数配置如下:

配置串口,遵循“9600, N, 8,1”

9600,波特率

N,无校验位

8,数据位

1,停止位

对于ARM的高速芯片,波特率默认上浮到115200bps

1.硬件时钟

使能端口A的硬件时钟

使能串口1的硬件时钟

2、硬件配置

端口A引脚配置为复用功能模式

引脚连接到串口1硬件

配置串口相关的参数:波特率、校验位、数据位、停止位

配置串口中断

编写中断服务函数(用来接收数据)

串口1发送数据、接收数据

注意:

​ 乱码情况,文本的格式可能不一样,PLL参数是否正确

3.串口配置的一般步骤

三、test

#include "usart.h"
#include "stm32f4xx.h"
#include <string.h>
//usart a9t a10r
static uint8_t USART1_buf[64];//接收缓存区void USART1_init(uint32_t bps)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//   GPIOA时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//  使能串口1的硬件时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//   引脚连接到串口1硬件GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);//    端口A引脚A9、A10配置为复用功能模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;    //第9号跟10号引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            //复用模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       //高速GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;         //推挽输出,增加输出电流能力GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;     //没有上拉下拉电阻GPIO_Init(GPIOA, &GPIO_InitStructure);//   配置串口相关的参数:波特率、校验位、数据位、停止位USART_InitStructure.USART_BaudRate = bps;                                      //波特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //数据位长度8位USART_InitStructure.USART_StopBits = USART_StopBits_1;                            //停止位1位/* When using Parity the word length must be configured to 9 bits */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);//   配置串口1的中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 配置串口1中断触发方式,接收一个字节触发中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);// 使能串口1工作USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数 接收数据
void USART1_IRQHandler(void)
{uint16_t  d;static uint16_t cnt = 0;if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)//检测中断标志{if(cnt < 63)//接收数据{USART1_buf[cnt] = USART_ReceiveData(USART1);}else{cnt = 0;}//将接收到的数据,返发给PCUSART_SendData(USART1, USART1_buf[cnt]);cnt ++;while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//清空标准位USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}void USART1_SendChar(uint16_t c)
{USART_SendData(USART1,c);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}void USART1_SendData(char *data)
{while(*data!='\0'){USART1_SendChar(*data);data++;}
}//buf:接收缓存首地址
//len:读到的数据长度
void MyUSART1_RcvData(char *buf,uint8_t *len)
{uint8_t i=0;while(USART1_buf[i]!='\0'){buf[i] = USART1_buf[i];i++;}if(i==0)*len = 0;else*len = i-1;
}int main(void)
{    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2init_led_beep();USART1_init(9600);USART1_SendData("hello world\r\n");char buf[64]={0};uint8_t len;while(1){memset(buf,0,64);delay_xms(40);MyUSART1_RcvData(buf,&len);if(len == 0)continue;if(strstr(buf,"open beep")!= NULL)BEEP = 1;if(strstr(buf,"close beep")!= NULL)BEEP = 0;if(strstr(buf,"open led")!= NULL)Led_All_On2();if(strstr(buf,"close led")!= NULL)Led_All_off2();}
}

四、重定向printf

《CortexM3与M4权威指南.pdf》583页 18.1章节

​ A common task for beginners is to generate a simple output message of“Hello world!” In C language, this is commonly handled with a “printf” state-ment. Under the hood, the message output can be redirected to different formsof communication interfaces. Typically this is known as re-targeting. Forexample, it is very common to retarget printf to a UART during embedded soft-ware development

《CortexM3与M4权威指南.pdf》584页 18.2.2章节

In Keil ? MDK-ARM (or other ARM ? toolchains such as DS-5 ? Professional), thefunction that needs to be implemented to support printf is “fputc.”

/* Short version of retarget.c - Minimum code to support simple printf in Keil MDK-ARM */
/**************************************************************/
/* Minimum retarget functions for ARM DS-5 Professional / Keil MDK */
/**************************************************************/
#pragma import(__use_no_semihosting_swi)
#include "stm32f4xx.h"
#include <stdio.h>struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;int fputc(int ch, FILE *f) {return (ITM_SendChar(ch));
}void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}

#pragma import(__use_no_semihosting_swi)

Pragma用于指示编译器完成一些特定的动作

在嵌入式程序编译时如果出现printf、fopen、fclose等文件操作,因程序中并没有对这些函数的底层实现,使得设备运行时会出现软件中断BAEB处,这时就需要

__use_no_semihosting_swi这个声明,使程序遇到这些文件操作函数时不停在此中断处

应用,指纹锁、手机无线传输模块,如WiFi模块,蓝牙模块,GPRS模块,GPS模块,4G模块、串口屏

test

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
static uint8_t USART1_buf[64];//接收缓存区
//重定向printf,实际上是重定向这个fputc
int fputc(int ch, FILE *f)
{USART_SendData(USART1, ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return ch;
}

test

#include "myusart.h"
#include "stdio.h"struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
//重定向printf
int fputc(int ch,FILE *f)
{USART_SendData(USART1,ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);return ch;
}void MYUSAERT_Init(uint32_t bps)
{USART_InitTypeDef USART_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure;NVIC_InitTypeDef  NVIC_InitStructure;//串口时钟使能,GPIO时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//引脚复用GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//GPIO端口模式设置/* Configure PG6 and PG8 in output pushpull mode */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA, &GPIO_InitStructure);//串口初始化/* USARTx configured as follows:- BaudRate = bps baud  - Word Length = 8 Bits- One Stop Bit- No parity- Hardware flow control disabled (RTS and CTS signals)- Receive and transmit enabled*/USART_InitStructure.USART_BaudRate = bps;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_Rx | USART_Mode_Tx; //收发USART_Init(USART1,&USART_InitStructure);//开启中断并初始化NVICNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能串口USART_Cmd(USART1,ENABLE);
}
//中断处理函数
void USART1_IRQHandler(void)
{//串口数据收发//串口传输动态获取if(USART_GetITStatus(USART1,USART_IT_RXNE)== SET)//检测中断标志,如果中断被触发,接收到一个字节的数据{uint16_t d = USART_ReceiveData(USART1); //从USART1获取数据USART_SendData(USART1,d);    //将接收到的数据返回给PCwhile(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清空标志位}
}int main(void)
{/* Configure two bits for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2MYUSAERT_Init(9600);printf("hello world");while(1);
}

stm32f4xx-USART相关推荐

  1. STM32F411核心板固件库开发(二) USART配置

    (一)芯片USART信息 我自己手上的F411CEU6只有48个引脚,属于UFQFPN48封装.对于同一系列型号的芯片,封装不一样,引脚的个数也会不一样,芯片上的外设资源自然也会不一样.UFQFPN4 ...

  2. ChibiOS系列:五、将STM32 USART与ChibiOS串行驱动程序配合使用

    本文翻译自:http://www.playembedded.org/blog/stm32-usart-chibios-serial/ 将STM32 USART与ChibiOS串行驱动程序配合使用 发表 ...

  3. STM32F4 | SYSTEM文件夹介绍 | delay文件夹 | sys文件夹 | usart文件夹

    文章目录 一.delay 文件夹代码介绍 1.delay_init 函数 2.delay_us 函数 3.delay_ms函数 二.sys 文件夹代码介绍 1.IO 口的位操作实现 三.usart 文 ...

  4. 《STM32从零开始学习历程》——USART串口通讯实验篇1——中断接收与发送

    <STM32从零开始学习历程>@EnzoReventon USART串口通讯实验篇1--中断接收与发送 最近开始接触了STM32F4xx系列单片机,对于我这个从零开始学习的小白来说,可谓困 ...

  5. 14 STM32F429 USART

    cc14 STM32F429 USART 1.USART功能框图 常用: TX:发送数据输出引脚. RX:接收数据输入引脚. 不常用: SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚, ...

  6. 《STM32从零开始学习历程》——USART串口通讯实验篇2——指令控制LED灯实验

    <STM32从零开始学习历程>@EnzoReventon USART串口通讯实验篇2--指令控制LED灯实验 本实验是在<USART串口通讯实验篇1--中断接收与发送>的基础上 ...

  7. USART串口通信实验

    整理自:正点原子PPT 文章目录 串口简介 串口通信基本原理 常用串口相关寄存器 串口操作相关函数 硬件连接 串口配置一般步骤 例程参考 升级版 串口简介 详情见STM32F4开发指南 串口通信基本原 ...

  8. STM32F4xx固件库的说明及使用

    一.固件库介绍 1.先从网站上找到STM32F4xx固件库文件 (文件名为STM32F4xx_DSP_StdPeriph_Lib_V1.4.0),这里我上传到了. 2.解压打开. 3.Librarie ...

  9. GPIO,I2C,SPI,UART,USART,USB的区别

    1.简单区别: 1) GPIO(General Purpose Input Output )为通用输入/输出,通用端口,总线扩展器, 利用工业标准I2C.SMBus™或SPI™接口简化了I/O口的扩展 ...

  10. 通讯接口:I2C和USART,SPI,CAN,USB2.0

    文章目录 一.通讯接口介绍 二.I2C总线 三.通用同步/异步收发器USART 四.串行外设接口SPI 五.控制器区域网络CAN 六.串行通用总线USB 杨桃32学习笔记,本文图片文字皆为转述 一.通 ...

最新文章

  1. 在把 png 或者 gif“储存为 web 所用格式”时,勾选“交错”选项
  2. 用 Python脚本生成 Android SALT 扰码
  3. RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序”...
  4. GMPC:一个 MPD 客户端
  5. 【C++深度剖析教程19】前置操作符与后置操作符
  6. android ListView常用知识总结
  7. HDOJ(HDU) 2123 An easy problem(简单题...)
  8. instead of触发器实现复杂视图dml和应用逻辑
  9. ssr客户端android!Android开发真等于废人?看看这篇文章吧!
  10. matlab进化树的下载,MEGA进化树下载
  11. 获取并处理中文维基百科语料
  12. 微分几何 Class 3 曲线,曲率与挠率
  13. 考取IT职业资格证书相关信息
  14. 如何快速拆分PDF文件(照片快速转换成pdf)
  15. 设置了相对定位relative之后,改变top值,如何去掉多余空白?
  16. 如何保持长时间高效学习
  17. Bootstrap简单认识之Tooltips组件
  18. js html占位符,JavaScript占位符
  19. 输入一个字符串,逆序并输出
  20. Excel密码保护破解代码

热门文章

  1. 分享国内外21大知名网盘
  2. 超标量处理器设计——第四章_分支预测
  3. Mysql 随机生成整数
  4. Docker安装与使用
  5. 详解Camtasia的注释功能
  6. 2006年中国商业科技100强---有哪些是您熟悉的公司呢?
  7. html设置表格字体样式表,CSS:表格样式(设置表格边框/文字/背景的样式)
  8. UnityUGUI系统之Sprite
  9. 基于javaweb+springboot的医院预约挂号系统(java+Springboot+jsp+maven+layui+mysql)
  10. PS(CS6) 编辑gif动态图片