前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >STM32F407Z 模拟串口(115200波特率)

STM32F407Z 模拟串口(115200波特率)

作者头像
知否知否应是绿肥红瘦
发布于 2025-02-19 13:14:42
发布于 2025-02-19 13:14:42
14800
代码可运行
举报
文章被收录于专栏:Linux知识Linux知识
运行总次数:0
代码可运行

PCB板打样回来发现串口1 TXD 和RXD 与CH340的TXD RXD没有交叉相连,导致串口1无法使用,于是将错就错,采用模拟串口的方式弥补了这个错误。波特率可达115200,支持printf函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "stdio.h"

#define TX_L() GPIO_ResetBits(GPIOA, GPIO_Pin_10)
#define TX_H() GPIO_SetBits(GPIOA, GPIO_Pin_10)
#define RX_READ() (GPIOA->IDR & GPIO_Pin_9)

u8 recvData=0;//!<接收的一个字节数据,全局变量
u32 delayTime = 8;	//1000000/115200=8.6us  
/*!
 * @brief 	模拟串口1 TX IO口配置
 * @param	none
 * @return	none
 * @note	Tx(PA10)
 */
void MUSART1_TX_init(void)
{  
    GPIO_InitTypeDef GPIO_InitStructure;
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_10);//TXD 空闲状态是高电平
}

/*!
 * @brief 	模拟串口1 RX IO口配置
 * @param	none
 * @return	none
 * @note	Rx(PA9)
 */
void MUSART1_RX_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//!<外部中断时钟
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource9);

    EXTI_InitStructure.EXTI_Line=EXTI_Line9;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿中断
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x2; //抢占优先级 2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
/*!
 * @brief	定时器14初始化
 * @param   定时器14复位后时钟=168M/2=84M
 * @return	NONE
 * @note	8us定时器,用于串口数据采样
 */
void Time14Init(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimerBaseStruct;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);//!<时钟使能
    TIM_DeInit(TIM14);					//!<Time1定时器重设缺省值
    TIM_TimerBaseStruct.TIM_Period=8;//!<设置重载寄存器初值 (设置为7,即:定时8us)
    TIM_TimerBaseStruct.TIM_Prescaler=83; 	//!<使用42M时钟,T=(83+1)*(7+1) /84= 8us
    TIM_TimerBaseStruct.TIM_ClockDivision=0;		//!<不分频
    TIM_TimerBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; //!<设置计数器向上计数模式
    TIM_TimeBaseInit(TIM14,&TIM_TimerBaseStruct);


    NVIC_InitStructure.NVIC_IRQChannel=TIM8_TRG_COM_TIM14_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//定时器优先级一定要最高
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
	
    TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update);
    TIM_ITConfig(TIM14,TIM_IT_Update,ENABLE);  		//!<使能TIM1中断源
    TIM_Cmd(TIM14,DISABLE);                     	//!<禁能TIM1定时器
}

/*!
 * @brief 	模拟串口1发送一个字节
 * @param
 * @return	none
 * @note	数据低位在前高位在后
 */
void MUSART1_SendData(u8 data)//发送一个数据
{
    u8 i = 0;
    TX_L();		//!<起始位
    delay_us(delayTime);
    for(i = 0; i < 8; i++) 
	  {
        if(data & 0x01)
            TX_H();
        else
            TX_L();
        delay_us(delayTime);
        data >>= 1;
    }
    TX_H();		//!<停止位
    delay_us(delayTime);
}

u8 RevSucc=0;//接收完成标志位
u8 MUSART1_ReadData(void)//接收一个数据
{
  while(RevSucc==0){};
	RevSucc=0;
  return  recvData;
}

/*!
 * @brief	串口接收IO中断处理函数
 * @param	none
 * @return	NONE
 * @note	none
 */
void EXTI9_5_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line9) != RESET) 
		{		
			  EXTI->IMR &= 0<<9;//关闭EXTI_Line9上的中断(如果要开启中断,则反操作即可)				
        if(RX_READ() == 0x00)
				{            
                recvData = 0; 
                TIM_SetCounter(TIM14,0);	
                TIM_Cmd(TIM14, ENABLE);	//打开定时器,接收数据							  						 
        }    
        EXTI_ClearITPendingBit(EXTI_Line9);	
        
    }
}

/*!
 * @brief	定时器14中断处理函数
 * @param
 * @return	NONE
 * @note
 */

u8 count=0;

void TIM8_TRG_COM_TIM14_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM14, TIM_IT_Update) != RESET)
    {  		  	  
        if(RX_READ())
        {
            recvData |= (1 << count);//读RX电平
        }
				count++;
				if(count==8)//数据读取完成
        {
            TIM_Cmd(TIM14, DISABLE);//!<关闭定时器
					  count = 0;				
					  RevSucc=1;//接收完成				  
					  EXTI->IMR|=1<<9; //开启外部中断 准备下一次接收       
        }					   
        TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update);
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef SIMULATION_USART1_H
#define SIMULATION_USART1_H


void MUSART1_TX_init(void);
void MUSART1_RX_init(void);
void Time14Init(void);
void MUSART1_SendData(u8 data);
u8 MUSART1_ReadData(void);



#endif
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/****************************************************************/
/*名称: fputc */
/*功能: 重定向Printf*/
/*输入: 无*/
/*输出: 无*/
/**/
/****************************************************************/
int fputc(int ch, FILE *f)
{
    //while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
   // USART1->DR = (u8) ch;
	  MUSART1_SendData(ch);
    return ch;
}
完整MDK工程下载:https://download.csdn.net/download/qq_24835087/12025936
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
STM32 F4串口接收中断
.c文件中: void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_Ini
小锋学长生活大爆炸
2020/08/13
1.2K0
【STM32】串口通信---用代码与芯片对话
文章目录 前言 一、串口通信基本知识 二、编程思路 usart.h usart.c main.c 宏定义 三、总结 前言 开发板:stm32f407VET6 开发环境:keil5 MDK 一、串口通信基本知识 【STM32】5分钟了解STM32的串口通信 二、编程思路 usart.h // ============================================= # @Time : 2020-09-03 # @Author : AXYZdong # @CSDN : http
AXYZdong
2020/11/05
8920
(十九)STM32——输入捕获
目录 学习目标 成果展示 内容 获取 配置 代码 总结  ---- 学习目标         本节内容我们要介绍的是输入捕获,其实也和定时器那部分知识是有关系的,所谓输入捕获,通俗一点来讲,其实就是通过检测上升沿和下降沿来计算你的输入持续时间。具体怎么去检测和捕获呢?我们来慢慢介绍。 成果展示 https://live.csdn.net/v/embed/231933 输入捕获实验 内容         关于输入捕获呢,我们主要分成4个部分来介绍,先拆分来理解,再综合在一起理解。      
小点点
2022/12/12
1.1K0
(十九)STM32——输入捕获
基于STM32F4单片机对步进电机的控制(有代码)「建议收藏」
步进电机是将电脉冲控制信号转变为角位移或线位移的一种常用的数字控制执行元件,又称为脉冲电机。在驱动电源的作用下,步进电机受到脉冲的控制,其转子的角位移量和速度严格地与输入脉冲的数量和脉冲频率成正比。步进电机每接收一个电脉冲,转子就转过一个相应的角度(步距角)。**改变通电顺序可改变步进电动机的旋转方向;改变通电频率可改变步进电动机的转速。**因此,通过控制输入电脉冲的数目、频率及电动机绕组的通电顺序就可以获得所需要的转角、转速及转向,利用单片机就可以很容易实现步进电机的开环数字控制。 传统的步进电机控制方法是由触发器产生控制脉冲来进行控制的,但此种控制方法工作方式单一而且难于实现人机交互,当步进电机的参数发生变化时,需要重新进行控制器的设计。因此适合于单片机控制,单片机通过向步进电机驱动电路发送控制信号就能实现对步进电机的控制。
全栈程序员站长
2022/08/23
9.3K2
基于STM32F4单片机对步进电机的控制(有代码)「建议收藏」
STM32F4 SPI DMA
张贴的代码显示如何配置我的GPIO,定时器,SPI, DMA和NVIC模块,以及一些系统如何工作的解释。 注意,我使用的是STM32F4标准外设库。
小锋学长生活大爆炸
2020/09/24
2.2K0
STM32F4 SPI DMA
104-CH32V307(WCH单片机)学习开发-串口
串口1 void uart_init(u32 bound1){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_USART1|RCC_APB
杨奉武
2022/05/25
1.4K1
104-CH32V307(WCH单片机)学习开发-串口
STM32F103系列串口1中断回显
用户11186929
2024/07/01
1270
STM32F103RCT6+串口DMA方式接收定长数据
知否知否应是绿肥红瘦
2025/02/19
2450
STM32F103RCT6+串口DMA方式接收定长数据
(十三)STM32——串口通信(UART)
目录 学习目标 内容 通信方法 并行通信 串行通信 通信方向 通信方式  UART 特点 串口参数 通信流程 寄存器 USART_SR USART_DR  USART_BRR 过程 代码 运行结果 运行结果 遇到的问题 总结  ---- 学习目标         本节我们要学习的的是STM32的通信部分,主要介绍UART(通用异步收发器),是一种异步、全双工的通信方式。 内容         首先,我们先来介绍一下通信的基本知识,之前在51单片机的学习中我们也接触过UART,在此就不做详细介绍,感兴
小点点
2022/12/12
1.9K0
(十三)STM32——串口通信(UART)
stm32之串口通信
在基础实验成功的基础上,对串口的调试方法进行实践。硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中。
用户6754675
2020/02/21
1.1K0
(33)STM32——485实验笔记
目录 学习目标 内容 串口  485 特点 收发器 配置 代码 总结  ---- 学习目标         本节内容我们要学习的是485通信,这个是在51上没有的,但是知识不是特别复杂,而且和我们之前学的串口知识是相似的。 内容 串口  串口是一种接口标准,它规定了接口的电气标准,简单说只是物理层的一个标准。没有规定接口插件电缆以及使用的协议,所以只要我们使用的接口插件电缆符合串口标准就可以在实际中灵活使用,在串口接口标准上使用各种协议进行通讯及设备控制。 典型的串行通讯标准是RS232和RS485
小点点
2022/12/12
6400
(33)STM32——485实验笔记
STM32F103系列串口2中断回显
用户11186929
2024/07/01
1800
stm32电机控制之控制两路直流电机!看完你会了吗
小车使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制,这里电机使用PWM驱动,速度控制框图如下:
用户6754675
2019/12/12
3.6K0
(24)STM32——待机唤醒(低功耗)笔记
        这三种模式的功耗是逐渐降低的,特别是待机模式,功耗特别低,最低只需要 2.2uA 左右的电流。停机模式是次低功耗的,其典型的电流消耗在 350uA 左右。最后就是睡眠模式了。根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式。
小点点
2022/12/12
1.6K0
(24)STM32——待机唤醒(低功耗)笔记
STM32F103系列串口3中断回显
用户11186929
2024/07/01
1350
STM32F407-USART3+DMA空闲中断收发
用户11186929
2024/07/01
3940
FreeRTOS例程4-串口DMA收发不定长数据
DMA(Direct Memory Access),即直接内存存储,在一些数据的传输中,如串口、SPI等,采用DMA方式,传输过程不需要CPU参与,可用让CPU有更多的时间处理其他的事情。
xxpcb
2020/08/04
2.9K0
单片机(MCU)如何才能不死机之串口Overrun
它是可以在 STM32F030 上调试通过的串口收发测试程序,发送采用延时循环,接收采用中断,接收到的数据存入缓冲区。
用户2366192
2021/05/31
1.3K0
(35)STM32——红外遥控实验
https://blog.csdn.net/weixin_66578482/article/details/126141850        这一篇笔记对红外遥控进行了详细的介绍,感兴yxky'x'k 
小点点
2022/12/12
7170
STM32单片机-输入捕获、FFT测频
​本内容介绍基于STM32F103VET6的一个实际工程中添加采集A相电压信号或B相电流信号频率的功能,分别通过输入捕获与FFT实现,均测试可用。持续更新,原创不易!
爱上电路设计
2024/05/28
3710
STM32单片机-输入捕获、FFT测频
推荐阅读
相关推荐
STM32 F4串口接收中断
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档