【STM32单片机_(HAL库)】4-3-1【定时器TIM】串口打印功能打开

news2024/12/25 12:22:45

1.硬件

  • STM32单片机最小系统
  • CH340模块

2.软件

  • main.c程序
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    led_init();                         /* 初始化LED灯 */
    uart1_init(115200);
    printf("hello world!\r\n");

    while(1)
    { 
        led1_on();
        led2_off();
        delay_ms(500);
        led1_off();
        led2_on();
        delay_ms(500);
    }
}


  • uart1.c程序
#include "sys.h"
#include "uart1.h"
#include "string.h"

UART_HandleTypeDef uart1_handle;                                            /* UART1句柄 */

uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE];                                    /* UART1接收缓冲区 */
uint16_t uart1_rx_len = 0;                                                  /* UART1接收字符长度 */

/**
 * @brief       重定义fputc函数
 * @note        printf函数最终会通过调用fputc输出字符串到串口
 */
int fputc(int ch, FILE *f)
{
    while ((USART1->SR & 0X40) == 0);                                       /* 等待上一个字符发送完成 */

    USART1->DR = (uint8_t)ch;                                               /* 将要发送的字符 ch 写入到DR寄存器 */
    return ch;
}

/**
 * @brief       串口1初始化函数
 * @param       baudrate: 波特率, 根据自己需要设置波特率值
 * @retval      无
 */
void uart1_init(uint32_t baudrate)
{
    /*UART1 初始化设置*/
    uart1_handle.Instance = USART1;                                         /* USART1 */
    uart1_handle.Init.BaudRate = baudrate;                                  /* 波特率 */
    uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;                      /* 字长为8位数据格式 */
    uart1_handle.Init.StopBits = UART_STOPBITS_1;                           /* 一个停止位 */
    uart1_handle.Init.Parity = UART_PARITY_NONE;                            /* 无奇偶校验位 */
    uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;                      /* 无硬件流控 */
    uart1_handle.Init.Mode = UART_MODE_TX_RX;                               /* 收发模式 */
    HAL_UART_Init(&uart1_handle);                                           /* HAL_UART_Init()会使能UART1 */
}

/**
 * @brief       UART底层初始化函数
 * @param       huart: UART句柄类型指针
 * @note        此函数会被HAL_UART_Init()调用
 *              完成时钟使能,引脚配置,中断配置
 * @retval      无
 */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;

    if (huart->Instance == USART1)                                          /* 如果是串口1,进行串口1 MSP初始化 */
    {
        __HAL_RCC_GPIOA_CLK_ENABLE();                                       /* 使能串口TX脚时钟 */
        __HAL_RCC_USART1_CLK_ENABLE();                                      /* 使能串口时钟 */

        gpio_init_struct.Pin = GPIO_PIN_9;                                  /* 串口发送引脚号 */
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;                            /* 复用推挽输出 */
        gpio_init_struct.Pull = GPIO_PULLUP;                                /* 上拉 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;                      /* IO速度设置为高速 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
                
        gpio_init_struct.Pin = GPIO_PIN_10;                                 /* 串口RX脚 模式设置 */
        gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;    
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);                            /* 串口RX脚 必须设置成输入模式 */
        
        HAL_NVIC_EnableIRQ(USART1_IRQn);                                    /* 使能USART1中断通道 */
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                            /* 组2,最低优先级:抢占优先级3,子优先级3 */

        __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);                          /* 使能UART1接收中断 */
        __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);                          /* 使能UART1总线空闲中断 */
    }
}

/**
 * @brief       UART1接收缓冲区清除
 * @param       无
 * @retval      无
 */
void uart1_rx_clear(void)
{
    memset(uart1_rx_buf, 0, sizeof(uart1_rx_buf));                          /* 清空接收缓冲区 */
    uart1_rx_len = 0;                                                       /* 接收计数器清零 */
}

/**
 * @brief       串口1中断服务函数
 * @note        在此使用接收中断及空闲中断,实现不定长数据收发
 * @param       无
 * @retval      无
 */
void USART1_IRQHandler(void)
{
    uint8_t receive_data = 0;   
    if(__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_RXNE) != RESET){        /* 获取接收RXNE标志位是否被置位 */
        if(uart1_rx_len >= sizeof(uart1_rx_buf))                            /* 如果接收的字符数大于接收缓冲区大小, */
            uart1_rx_len = 0;                                               /* 则将接收计数器清零 */
        HAL_UART_Receive(&uart1_handle, &receive_data, 1, 1000);            /* 接收一个字符 */
        uart1_rx_buf[uart1_rx_len++] = receive_data;                        /* 将接收到的字符保存在接收缓冲区 */
    }

    if (__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_IDLE) != RESET)        /* 获取接收空闲中断标志位是否被置位 */
    {
        printf("recv: %s\r\n", uart1_rx_buf);                               /* 将接收到的数据打印出来 */
        uart1_rx_clear();
        __HAL_UART_CLEAR_IDLEFLAG(&uart1_handle);                           /* 清除UART总线空闲中断 */
    }
}

  • uart1.h程序
#ifndef __USART_H__
#define __USART_H__

#include "stdio.h"
#include "sys.h"

/* 错误代码 */
#define UART_EOK                     0      /* 没有错误 */
#define UART_ERROR                   1      /* 通用错误 */
#define UART_ETIMEOUT                2      /* 超时错误 */
#define UART_EINVAL                  3      /* 参数错误 */

/* UART收发缓冲大小 */
#define UART1_RX_BUF_SIZE            128
#define UART1_TX_BUF_SIZE            64


void uart1_init(uint32_t bound);            /* 串口初始化函数 */

#endif

3.实物效果

  • 硬件模块接线
    CH340—>STM32
    RX—>PA9(TX1)
    TX—>PA10(RX1)
    ST-Link下载方式
  • 实验现象
    STM32连接CH340,并连接到电脑,打开串口软件,选择串口号,并设置波特率,点击打开串口。可以看到串口打印hello world。
    在这里插入图片描述

串口打印功能实现keil源文件

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见的RTSP播放器有哪些?

VLC播放器 特点:VLC 是一款功能强大、跨平台的多媒体播放器,支持多种音频和视频格式以及流媒体协议,包括 RTSP。它具有广泛的解码器支持,能播放大多数常见的视频和音频格式。其开源特性使得它拥有活跃的开发者社区,不断…

【教学类-59-01】20241001双面五星红旗国旗(中2班)

背景需求: 国庆在即,怎么能不做一面五星红旗呢? 【教学类-39】A4红纸-国旗灯笼纸模(庆祝中华人民共和国成立74周年)_a4 打印 灯笼-CSDN博客文章浏览阅读626次。【教学类-39】A4红纸-国旗灯笼纸模(庆祝中华…

车辆重识别(注意力 U-Net:学习在哪些区域寻找胰腺)论文阅读2024/10/01

什么是注意力机制? 什么是加性注意力? 大致说一下流程: 对于一张特征图来说,对于这张图中的每一个像素向量(例如a),计算该向量与所有像素向量的相似度,对这些相似度进行激活函数…

nvm实现nodejs版本管理

nvm相关操作 1. nvm的作用2. 下载nvm之前的操作3. 下载nvm3.1 zip不同的名称区别 4. 验证是否安装成功5. 配置镜像,提高下载速度6. 安装nodeJS7. 查看目前已经安装的版本8.安装成功后npm无法使用9. 卸载指定node版本10. 切换node版本11.NVM常用命令 1. nvm的作用 nvm是一个方便…

24-10-1-读书笔记(二十一)-《契诃夫文集》(四)下([俄] 契诃夫 [译] 汝龙) 我爱你,娜坚卡。

文章目录 《契诃夫文集》(四)下([俄] 契诃夫 [译] 汝龙 )目录阅读笔记记录总结 《契诃夫文集》(四)下([俄] 契诃夫 [译] 汝龙 ) 十月第一篇,放假了,挺高兴的&…

如何使用SCCMSecrets识别SCCM策略中潜在的安全问题

关于SCCMSecrets SCCMSecrets是一款针对SCCM策略的安全扫描与检测工具,该工具旨在提供一种有关 SCCM 策略的全面安全检测方法。 该工具可以从各种权限级别执行,并将尝试发现与策略分发相关的潜在错误配置。除了分发点上托管的包脚本外,它还将…

螺狮壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习01(环境准备)

1 准备工作 由于创建数据中心需要安装很多服务器,这些服务器要耗费很所物理物理计算资源、存储资源、网络资源和软件资源,作为穷学生只有几百块的n手笔记本,不可能买十几台服务器来搭建数据中心,也不愿意跑实验室,想躺…

信息安全数学基础(23)一般二次同余式

前言 信息安全数学基础中的一般二次同余式是数论和密码学中的一个重要概念,它涉及到了二次方程、模运算以及同余关系等多个方面。 一、定义 设m是正整数,a,b,c是整数,且a0,则形如ax2bxc≡0(modm)的同余式称为模m的二次同余式。…

Git傻傻分不清楚(上)

环境:Idea2022.3.3、Git(忘辽~) 怎么上传自己的项目到Github上? Idea和Github进行账号关联将项目上传到本地仓库(Commit)将本地仓库中的项目上传到Github上(Push) 一、关联账号 …

移动应用中提升用户体验的因素

用户体验(UX)是任何移动应用程序成功的关键因素。随着数以百万计的应用程序争夺注意力,提供无缝、愉快和高效的体验可能是获得忠实用户或在一次互动后失去忠实用户之间的区别。无论是商业应用程序、游戏还是社交平台,增强用户体验…

TypeScript 封装 Axios 1.7.7

随着Axios版本的不同,类型也在改变,以后怎么写类型? 1. 封装Axios 将Axios封装成一个类,同时重新封装request方法 重新封装request有几个好处: 所有的请求将从我们定义的requet请求中发送,这样以后更换…

WebRTC入门

主要参考资料: WebRTC 在 ESP32 系列硬件平台上的实现: https://www.bilibili.com/video/BV1AEHseWEda/?spm_id_from333.337.search-card.all.click&vd_sourcedd284033cd0c4d1f3f59a2cd40ae4ef9 火山 RTC豆包大模型,给用户体验装上银色子弹: https:…

第九篇——数列和级数(二):传销骗局的数学原理

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 文章不长,但是道理深刻;相邻两个数的差值&#xf…

Prompt 模版解析:诗人角色的创意引导与实践

Prompt 模版解析:诗人角色的创意引导与实践 Prompt 模版作为一种结构化工具,旨在为特定角色——本例中的“诗人”——提供明确的指导和框架。这一模版详尽地描绘了诗人的职责、擅长的诗歌形式以及创作规则,使其能在自动化系统中更加精确地执…

咸鱼sign逆向分析与爬虫实现

目标:🐟的搜索商品接口 这个站异步有点多,好在代码没什么混淆。加密的sign值我们可以通过搜索找到位置 sign值通过k赋值,k则是字符串拼接后传入i函数加密 除了开头的aff…,后面的都是明文没什么好说的,我…

学习记录:js算法(五十):二叉树的右视图

文章目录 二叉树的右视图我的思路网上思路 总结 二叉树的右视图 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 图一: 示例 1:如图一 输入: [1,2,3,null,5,null,4] …

uni-app #ifdef #ifndef #endif的使用和区别

1. uni-app #ifdef #ifndef #endif的使用和区别 条件编译是一种在编程中根据特定平台选择性编译代码的技术。如#ifdef和#endif根据APP-PLUS平台标识在微信小程序、支付宝小程序、百度小程序、头条小程序、QQ小程序以及H5应用中实现代码的平台特定执行。下面介绍了如何使用#ifde…

基于Java+SpringBoot3+vue3+uniapp点餐/外卖管理系统设计与实现(视频讲解)

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

微服务sentinel解析部署使用全流程

sentinel源码地址: 介绍 alibaba/Sentinel Wiki GitHub sentinel官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html Sprong Cloud alibaba Sentinel文档【小例子】 : Sentinel alibaba/spring-cloud-alibaba Wiki GitHub 目录 1、…

wsl(1) --- win11环境配置

1. 开启WSL可选功能 打开设置,点击应用,点击可选功能,点击更多Windows功能,查看是否开启了【适用于Linux的Windows子系统】和【虚拟机平台】 2. 更新wsl 不执行这步,启动wsl镜像时会出现WslRegisterDistribution f…