MSP432自主开发笔记3:串口__编写自定义printf发送函数、编写发送字节字符串函数编写

news2024/11/29 8:55:01

之前其实对于串口在收发字节、收发字符串方面的介绍已经挺完全了,

但今日无意间发现漏了些什么,之前有讲到过串口的printf()发送问题,但也仅仅教大家如何重定向printf();来决定向哪个串口发送数据.

printf();固然是个包容性很强、使用起来很方便的函数,但它却只有一个,无法满足多串口都能享受这么方便的发送方式~

因此我们需要更多类似的函数来满足多个串口更方便发送数据的需要!

此处提供俩种思路:

1.编写普通的串口字节、字符串发送函数

2.自定义类似于printf();发送函数的编写

本文教大家俩种思路的写法,文章提供源码、测试工程下载

目录

相关串口学习文章传送门:

一、普通的串口字节、字符串发送函数编写:

1.编写普通的串口字节、字符串发送函数:

2.自定义printf();发送函数的编写:

整体测试工程下载:


 

相关串口学习文章传送门:

基础串口收发的知识与配置在此我不做介绍了,没有学习熟悉的可以看下面有关串口的文章,我也许没有全部罗列出来,可以自行去专栏查找~~

MSP432学习笔记10:串口接收字符串命令并执行任务_msp432串口通信_NULL指向我的博客-CSDN博客

 MSP432学习笔记3:串口通信初步配置收发_msp432串口_NULL指向我的博客-CSDN博客

需要USB转串口模块(下图绿色盒子 )进行测试,因为除了串口A0其余都不是USB

 

一、普通的串口字节、字符串发送函数编写:

1.编写普通的串口字节、字符串发送函数:

这个十分简单,无需做过多介绍,此处直接写出实践目标1:

实践目标1:

1.配置初始化串口A1 波特率115200

2.不使用重定向的printf,编写基础的发送函数,使用A1串口发送ABCDEF....给上位机测试

关键代码如下:

//A~I的ascll码值
char str[9]={65,66,67,68,69,70,71,72,73};

//使用A1串口发送8bit的数据
//传入的参数是需要发送的8位的数据
void send_byte_A1(char Data_8bit)
{
	UART_transmitData(EUSCI_A1_BASE,Data_8bit);
}

//使用A1串口发送字符串
//传入的参数一个是字符串一个是字符串长度
void send_string_A1(char *str,char numb)
{
	char i,j;
	i=numb;
	for(i=0;i<numb;i++)
	{
	j=str[i];
	UART_transmitData(EUSCI_A1_BASE,j);
	}
}

主函数调用情况如下:

#include "main.h"

//A~I的ascll码值
char str[9]={65,66,67,68,69,70,71,72,73};


int main(void)
{
	  inint_all();   //初始化所有模块
    while (1)
    {
			
    }
}

//初始化所有模块
void inint_all(void)
{
    SysInit();                                  //时钟配置    
    delay_init();								 								//delay_ms函数配置
		uart_init(115200);				      //串口A0初始化
		uart_init_A1(115200);  			        //串口A1初始化
//	  printf("Hello,MSP432!\r\n");			//printf()向串口0打印测试字符
		send_string_A1(str,9);
		MAP_Interrupt_enableMaster();         // 开启总中断
}

下载测试成功效果图:

 介绍总结:

这样编写的基础收发函数固然可用,但需要在进制间与ASCLL码对照转换,十分不方便!

因此,本文后半段推出的自定义printf函数,就很好地解决这个问题!

2.自定义printf();发送函数的编写:

学习自定义格式化输出printf函数的书写,首先要隆重介绍一下库:#include "stdarg.h"

主要目的是为了函数接收可变参数里面含有4个标准宏

#ifdef __clang__
  typedef __builtin_va_list va_list;
  #define va_start(ap, param) __builtin_va_start(ap, param)
  #define va_end(ap)          __builtin_va_end(ap)
  #define va_arg(ap, type)    __builtin_va_arg(ap, type)
  #if __STDC_VERSION__ >= 199900L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
  #define va_copy(dest, src)  __builtin_va_copy(dest, src)
  #endif

- `va_list`

是一个用于存储可变参数的类型,可以将其理解为一个指向参数列表的指针。
- `va_start(ap, param)`

用于在可变参数函数中初始化 `va_list`,`ap` 是一个 `va_list` 类型的变量,`param` 是函数中最后一个固定参数的名称。
- `va_end(ap)`

用于结束可变参数函数的处理,释放 `va_list` 相关资源。
- `va_arg(ap, type)`

用于获取下一个可变参数的值,`ap` 是一个 `va_list` 类型的变量,`type` 是要获取的参数的类型。
- `va_copy(dest, src)`

用于将 `src` 复制到 `dest`,用于在可变参数函数中进行副本操作。

这些宏的作用是为了在可变参数函数中能够按需获取和操作参数列表的值。

关键代码:

#include "stdarg.h"  //别忘记添加这个头文件


#define USART2_TXBUFF_SIZE 25


//自定义printf函数输出

void printf_EUSCI_A1(char *fmt,...)
{
	 char buffer[USART2_TXBUFF_SIZE];   //USART2_TXBUFF_SIZE为外部定义发送的最大长度
	 int i = 0;
	 va_list arg_ptr; 
   va_start(arg_ptr, fmt); //初始化list
   vsnprintf(buffer, USART2_TXBUFF_SIZE+1, fmt, arg_ptr); //将数据返回到buffer
   	 while ((i < USART2_TXBUFF_SIZE) && buffer[i])
 	   {UART_transmitData(EUSCI_A1_BASE,(char)buffer[i++]);}
   va_end(arg_ptr);//arg_ptr为空释放内存
}

这个函数可以直接搬运了,想写别的串口的这种函数,全部复制,改名,改串口号即可!

 测试成功截图:

我们可以看到:自定义的printf函数(void printf_EUSCI_A1(char *fmt,...))与原汁原味的printf()是一样使用的!~~~

 

整体测试工程下载:

https://download.csdn.net/download/qq_64257614/88056594?spm=1001.2014.3001.5503

 

 希望对大家有帮助~~~~~

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

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

相关文章

代码随想录算法训练营第57天 | 动态规划 part17 ● 647 回文子串 ●516最长回文子序列 ●动归总结

#647 回文子串 自己不会做。 之前遇到的大部分题目是&#xff0c;我们求什么dp里面就放什么。但这道回文的题不是&#xff1a;" 本题如果我们定义&#xff0c;dp[i] 为 下标i结尾的字符串有 dp[i]个回文串的话&#xff0c;我们会发现很难找到递归关系。dp[i] 和 dp[i-1]…

自监督语义分割面模型——Masked Autoencoders Are Scalable Vision Learners(MAE)论文阅读

1、摘要 This paper shows that masked autoencoders (MAE) are scalable self-supervised learners for computer vision. Our MAE approach is simple: we mask random patches of the input image and reconstruct the missing pixels. It is based on two core designs. F…

实现二分搜索函数,设计脚手架程序进行自动测试。

1. 设计思路   二分搜索算法每次将数组中间值与目标值相比较&#xff0c;若相同&#xff0c;则该元素就是要寻找的元素&#xff0c;若不相同&#xff0c;二分搜索法通过一定的方法抛弃一半的待搜索区间&#xff0c;在剩余的区间中继续以相同方法搜索目标值. 2.源代码 #incl…

网络存储技术知识点整理

目录 前言1. 直接附加存储2. 网络附加存储3. 存储区域网络 前言 目前主流的存储技术只要有三种&#xff1a; 直接附加存储&#xff08;Direct Attached Storage&#xff0c;DAS&#xff09;网络附加存储&#xff08;Network Attached Storage&#xff0c;NAS&#xff09;存储…

flutter开发实战-Canvas绘图之Path路径动画

flutter开发实战-Canvas绘图之Path路径动画 flutter提供一块2D画布Canvas&#xff0c;Canvas内部封装了一些基本绘制的API&#xff0c;开发者可以通过Canvas绘制各种自定义图形。canvas上绘图&#xff0c;有多种不同的方式&#xff0c;常用的就是使用 Path。这里是flutter实现…

10分钟设置免费远程桌面

“你见过洛杉矶凌晨4点的样子吗&#xff1f;” 没有也没关系&#xff0c;你可以轻松配置一台位于洛杉矶的免费远程桌面。 利用Amazon全球可用区&#xff0c;甚至可以在世界各地搭建符合你配置需求的远程桌面。 本教程需要先拥有亚马逊云科技海外账户。目前注册亚马逊云科技账户…

32-ADC的寄存器

目录 stm32-adc通过比较获取电压原理 为什么会分注入组和规则组&#xff1f; “ECO"是指"Engineering Change Order”&#xff0c;即工程变更指令。 双ADC的不同模式以及为什么会有这个模式&#xff1a; 同步注入模式&#xff1a; 同步规则模式&#xff1a; 快…

应用系统的集成的方式

一、说明 应用系统的集成从技术上可以分为界面集成、数据集成、接口集成、流程集成和平台集成等多种方式。 二、详情 2.1界面集成 指的是系统与系统之间没有实质上的关联&#xff0c;只是汇聚到同样的应用接人点&#xff0c;采用类似的初始界面&#xff0c;或者统一的登录手…

IDEA修改新添加项目的Maven配置信息

改成自己的Maven环境即可 以后打开新项目都会自动哟用这个

【JDK环境配置】| 两种JDK环境能在同一台电脑共存吗?

目录 &#x1f981; 前言&#x1f981; 基础环境&#x1f981; 安装JDK1.8Ⅰ. 下载Ⅱ. 安装 &#x1f981; 在项目里更改JDK版本---------------------------------------------福利在下面--------------------------------------------------&#x1f981; 福利&#xff08;送…

一张表实现短视频“评论区“完整功能

前言 现如今&#xff0c;不管是哪种类型的应用&#xff0c;评论区都少不了。从工具类的到媒体信息流类的&#xff0c;评论留言都是最基本的互动环节。比如抖音短视频下&#xff0c;针对视频每个用户都可以发表自己的观点&#xff1b;而针对用户的评论&#xff0c;其他的用户又可…

小程序form表单验证,validate 在更新数据以后不能验证?还是提示同意错误

报错&#xff1a; 一直报手机号码必须填写&#xff0c;但是我已经填写了。 解决&#xff1a; 花了2个小时&#xff0c;最后发布是模式models写错了。 改完之后&#xff0c;终于提示别的错误了&#xff1a; 源码&#xff1a; //wxml <view class"welcome">欢…

【使用深度学习的城市声音分类】使用从提取音频特征(频谱图)中提取的深度学习进行声音分类研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

java正则表达式大全(常用)

一、校验数字的表达式 数字&#xff1a;^[0-9]*$ n位的数字&#xff1a;^\d{n}$ 至少n位的数字&#xff1a;^\d{n,}$ m-n位的数字&#xff1a;^\d{m,n}$ 零和非零开头的数字&#xff1a;^(0|[1-9][0-9]*)$ 非零开头的最多带两位小数的数字&#xff1a;^([1-9][0-9]*)(.[0…

一分钟教会你五种CycleGAN的优质创新思路(附代码)

专栏导读 &#x1f525;&#x1f525;本文已收录于专栏&#xff1a;《风格迁移之从入门到成功魔改》&#xff0c;欢迎免费订阅​此专栏用于带你从零基础学会什么是风格迁移&#xff0c;风格迁移有什么作用&#xff0c;传统做法和Cyclegan的原理&#xff0c;及其优缺点&#xf…

领域驱动中的Android开发

领域驱动的Android开发 构建有意义的模型 在Android开发世界中&#xff0c;最佳架构的竞争一直存在。MVC、MVP、MVVM、MVI是互联网上许多文章讨论的热门话题。 我们知道View不应包含任何复杂逻辑。我们知道Controller、Presenter和ViewModel之间的区别。但是&#xff0c;我们…

数据结构复习(一)到循环队列

第一章 数据结构绪论 数据结构&#xff1a;是相互之间存在一种或多种特定关系的数据元素的集合。 第2章 算法 算法&#xff1a;解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示为一个或多个操作。 算法具有五个基本特性…

2023.7.17-用*来画一个直角在左(右)下方的等腰直角三角形

功能&#xff1a;如题&#xff0c;直角边长度为5。 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int a, b, i,j;printf("直角边的长度为&#xff1a;");scanf("%d",&a);for (i 1; i < a;i){for (j…

JMeter和Postman:哪一个更适合性能测试?

Postman 和 JMeter 都可以用来做 API 测试&#xff0c;但是它们之间有一些区别。 测试类型 Postman 主要用于功能测试和集成测试&#xff0c;而 JMeter 主要用于性能测试和负载测试&#xff0c;例如压力测试和并发测试。因此&#xff0c;如果你需要测试应用程序的性能和可伸缩…

​python接口自动化(四十一)- 发xml格式参数的post请求(超详解)​

简介 最近在工作中&#xff0c;遇到一种奇葩的接口&#xff0c;它的参数数据是通过xml&#xff0c;进行传递的&#xff0c;不要大惊小怪的&#xff0c;林子大了什么鸟都有&#xff0c;每个人的思路想法不一样&#xff0c;开发的接口也是各式各样的&#xff0c;如果想要统一的话…