STM32F4VGT6-DISCOVERY:uart1驱动

对于这款板子,官方并没有提供串口例程,只能自行添加。

一、PA9/PA10复用成串口1功能不可用

驱动测试代码如下:

main.c:

#include "main.h"
#include <stdio.h>void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//GPIO口时钟使能, 引脚PA9,PA10可以复用为串口功能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PA9+PA10]GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}int main(void)
{usart1_init();while(1){;}return 0;
}

固件烧录后,连接PC端串口工具,串口收发功能不可用。原因:PA9/PA10设计给板载USB使用,打开原理如下:

所以,只能换一组GPIO,换成PB6/PB7(原理图上可确认没有其他外设使用),测试代码如下:

#if 0
void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//GPIO口时钟使能, 引脚PA9,PA10可以复用为串口功能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PA9+PA10]GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}#else
void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PB6+PB7]GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;STM_EVAL_LEDOn(LED4);//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来STM_EVAL_LEDOn(LED5);USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}
#endifint main(void)
{usart1_init();while(1){;}return 0;
}

板子实物图连接如下:

串口工具测试如下:

二、串口标准输入输出重定向打印实现

直接重写标准输入输出函数的底层接口即可,如下:

//重写printf底层函数接口

int fputc(int c, FILE *stream)

{

  USART1->DR=c; //发送一个字符

  while(!(USART1->SR&1<<7)){}

return c;

}

//重写scanf底层函数接口

int fgetc(FILE *stream)

{

  while(!(USART1->SR&1<<5)){}

    return USART1->DR;

}

烧录固件,并按reset键,观察串口调试助手上的打印:使用ST-LINK的方式进行烧录

串口助手:

三、完整代码

usart.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include <stdio.h>void usart1_init(uint32_t BaudRate)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PB6+PB7]GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = BaudRate;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}//重写printf底层函数接口
int fputc(int c, FILE *stream)
{USART1->DR=c; //发送一个字符while(!(USART1->SR&1<<7)){}return c;
}//重写scanf底层函数接口
int fgetc(FILE *stream)
{while(!(USART1->SR&1<<5)){}return USART1->DR;
}/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

usart.h

#ifndef __USART__H__
#define __USART__H__void usart1_init(uint32_t BaudRate);#endif /* __USART__H__ */

main.c

#include "usart.h"
#include <stdio.h>int main(void)
{usart1_init(115200);printf("hello world!\n");while(1){;}return 0;
}

注:这款Discovery开发板是基于标准外设库函数来开发的,因此工程中要把串口相关的库函数文件添加进来,如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/151553.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CAN接口的PCB Layout规则要求汇总

随着时代高速发展&#xff0c;控制器局域网&#xff08;CAN&#xff09;接口的应用越来越广泛&#xff0c;尤其是在汽车电子、航空航天等领域中发挥着重要作用&#xff0c;为了确保CAN接口的可靠性和稳定性&#xff0c;工程师必须在其PCB Layout方面下功夫&#xff0c;下面来看…

JVM虚拟机:Java对象的头信息有什么?

本文重点 在前面的课程中,我们学习了对象头,其中对象头包含Mark Word和class pointer,当然数组还会有一个数组长度。本文主要分析Mark Work中包含的信息。 Mark Word 以下两张图是一个意思: 32位 32位 64位 以上就是Mark Word会存储的信息,这个意思是说Java对象在不同…

FPGA时序分析与约束(7)——通过Tcl扩展SDC

一、概述 术语“Synopsys公司设计约束”&#xff08;又名SDC&#xff0c;Synopsys Design Constraints&#xff09;用于描述对时序、功率和面积的设计要求&#xff0c;是EDA工具中用于综合、STA和布局布线最常用的格式。本文介绍时序约束的历史概要和SDC的描述。 二、时序约束…

node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)

文章目录 ⭐前言⭐ 环境准备⭐ 实现过程⭐ mysql 配置⭐路由前的准备⭐账号注册生成token⭐账号登录生成token⭐token登录 ⭐ 自测过程截图⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node实战——后端koa项目配置jwt实现登录注册&#xff08;n…

VScode 自定义主题各参数解析

参考链接&#xff1a; vscode自定义颜色时各个参数的作用(史上最全)vscode编辑器&#xff0c;自己喜欢的颜色 由于 VScode 搜索高亮是在是太不起眼了&#xff0c;根本看不到此时选中到哪个搜索匹配了&#xff0c;所以对此进行了配置&#xff0c;具体想增加更多可配置项可参考…

windows + ubuntu + vscode开发环境配置安装

一、卸载WSL/WSL2 如果安装了windows子系统的朋友&#xff0c;可以选择继续使用。或者提前卸载WSL&#xff0c;再选择安装虚拟机。虚拟机占用内存较大&#xff0c;WSL可能对于开发的一些需求还有欠缺。根据自己的实际情况进行选择。 WIN10/11安装WSL(请参考官方资料&#xff0c…

nvm的安装和使用

nvm用途 nvm是用来管理node版本的,安装成功之后可以去切换自己的node版本,就不需要通过安装卸载不同版本的node包 下载与安装 下载地址是https://github.com/coreybutler/nvm-windows/releases 下载nvm-setup.zip,然后安装就可以了 默认路径是C:\Users\wangjingtao\AppData\…

NPM【问题 01】npm i node-sass@4.14.1报错not found: python2及Cannot download问题处理

node-sass安装问题处理 1.问题2.处理2.1 方案一【我的环境失败】2.2 方案二【成功】2.3 方案三【成功】 1.问题 gyp verb which failed Error: not found: python2 # 1.添加Python27的安装路径到环境变量 gyp verb check python checking for Python executable "python…

C#WinformListView实现缺陷图片浏览器

C#&Winform&ListView实现缺陷图片浏览器 功能需求图像浏览行间距调整悬浮提示 功能需求 机器视觉检测系统中特别是缺陷检测系统&#xff0c;通常需要进行对已经检出的缺陷图片进行浏览查阅。主要是通过条件筛选查询出所需要的数据&#xff0c;进行分页再展示到界面中。…

财务数字化转型是什么?_光点科技

财务数字化转型是当今企业发展中的一项关键策略&#xff0c;旨在借助先进的数字技术&#xff0c;重新塑造和优化财务管理体系&#xff0c;以适应迅速变化的商业环境。这一转型不仅仅是技术的升级&#xff0c;更是对企业财务理念和流程的全面升级和改革。 财务数字化转型的核心在…

5.OsgEarth加载地形

愿你出走半生,归来仍是少年&#xff01; 在三维场景中除了使用影像体现出地貌情况&#xff0c;还需要通过地形体现出地势起伏&#xff0c;还原一个相对真实的三维虚拟世界。 osgEarth可通过直接加载Dem数据进行场景内的地形构建。 1.数据准备 由于我也没有高程数据&#xff0c…

云服务器搭建Zookeeper集群

文章目录 1.集群配置2.zookeeper的群起脚本3. Zookeeper节点的创建和删除相关4. Zookeeper的选举机制 1.集群配置 Zookeeper的集群个数最好保证是奇数个数&#xff0c;因为Zookeeper的选举过程有一个“半数机制”。 5台服务器&#xff0c;可以设置Zookeeper的集群为3或者5&…