串口通信——发送和接收数据(8位和16位数据之间的转换)

这篇具有很好参考价值的文章主要介绍了串口通信——发送和接收数据(8位和16位数据之间的转换)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 实验目的

1.发送两个字节数据,就是16位的数据,每一次发送8位,发送两次,这里要进行数据的拆分,如发送一个0XFF56,接收得到的也是FF56(16进制显示);
2.接收两个字节的数据(这里通过串口助手以16进制发送一个数据),将拼接的数据(只能一个字节一个字节接收)除以100展示出来,如通过串口助手发送一个DEEE(16进制发送),其10进制就是57070,最终要展示为570.70。
其中串口是USART1,其端口是GPIOA,引脚是PIN9、PIN10,一个用来收数据,一个用来发收据。

2. 实验流程

初始化串口;
编写发送数据函数;
编写接收中断函数;
main函数调用发送函数。

2.1 初始化串口

//配置中断函数,这个函数下面有调用
 void EXTI_NVIC_Config(void){
	//NVIC初始化结构体
	NVIC_InitTypeDef  NVIC_InitStruct;
	//设置中断优先级的分组
	//就是设置主抢占优先级和子抢占优先级各是几,这里是分组为1,代表主优先级可以是0和1(就是1个位来设置主优先级),子优先级是0-7,是2的3次方
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	//配置USART为中断源
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	//配置抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	//配置子优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	//使能中断
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
}
//串口初始化函数
void USART_Config(void){
	//1.初始化GPIO(PA9(接串口1的TX引脚),这里是PA10(接串口1的RX引脚))
	//初始化结构体 GPIO_InitStruct
	//里面是GPIO的速度,上下拉,输出类型等
	 GPIO_InitTypeDef   GPIO_InitStruct;
	//USART结构体
	 USART_InitTypeDef   USART_InitStruct;
	//打开GPIOA时钟(一般开时钟要放到前面的位置,然后再是设置上拉,输出这些)
	 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);  //使能时钟必须放到前面,不然后面的操作不会使灯点亮
	//打开USART1时钟
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
	//复位串口1
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,  GPIO_AF_USART1); //PA9 复用为 USART1
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); //PA10 复用为 USART1
	//驱动是哪个引脚  PA9/PA10
	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_9|GPIO_Pin_10;
	//模式是复用功能
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
		//输出的速度
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	//推挽复用输出
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	//上拉
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	//变量获取它的指针,取地址就行(&)
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	//2.初始化串口
	//使能串口时钟 (放在最上面了)
	//配置波特率
	USART_InitStruct.USART_BaudRate = 115200;  //设置波特率115200
	//配置针数据字长
	USART_InitStruct.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
	//配置停止位
	USART_InitStruct.USART_StopBits = USART_StopBits_1;     //设置为一个停止位
	//配置校验位
	USART_InitStruct.USART_Parity = USART_Parity_No;     //无奇偶校验位
	//配置硬件流控制
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //不使用硬件流控制
	//配置工作模式
	USART_InitStruct.USART_Mode =  USART_Mode_Rx|USART_Mode_Tx;  //收发模式
	//完成串口的初始化配置
	USART_Init(USART1,&USART_InitStruct);
	//串口中断优先级配置(初始化)
	EXTI_NVIC_Config();
	//使能串口接收中断(中断配置函数)  这是使能哪种中断,比如在接收到数据的时候(RXNE 读数据寄存器非空),我们要产生中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  //生成串口中断   接收到数据就产生了中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);	// 开启空闲中断
	//使能串口(串口使能函数)
	USART_Cmd(USART1,ENABLE);
}

2.2 编写发送数据函数

一个16位的数据,先发送的是高8位,再发送第八位。
uint8_t temp_h,temp_l;
取高8位:temp_h = (data&0xFF00) >>8,先把数据按位与上0xFF00,这样低八位全取了0,再右移8位就得到了高8位。
取低8位:temp_l = (data&0x00FF); 把数据按位与上0x00FF就是高八位清零了,只剩下八位了。

//发送一个字节数据,进行了简单封装,判断了发送结束
void Usart_SendByte(USART_TypeDef* USARTx, uint8_t data){
	//串口发送数据
	USART_SendData(USARTx, data);
	//什么时候结束 检测状态寄存器的TXE位(发送数据寄存器为空)  TXE:Transmit data register empty
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)== RESET){} //如果发送完成会结束循环 RESET=0
	//while(!(USART_GetFlagStatus(USARTx, USART_FLAG_TXE))){} //这个应该也是可以的
}

//发送两个字节数据
void Usart_SendHalfWord(USART_TypeDef* USARTx, uint16_t data){
	//定义高八位和低八位
	uint8_t temp_h,temp_l;
	//高8位的值是
	temp_h = (data&0xff00) >>8;
	temp_l =  data&0x00ff;   //高8位清0
	//串口发送高8位数据
	USART_SendData(USARTx,temp_h); //这里的USART_SendData是可以发送16位数据的
  //检测发送完成 检测状态寄存器的TXE位(发送数据寄存器为空)  TXE:Transmit data register empty
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)== RESET){} //如果发送完成会结束循环 RESET=0
	//串口发送低8位数据
	USART_SendData(USARTx, temp_l);
  //检测发送完成 检测状态寄存器的TXE位(发送数据寄存器为空)  TXE:Transmit data register empty
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)== RESET){} //如果发送完成会结束循环 RESET=0	
}

2.3 编写接收中断函数

	uint8_t rx_buff[50];  //声明一个数组
    uint8_t rx_cnt = 0;   //数组索引为0
    uint8_t usart_idle_flag = 0;
    uint16_t temp;
    //接收数据中断函数
void USART1_IRQHandler(void){
	uint8_t i;
	unsigned int data;
  if(USART_GetITStatus(USART1,USART_IT_RXNE)){  //每当接收到1个字节,会产生USART_IT_RXNE中断
		rx_buff[rx_cnt] = USART_ReceiveData(USART1);  //把这个数据放到数组中去
		rx_cnt++;
	}
  if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET){  //当接收到一帧数据,就会产生USART_IT_IDLE中断
		data = USART1->SR;		 // 清空闲中断
		data = USART1->DR;       
		usart_idle_flag = 1;	//产生空闲中断,没有用到
	//展示接收到的数据
	for(i=0;i<2;i++){
		printf("value = %x\n",rx_buff[i]);
	}
	//拼接数据
	temp = (rx_buff[0]<<8)|(rx_buff[1]); //或者是 (uint16_t)rx_buff[0]<<8 + (uint16_t)rx_buff[1]
		printf("value = %.2f\n",(float)temp/100);
		memset(rx_buff,0,sizeof(rx_buff));   //清空数组
		rx_cnt = 0;                          //索引置0
	}
}

2.4 main.c函数

int main(void){
  USART_Config();       //初始化串口
  Usart_SendHalfWord(USART1,0XFF56);  //调用发送两个字节函数
  while(1){}
}

3. 实验结果

发送两个字节展示如下图所示:
m2dock串口通信电脑接收数据并返回结果,单片机,单片机,stm32,嵌入式硬件
接收两个字节如下图所示:
m2dock串口通信电脑接收数据并返回结果,单片机,单片机,stm32,嵌入式硬件

4. 总结发现

在编写接收数据中断函数时,如果使用printf进行接收数据的打印时候,只会打印接收到的第一个字节,这里是把printf放到接收和空闲中断之间,会产生问题。文章来源地址https://www.toymoban.com/news/detail-795687.html

//接收数据中断函数
void USART1_IRQHandler(void){
	uint8_t i;
	unsigned int data;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)){  //每当接收到1个字节,会产生USART_IT_RXNE中断
		rx_buff[rx_cnt] = USART_ReceiveData(USART1);  //把这个数据放到数组中去
		rx_cnt++;
	}
 
 //---------------------------------------------
  //放到两者之间的时候
  for(i=0;i<2;i++){
		printf("value = %x\n",rx_buff[i]);
	}
 //---------------------------------------------
	if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET){  //当接收到一帧数据,就会产生USART_IT_IDLE中断
		data = USART1->SR;		 // 清空闲中断
		data = USART1->DR;           
		usart_idle_flag = 1;	//产生空闲中断,没有用到
		temp = (rx_buff[0]<<8)|(rx_buff[1]); //或者是 (uint16_t)rx_buff[0]<<8 + (uint16_t)rx_buff[1]
		printf("value = %.2f\n",(float)temp/100);
		memset(rx_buff,0,sizeof(rx_buff));   //清空数组
		rx_cnt = 0;                          //索引置0
	}
}

到了这里,关于串口通信——发送和接收数据(8位和16位数据之间的转换)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32串口通信—串口的接收和发送详解

    目录 前言: STM32串口通信基础知识: 1,STM32里的串口通信 2,串口的发送和接收 串口发送: 串口接收: 串口在STM32中的配置: 1. RCC开启USART、串口TX/RX所对应的GPIO口 2. 初始化GPIO口 3. 串口初始化 4. 串口使能 5. 串口发送数据 串口接收的两种实现方式: 1,轮询方式: 2,中断

    2024年04月08日
    浏览(87)
  • 【个人笔记】51单片机串口通信的字符串接收和发送,串口通信调节数码管显示时钟(串口通信,定时器,数码管)

           目的:利用PROTUES仿真软件、串口调试助手、虚拟串口,搭建单片机与PC通信仿真平台,熟悉单片机串口的配置及与PC机的通信方法;尝试制定通信协议,单片机根据通信协议解析接收到的内容,并根据接收的指令执行相应的操作。 基本功能: 1.时分秒的动态显示。

    2024年02月11日
    浏览(35)
  • 串口通信——串口助手发送正数/负数(以ascii码的形式发送或者以16进制形式发送),最后展示出发送的数

    1.串口助手发送一个数(发送的形式是ascii码),最后除以100展示这个数,如发送一个-29987,最后要展示出-299.87。 2.串口助手发送一个数(发送的形式是16进制),最后除以100展示这个数,如发送一个-3,最后要展示出-0.03。 其中串口是USART1,其端口是GPIOA,引脚是PIN9、PIN10,

    2023年04月23日
    浏览(33)
  • STM-32:USART串口协议、串口外设—数据发送/数据发送+接收

    通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统。比如STM32芯片里面集成了很多功能模块,如定时器计数、PWM输出、AD采集等等,这些都是芯片内部的电路,它们的配置寄存器、数据寄存器都在芯片里面,操作简单,直接读写就行。但是有些功能STM32内部没有

    2024年02月04日
    浏览(41)
  • 串口发送数据,只接收到00的原因之一

    1、环境: STM32F103RCT6 KEIL 5 2、现象: 不管我发送任何类型的数据,在串口助手上显示接收到的都是00, 我头很大,去网上找了别人的代码对比检查。 终于,细心的我发现,原来粗心的我少了一行代码。 3、解决方案1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); 好了,加上这一行

    2024年02月12日
    浏览(62)
  • STM32实现三个串口同时开启发送接收数据

            实现STM32开通三个串口,每个串口都可以实现接收和发送数据。          编程时,严禁在中断函数中写入发送串口数据代码,否则会出错,具体原因不清楚(有大佬知道的话帮我指出),可能原因是DR寄存器冲突导致。         RX,TX连接到A9,A10使用串口1,使

    2024年04月13日
    浏览(47)
  • C#与松下PLC串口通讯发送,接收数据

    记录与学习 第一次跟PLC打交道,C#与松下plc交互读写功能,很多东西都是自己在网上找的,整理了下做个记录  引入“Panasonic.dll”文件 下载地址 百度盘百度网盘 请输入提取码  提取码:8vnm  public Panasonic.PLC Sp_PLC;   Sp_PLC.WCS(\\\"R\\\", \\\"1\\\", true);//提示PLC软件初始化完成,可以正常工

    2023年04月12日
    浏览(29)
  • 最详细STM32,cubeMX串口发送,接收数据

    这篇文章将详细介绍 串口 发送数据,接受数据。 实验开发板:STM32F103C8T6。 所需软件:keil5 , cubeMX 。 实验目的:了解 串口的基础知识,掌握串口如何发送,接收数据 。 实验:串口发送数据点亮 led。 如果想了解串口的基础知识可以参考我之前的文章: STM32Cube串口USART发送

    2024年02月04日
    浏览(47)
  • Qt+C++串口调试接收发送数据曲线图

    程序示例精选 Qt+C++串口调试接收发送数据曲线图 如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助! 这篇博客针对Qt+C++串口调试接收发送数据曲线图编写代码,代码整洁,规则,易读。 学习与应用推荐首选。 一、所需工具软件 二、使用步骤

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包