目录

  • 串口
  • 步骤
    • 1、确定 IO 口并初始化
    • 2、初始化 UATR
    • 3、UART 中断配置
    • 4、编写 UART 中断服务函数
    • 5.1、方法一:重定向 fputc()
    • 5.2、方法二:将字符串分割成一个一个字符发送出去
  • 效果
  • 附源码

串口

  • 串口全称为串行接口,采用 全双工异步通信的通信方式,一次只能传输一帧,一帧中包含 起始位数据位(一般为 8bit )校验位停止位
  • 由于采用异步通信,所以通信双方(这里是 上位机 与 STM32)必须提前说明好 字符格式(一帧中的字符格式)通信速率(波特率)

步骤

1、确定 IO 口并初始化

数据进入 USB 端口之后会进入 CH340(RS232 转 TTL),接着会进入 UART1端口,根据下图选择 PA9、PA10 作为接受口和发送口

 GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);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_InitStructure.GPIO_Pin   = GPIO_Pin_9;              //引脚编号GPIO_Init(GPIOA, &GPIO_InitStructure);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_InitStructure.GPIO_Pin   = GPIO_Pin_10;             //引脚编号GPIO_Init(GPIOA, &GPIO_InitStructure);

2、初始化 UATR

 USART_InitStruct.USART_BaudRate = 9600;                        //波特率   USART_InitStruct.USART_WordLength = USART_WordLength_8b;   //数据位USART_InitStruct.USART_StopBits = USART_StopBits_1;           //停止位USART_InitStruct.USART_Parity = USART_Parity_No;          //校验位USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//模式 发送 + 接收USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_Init(USART1, &USART_InitStruct);

3、UART 中断配置

 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);      USART_Cmd(USART1, ENABLE);//配置中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;           //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;        //响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //使能通道NVIC_Init(&NVIC_InitStructure);

4、编写 UART 中断服务函数

// 每接收到一个字符(1个字节)就会触发一次UART中断!!!
void USART1_IRQHandler(void)
{uint16_t buf;//检测中断线的标志if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET ){buf = USART_ReceiveData(USART1);USART_SendData(USART1, buf);//判端是否将数据发送完while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//清除中断标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

5.1、方法一:重定向 fputc()

修改 ==fputc()==函数,将 printf() 内的内容通过串口输出给上位机,通过上位机的串口软件查看该内容

int fputc(int ch, FILE *f)
{ USART_SendData(USART1, ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return ch;
}

5.2、方法二:将字符串分割成一个一个字符发送出去

//传入的参数是字符串
void uart_str(char *str)
{uint16_t word; //因为标准库中函数 USART_ReceiveData() 返回的数据类型是 uint16_t,所以参数尽量采用相同的数据类型  char buf[20];  //存放 strstrcpy(buf, str);for(int i = 0; i < 20; i++){word = buf[i];  USART_SendData(USART1, word);   //第二个参数其实是 ASCII 码,所以在上一行代码中将对应的字母的 ASCII 码传给 worddelay_ms(2);   //必须要延时,否则来不及把所有数据发送到串口造成发送缺漏}
}

效果

上位机的串口软件每隔 500ms 接受一句“hello world”

附源码

//uart_printf.c#include "stm32f4xx.h"
#include <stdio.h>int fputc(int ch, FILE *f)
{ USART_SendData(USART1, ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return ch;
}void usart1_init(void){GPIO_InitTypeDef   GPIO_InitStructure;USART_InitTypeDef     USART_InitStruct;NVIC_InitTypeDef   NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);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_InitStructure.GPIO_Pin   = GPIO_Pin_9;              //引脚编号GPIO_Init(GPIOA, &GPIO_InitStructure);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_InitStructure.GPIO_Pin   = GPIO_Pin_10;             //引脚编号GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitStruct.USART_BaudRate = 9600;                        //波特率   USART_InitStruct.USART_WordLength = USART_WordLength_8b;   //数据位USART_InitStruct.USART_StopBits = USART_StopBits_1;           //停止位USART_InitStruct.USART_Parity = USART_Parity_No;          //校验位USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//模式 发送 + 接收USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_Init(USART1, &USART_InitStruct);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        USART_Cmd(USART1, ENABLE);/* Enable and set EXTI Line0 Interrupt 配置中断优先级*/NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;            //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;        //响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //使能通道NVIC_Init(&NVIC_InitStructure);
}void delay_ms(uint16_t nms){//systick 的频率 21MHz 21次 1us, 21000次 1ms, SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);SysTick->CTRL = 0;                         //使能时钟SysTick->LOAD = 21000*nms-1;          //计数值 SysTick->VAL = 0;                         //清除计数标志 //SysTick->CTRL |= (1<<0);                       //使能时钟SysTick->CTRL = 1;while ((SysTick->CTRL & 0x00010000)==0);//等待计数标志被置 1SysTick->CTRL = 0;                         //失能 systickSysTick->VAL = 0;                       //清除计数标志
}int main()
{//1.串口初始化usart1_init();//2.进入死循环while(1){printf("hello world \n");delay_ms(500);}
}//中断服务函数
void USART1_IRQHandler(void)
{uint16_t buf;//检测中断线的标志if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET ){buf = USART_ReceiveData(USART1);USART_SendData(USART1, buf);//判端是否将数据发送完while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//清除中断标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

STM32串口输出字符串相关推荐

  1. stm32 串口输出 中文乱码

    使用hal库函数 情况: 在使用串口输出中英文混合字符时, 遇到了英文和数字正常显示, 中文出现乱码的情况, 进一步查看,发现串口调试助手显示16进制时,相同位置中文和乱码的16进制都是一样的,所以并 ...

  2. 基于stm32cubeMX的stm32串口输出的Protues仿真

    stm32cubeMX设置 RCC时钟配置使用外部晶振 SYS配置 "Serial Wire" 时钟树配置 8M晶振经过 PLL产生72M的时钟:串口1挂在APB2时钟线上,其他串 ...

  3. 瑞萨单片机boot程序中串口打印字符串乱码-问题记录

    MCU型号: R7F0C004 编辑软件:CS+ for CC 在boot工程中,通过串口打印字符串,例如调用UART2_Send_String("uart output test!\r\n ...

  4. STM32 串口DMA接收 Openmv / K210 整数、小数字符串数据 (基于HAL库)

    目录 前言 一.工程配置 二.串口DMA部分代码 1.源文件UART_DMA.c 2.头文件UART_DMA.h 3.stm32f1xx_it.c的修改 4.串口收发DMA测试 三.字符串数字提取代码 ...

  5. STM32 汇编程序——串口输出 Hello world

    文章目录 一.UART介绍 二.项目建立及编译 1.新建项目 2.代码 3.编译 三.电路连接及烧录 1.串口连接 2.烧录 四.串口输出 五.总结 参考链接 一.UART介绍 通用同步异步收发器(U ...

  6. STC51和STM32使用串口输出中文乱码问题解决

    STC51和STM32使用串口输出中文乱码问题解决 问题描述:在进行串口实验时,我们想通过串口调试助手来输出中文信息, 但是我们经常会发现在串口调试助手上会输出乱码,跟我们预期的中文信息不符,见以下图 ...

  7. 嵌入式系统串口解析二进制数_关于串口的字符串输出和二进制数据流输出

    串口输出的类型主要分为单字节 字符串和二进制数据流,它们的控制输出函数各不相同. Windows系统里面,每行结尾是" ",即"\r\n" #define CR ...

  8. STM32获取GY-25A倾角传感器串口输出数据

    STM32获取GY-25A倾角传感器串口输出数据 GY-25A模块是新型的倾角传感器模块,具有X和Y两轴模拟角度输出和串口角度输出的功能.这里介绍STM32获取GY-25A串口输出的角度数据.(获取模 ...

  9. STM32驱动矩阵键盘串口输出

    原理:矩阵键盘的原理就是分行和列扫描,来获知按键的行数和列数,然后得到按键的键值.(按键按下时) 矩阵原理图 效果视频演示 STM32驱动矩阵键盘串口输出 硬件部分 f103c8t6核心板 4*4矩阵 ...

最新文章

  1. nginx 访问控制之 认证
  2. CRM WebClient UI里word文档调用web service的问题
  3. 谈谈对IOC及DI的理解与思考
  4. 【iOS开发】带有 Extension Target 的 App,如何签名打包
  5. git推送出现fatal: the remote end hung up unexpectedly
  6. 大数据平台目前存在的问题
  7. 让人死去活来的cocos2d-x安卓开发环境搭建(windows+eclipse+ndk 不用cygwin)【上图】
  8. 中国智能座舱行业发展前景展望与投资战略规划研究报告2022年版
  9. highcharts 解决数据提示框展示的内容太多 ,部分内容无法显示的问题
  10. 抖音内测语音直播交友 能够用声音打开社交的一扇门吗?
  11. ubuntu18.04通过deb文件安装软件
  12. 盘点免费好用的5款思维导图工具
  13. 点阵发光管怎么用C语言编程,LED点阵经验各种点阵驱动方法讲解
  14. 360手机如何修改服务器,360路由器手机怎么设置_手机如何设置360路由器? - 192路由网...
  15. 2021最新 深圳互联网公司排名
  16. Verilog编程之乘法器的实现
  17. linux trac apache,Linux环境下安装trac图文教程
  18. 这时的我已经激动的连话都说不出来了
  19. Linux服务器配置与管理:Linux基础
  20. Jekyll(二). Liquid 模板语言

热门文章

  1. vue 点赞+收藏 图标
  2. 【2389. 和有限的最长子序列】
  3. Java Web实现用户注册页面的提交
  4. 如何用Git将代码上传到GitHub
  5. TCP与UDP的区别!
  6. JS 轻松搞定数据处理,让前端开发更高效
  7. 标量、向量和矩阵的求导法则
  8. Invocation Target Exception调用目标异常可能是参数漏传
  9. PHP解决中文乱码问题
  10. 2023年Java面试题大全(最新版版)面试题附答案详解,看完BTA可进