STM32串口通信

一、串口发送

1.初始化引脚

void Serial_Init(uint32_t BaudRate)
{RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA ,ENABLE );RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1 ,ENABLE );GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;//由于PIN9为TX,故初始化为发送引脚GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init (GPIOA ,&GPIO_InitStructure);USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=BaudRate;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控USART_InitStructure.USART_Mode=USART_Mode_Tx;//引脚初始化为发送模式USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位为1位USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长位8bit即没有校验位USART_Init(USART1,&USART_InitStructure);USART_Cmd(USART1,ENABLE);//USART硬件使能
}

2.写发送函数

1.发送一个字节

        每次对DR寄存器的写操作会清空TXE标志位,故不需要手动清除。

void Serial_SendByte(uint8_t data)
{USART_SendData(USART1,data);//通过DR寄存器发送一个字节while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待TDR位空再发送下一个字节的数据,TDR的写命令会自动清除TXE标志位
}

2.发送一个数组

void Serial_SendArry(uint8_t *arry,uint8_t length)
{for(int i=0;i<length;i++){Serial_SendByte(arry[i]);}
}

3.发送一个字符串

void Serial_String(char* String)
{for(int i =0;String[i]!=0;i++){Serial_SendByte(String[i]);}
}

4.发送数字

void Serial_SendNum(uint16_t Num)
{uint16_t weishu=1+log10(Num);uint8_t data=0;uint16_t chushu=0;for(int i = weishu-1;i>=0;i--){chushu=(uint16_t) pow(10,i );data=Num/chushu;Num=Num%chushu;Serial_SendByte(data+0x30);}
}

5.printf重定向

        这里需要注意,需要在魔术棒中勾上相关选项

//重写fputc函数
int fputc(int ch, FILE *f)
{Serial_SendByte(ch);return ch;
}

二、串口接收

1.轮询方式接收数据

        即在主循环中不断查询DR寄存器中的RXNE标志位是否被置为,若被置位,则说明有数据被接收,此时便可以使用USART_ReceiveData()函数去取数据。同样,对DR寄存器的读操作也会被清零。故不需要手动清零。

	 while(1){if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET){data=USART_ReceiveData(USART1);printf("data=%d\r\n",data);}}

2.中断方式接收数据

1.在初始化中加入与中断相关的函数

	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);NVIC_InitTypeDef usart_InitStructure;usart_InitStructure.NVIC_IRQChannel=USART1_IRQn;usart_InitStructure.NVIC_IRQChannelCmd=ENABLE;usart_InitStructure.NVIC_IRQChannelPreemptionPriority=2;usart_InitStructure.NVIC_IRQChannelSubPriority=2;NVIC_Init(&usart_InitStructure);

2.写中断函数以及相关接口函数

uint8_t Serial_GetFlag(void)
{if(Rxflag==1){Rxflag=0;return 1;}elsereturn 0;
}
uint8_t Serial_GetData(void)
{return Rxdata;
}
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){Rxdata=USART_ReceiveData(USART1);Rxflag=1;}
}

 3.主函数

	 while(1){if(Serial_GetFlag()==1){printf("data=%d\r\n",Serial_GetData());}}
}	

4.或者直接在中断中输出也可以

void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){printf("rxdata=%d\r\n",USART_ReceiveData(USART1));}
}

3.串口接收HEX数据包

        原理就是使用状态机的方式

void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){static uint8_t status=0;static uint8_t PacketNum=0;if(status==0){if(USART_ReceiveData(USART1)==0XFF)//如果接收到了包头OXFF,则进入下一个状态{status=1;}}else if(status==1)//不断接受数据包的内容,如果接收了四个,则进入下一个状态{if(PacketNum<4){Rxdata[PacketNum]=USART_ReceiveData(USART1);PacketNum++;}elsestatus=2;}else if(status==2)//如果接收到了OXFE,则说明接收到了包尾,则将状态位以及数组个数全部清零,同时至标志位为1,允许主循环检测{if(USART_ReceiveData(USART1)==0xFE){status=0;PacketNum=0;Rxflag=1;}}}
}
	 while(1){if(Serial_GetFlag()==1){for(int i =0;i<4;i++){printf("Rxdata的值为[%d]=:%d\r\n",i,Rxdata[i]);}}}
}	

4.串口接收文本数据包

char Rxdata[100] ;
uint8_t Rxflag;void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){static uint8_t status=0;static uint8_t PacketNum=0;if(status==0){if(USART_ReceiveData(USART1)=='@'){status=1;}}else if(status==1) {if(USART_ReceiveData(USART1)!='\r'){Rxdata[PacketNum]=USART_ReceiveData(USART1);PacketNum++;}elsestatus=2;}else if(status==2) {if(USART_ReceiveData(USART1)=='\n'){Rxdata[PacketNum]=0;//这里加上'\0',是字符串结束的标志status=0;PacketNum=0;Rxflag=1;}}}
}
	 while(1){if(Serial_GetFlag()==1){Serial_String(Rxdata);Serial_SendByte('\r');Serial_SendByte('\n');}}

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

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

相关文章

[疑难杂症2024-003]如何判断一张没有头信息的dcm图像,是否是压缩图像?

本文由Markdown语法编辑器编辑完成&#xff0e; 1. 前言: DCM格式&#xff0c;是医学图像领域里面的通用格式&#xff0e;DCM图像一般分为两大部分&#xff0c;一部分是TAG信息&#xff0c;一部分是像素. 而TAG信息&#xff0c;一般又会分为两部分&#xff0c;如下图所示, 是…

C++_智能指针

文章目录 前言一、智能指针原理二、库支持的智能指针类型1.std::auto_ptr2.std::unique_ptr3.std::shared_ptr4.std::weak_ptr 三、删除器总结 前言 智能指针是一种采用RAII思想来保护申请内存不被泄露的方式来管理我们申请的内存&#xff0c;对于RAII&#xff0c;我们之前也已…

LeetCode-热题100:102. 二叉树的层序遍历

题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a; [[3],[9,20],[15,7]] 示例 2&am…

【GEE实践应用】使用MODIS NDVI数据集绘制研究区域每日NDVI序列曲线

// 设置研究区域 var geometry table;// 选择MODIS NDVI 数据集 var modisNDVI ee.ImageCollection(MODIS/006/MOD13A2).filterBounds(geometry).filterDate(2000-01-01, 2023-12-31);// 计算每天的平均 NDVI var dailyMeanNDVI modisNDVI.map(function(image) {var date e…

AndroidStudio AGP 7+, 编译aar并输出到本地仓库

1 编写构建gradle脚本代码 1.1 配置publication和repository 在指定moudle目录下新建名为"maven-publish.gradle"文件&#xff0c;其声明的publication和repository如下所示&#xff1a; apply plugin: maven-publish// This creates a task called publishReleas…

# 从浅入深 学习 SpringCloud 微服务架构(二)模拟微服务环境

从浅入深 学习 SpringCloud 微服务架构&#xff08;二&#xff09;模拟微服务环境&#xff08;1&#xff09; 段子手168 1、打开 idea 创建父工程 创建 artifactId 名为 spring_cloud_demo 的 maven 工程。 --> idea --> File --> New --> Project --> Ma…

java高校办公室行政事务管理系统设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于mvc的高校办公室行政…

软件缺陷的生命周期

参考&#xff1a;Defect/Bug Life Cycle in Software Testing 什么是缺陷 软件缺陷一般被我们叫做Bug。对应的软件缺陷&#xff0c;就是我们所测试的程序中存在的无法正常运行或功能有相关缺陷。 IEEE729-1983对缺陷的标准定义&#xff1a; 从产品内部看&#xff0c;缺陷是…

基于快照行情的股票/基金 1分钟 K 线合成指南

1. 概述 由于不同交易所不同资产的交易规则是有差异的&#xff0c;导致不同交易所基于快照行情或逐笔成交合成不同资产1分钟 K 线的计算方法是不同的。 本教程旨在提高 DolphinDB 在具体业务场景下的落地效率&#xff0c;降低 DolphinDB 在实际业务使用中的开发难度。 本教程…

C语言如何使⽤指针?

一、问题 指针变量在初始化以后就可以使⽤和参与操作了&#xff0c;那么就要⽤到对指针变量最常⽤的两个操作符——> * 和 &#xff06; 。 二、解答 这⾥⼜要提到始终贯穿着指针的⼀个符号“ * ”&#xff0c;但是这⾥的“ * ”是作为指针运算符使⽤的&#xff0c;叫做取内…

如何合理利用多个中国大陆小带宽服务器?

我们知道在中国大陆带宽单价非常昂贵&#xff0c;一个1Mbps 带宽的机子一年就得卖好几百人民币&#xff0c;这是不值当的&#xff0c;当然我们可以去低价漂阿里云、腾讯云的轻量服务器&#xff0c;99包年&#xff0c;但是带宽太小很难崩。 所以&#xff0c;我们必须构建一个能够…

linux进阶篇:重定向和管道操作

Linux中的重定向和管道操作 llinux中的三种IO设备&#xff1a; 标准输入&#xff08;STDIN&#xff09;,文件描述符号为&#xff1a;0&#xff0c;默认从键盘获取输入 标准输出&#xff08;STDOUT&#xff09;,文件描述符号位&#xff1a;1&#xff0c;默认输出到显示终端 标准…

5GNR刷题

5G帧结构 5G NR帧结构的基本时间单位是( C ) A) subframe B) slot C) Tc D) symbol 5G无线帧长是多少ms&#xff08;B&#xff09; A) 5 B) 10 C) 20 D) 40 下面哪种子载波间隔是中国移动白皮书中规定必选(B ) A) 15KHz B) 30KHz C) 60KHz D) 120KHz 5G参数集包含哪…

【笔试训练】day5

今天的题&#xff0c;最后一题忘公式了&#xff0c;卡了一会推出来了 1、游游的you 思路&#xff1a; 看清题目意思就行&#xff0c;这里的相邻两个o可以重复算&#xff0c;也就是说&#xff0c;“ooo”算2分。 先算you的得分&#xff0c;再算oo 对了&#xff0c;不开long lo…

24年蓝桥杯java-b组

24年蓝桥杯javaB组 蓝桥杯在昨天考完了&#xff0c;结果很不乐观&#xff0c;哎&#xff0c;还是太笨了&#xff0c;脑子确实转的慢&#xff1b;&#x1f625; 本篇博客中解题思路和代码并不一定完全正确&#xff0c;是我和同学们讨论的解答方法&#xff0c;但并未使用官方题…

【python从入门到精通】-- 第五战:函数大总结

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

Leo赠书活动-24期 【三大层次学习企业架构框架TOGAF】文末送书

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

自定义Centos的终端的命令提示符

背景 当我们使用终端登陆Centos时&#xff0c;就自动打开了ssh终端。这个终端的命令提示符一般是这样的&#xff1a; 这个以#号结束的一行字&#xff0c;就是我们说的命令提示符了。 这个是腾讯云的服务器的提示符&#xff0c;可以看到主机名是VM-4-7-centos。 但是这个看起…

STL库 —— priority_queue 的编写

目录 一、 优先级队列的介绍 二、优先级队列的使用 2.1 建大堆 less 2.2 建小堆 greater 2.3 详解 greater 与 less 三、 priority_queue 的模拟实现 3.1 编写框架 3.2 编写简单函数 3.2 进堆 向上调整 3.3 出堆 向下调整 四、完整代码 一、 优先级队列的介绍 1.…

web轮播图

思路&#xff1a; 例如&#xff1a;有5张轮播的图片&#xff0c;每张图片的宽度为1024px、高度为512px.那么轮播的窗口大小就应该为一张图片的尺寸&#xff0c;即为&#xff1a;1024512。之后将这5张图片0px水平相接组成一张宽度为&#xff1a;5120px,高度依然为&#xff1a;5…