项目场景:

串口通信可以说很常用的一种通信方式,例如 蓝牙通信 openmv 与串口 通信 等等


问题描述

1.我们在进行数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据,导致数据部分缺失,或者出现乱码的问题,所以说代码需要准确性。

2.比如我们发送一组数据(1,2,3,4,5)放在数组里面,你想读取 USART1_RX_BUF[1] 是什么 通过 printf 打印 USART1_RX_BUF[1];这时如果你用整形 也就是:

(printf("%d",USART1_RX_BUF[1])

你就会发现 你打印的数据 是48 向上加,就不是你想要得到的值.


原因分析:

原因1:如果将接收到的数据直接进行处理,单片机处理数据很快,就有可能出现数据丢失等情况,为了增强接收数据的准确性,我们添加一些数据帧头帧尾的检测,便于数据处理的更加准确。

原因2:经过不断的调试判定是数据类型问题,就在一个个的改动,也是碰巧发现 接受数组里面是字符型 更改后[ printf("%c", USART1_RX_BUF[1] ] 这样就可以接受到你想要的数据了。


解决方案:

通过在监视串口的数据不断的尝试,调试出适合自己的程序;

下面直接上代码

毕业学长看完给的建议:
第一:在一组数据进行传输的时候如果想要准确性,单靠帧头帧尾还不行,因为你发送的数据会出现和帧头帧尾同样的数据,较好的解决办法是在数据末尾加上CRC校验的数据,收到这组数据后同样先进行CRC校验,校验结果一致的情况下才能用这一组数据

第二:我看你用的是单字节接收,这个时候程序就要知道要接收多少个字节,单靠超时或者你可能会用到的帧尾的话就显然不能保证很靠谱,有一种解决方法是在发送的数据中加入数据长度,在中断里进行判断, 这是比较简单的一种方法,但是这种数据的结构特别常用,等下我可以给你看看我实际项目用到的协议帧是怎么定义的,基本就是按照MODBUS的格式来的

第三:可以尝试用DMA或者DMA+队列的方式直接接收一帧完整的数据

usart.c

#include "usart.h"      u8 USART1_RX_BUF[USART1_REC_LEN];     //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬   ½ÓÊÕÍê³É±êÖ¾
//bit14£¬   ½ÓÊÕµ½0x0d
//bit13~0£¬ ½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART1_RX_STA=0;       //½ÓÊÕ״̬±ê¼Ç  #ifdef USART1_PRINTF
int fputc(int ch,FILE *p)  //º¯ÊýĬÈϵģ¬ÔÚʹÓÃprintfº¯Êýʱ×Ô¶¯µ÷ÓÃ
{USART_SendData(USART1,(u8)ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);return ch;
}
#endif/*******************************************************************************
* º¯ Êý Ãû         : USART1_Init
* º¯Êý¹¦ÄÜ         : USART1³õʼ»¯º¯Êý
* Êä    Èë         : bound:²¨ÌØÂÊ
* Êä    ³ö         : ÎÞ
*******************************************************************************/
void USART1_Init(u32 bound)
{//GPIO¶Ë¿ÚÉèÖÃGPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);    //´ò¿ªÊ±ÖÓ/*  ÅäÖÃGPIOµÄģʽºÍIO¿Ú */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX             //´®¿ÚÊä³öPA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;      //¸´ÓÃÍÆÍìÊä³öGPIO_Init(GPIOA,&GPIO_InitStructure);  /* ³õʼ»¯´®¿ÚÊäÈëIO */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX             //´®¿ÚÊäÈëPA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;       //Ä£ÄâÊäÈëGPIO_Init(GPIOA,&GPIO_InitStructure); /* ³õʼ»¯GPIO *///USART1 ³õʼ»¯ÉèÖÃUSART_InitStructure.USART_BaudRate = bound;//²¨ÌØÂÊÉèÖÃUSART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽUSART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλUSART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλUSART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆUSART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú1USART_Cmd(USART1, ENABLE);  //ʹÄÜ´®¿Ú1 USART_ClearFlag(USART1, USART_FLAG_TC);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆôÏà¹ØÖжÏ//Usart1 NVIC ÅäÖÃNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//´®¿Ú1ÖжÏͨµÀNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇÀÕ¼ÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;      //×ÓÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQͨµÀʹÄÜNVIC_Init(&NVIC_InitStructure);    //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷¡¢
}/*******************************************************************************
* º¯ Êý Ãû         : USART1_IRQHandler
* º¯Êý¹¦ÄÜ         : USART1ÖжϺ¯Êý
* Êä    Èë         : ÎÞ
* Êä    ³ö         : ÎÞ
*******************************************************************************/
//void USART1_IRQHandler(void)                  //´®¿Ú1ÖжϷþÎñ³ÌÐò
//{
//  u8 r;
//  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ
//  {
//      r =USART_ReceiveData(USART1);//(USART1->DR);    //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
//      USART_SendData(USART1,r);
//      while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
//  }
//  USART_ClearFlag(USART1,USART_FLAG_TC);
//}
/*******************************************************************************/
void USART1_IRQHandler(void)                    //´®¿Ú2ÖжϷþÎñ³ÌÐò
{u8 r;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ{r =USART_ReceiveData(USART1);//(USART1->DR);   //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ýif((USART1_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É{if(USART1_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d{if(r!=0x0a)USART1_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼else USART1_RX_STA|=0x8000;   //½ÓÊÕÍê³ÉÁË }else //»¹Ã»ÊÕµ½0X0D{  if(r==0x0d)USART1_RX_STA|=0x4000;else{USART1_RX_BUF[USART1_RX_STA&0X3FFF]=r ;USART1_RX_STA++;if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ    }      }}         } }      

usart.h

#ifndef __usart_H
#define __usart_H#include "system.h"
#include "stdio.h" #define USART1_PRINTF#define USART1_REC_LEN            200     //¶¨Òå×î´ó½ÓÊÕ×Ö½ÚÊý 200
#define EN_USART1_RX            1       //ʹÄÜ£¨1£©/½ûÖ¹£¨0£©´®¿Ú1½ÓÊÕextern u8  USART1_RX_BUF[USART1_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.Ä©×Ö½ÚΪ»»Ðзû
extern u16 USART1_RX_STA;               //½ÓÊÕ״̬±ê¼Ç  void USART1_Init(u32 bound);#endif

main.c

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"int main()
{u8 sf[10];u16 i=0;u8 t;u8 len;
// int16_t data1;
// int16_t data2;
// int16_t data3;
// int16_t data4;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //ÖжÏÓÅÏȼ¶·Ö×é ·Ö2×éLED_Init();USART1_Init(9600);while(1){if(USART1_RX_STA&0x8000){                       len=USART1_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶Èprintf("\r\nÄú·¢Ë͵ÄÏûϢΪ: ");for(t=0;t<len;t++){sf[t]=USART1_RX_BUF[t];
//              USART_SendData(USART1, USART1_RX_BUF[t]);         //Ïò´®¿Ú1·¢ËÍÊý¾Ý
//              while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//µÈ´ý·¢ËͽáÊø}if(sf[3]=4){led1=0;}printf("%c",sf[0]);printf("\r\n");//²åÈë»»ÐÐUSART1_RX_STA=0;}
//      else
//      {
//
//      i++;
//      if(i%200==0)
//      {
//          led1=!led1;
//      }
//      if(i%200==0)
//      {
//          printf("521.521.521.521.521.\r\n");
//      }
//      delay_ms(10);
//  }
}
}

usart串口发送与接收问题相关推荐

  1. USART串口协议和USART串口外设(USART串口发送串口发送和接收)

    1.通信接口 A.基本概念 • 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统 • 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发  异步:需要双方约定一个频率 B.数据通信方 ...

  2. STM32L152RE实现串口发送及接收数据

    本文主要讲解用keil软件实现USART串口发送及接收数据,默认读者keil环境已经配好,且头文件已正确引入,如出现编译错误以及st-link下载问题,请自行百度解决. 串口发送和接收数据是一件看起来 ...

  3. STM32—USART串口发送+接收

    STM32-USART串口发送+接收 本文来自于<STM32--江科大>的笔记整理. 文章目录 STM32-USART串口发送+接收 10.3 串口发送 串口调试助手 10.3.1 数据模 ...

  4. 串口通信—串口发送和接收代码讲解

    USART 初始化结构体详解 标准库函数对每个外设都建立了一个初始化结构体,比如USART_InitTypeDef,结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如USART_Init() ...

  5. 蓝桥杯 stm32 USART 串口发送数据

    文章代码使用 HAL 库. 文章目录 前言 一.串口原理图 二.CubeMX 创建工程. 三.串口发送函数: 四.串口助手 配置: 五.详细代码: 注意:连续发送数据 六.printf 重定向问题 代 ...

  6. stm32f1串口发送与接收

    目录 串口配置 串口发送 1使用SendString函数发送 2使用printf函数发送 ​串口接收 串口配置 首先对串口进行初始化 包括使能串口时钟,这里我使用的是usart2,使能GPIO时钟,这 ...

  7. python串口通信的接收与发送_31.用python中的serial向串口发送和接收数据(案例一)...

    代码功能说明:1.向串口助手发送十六进制数据:0X01,0X03,0X00,0X00,0X00,0X01,0X84,0X0A: 2.用串口助手向代码发送数据,并将发送过来的数据保存在数据库中,按数据和 ...

  8. STM32串口发送和接收

    采用标准库 主控STM32F103C8T6 03代码: #include "main.h" #include "led/led.h" #include &quo ...

  9. Arduino串口发送与接收16进制数据(HEX)(数据乱码)-JDY-10M组网

    最近使用JDY-10M蓝牙组网,需要Arduino收发数据,将遇到的一些问题与最终解决方法分享给大家,如果内容有问题,还请大家指点. 1.JDY-10M组网 关于如何JDY-10M如何组网网上介绍,这 ...

最新文章

  1. Android开发之git命令创建tag提交远程仓库的方法(图文教程)
  2. 【人脸识别】arcface详解
  3. GiraffeDet的学习笔记
  4. python实现排序算法 整理
  5. 深度强化学习调度研究的心路历程
  6. sublime配置python开发环境_【教程】把Sublime Text 2用作Python的IDE去实现Python的开发...
  7. 菜鸟教程学习Java
  8. SQLmap下载和安装教程(详细附图)
  9. 漫步STL-string in [Cpp] v.s. String in [Java]
  10. ios12怎么滑屏解锁_iOS12.2 越狱来袭,又是一波秀
  11. php 系统管理和监控软件
  12. 《中国睡眠研究报告2022》:被调查大学生睡前不看手机的不足3%
  13. 刷屏器!简单!快速!稳定!可控制速度!
  14. 基于网络视频监控的人员考勤系统设计
  15. 阿里云ecs服务器(Ubuntu)配置图形界面并远程桌面连接
  16. cmake添加查找目录_CMake如何查找库路径(一)
  17. PAT——1121 Damn Single 甲级
  18. 什么是B2B电子商务模式
  19. matlab迭代实验总结,实验报告二
  20. jsp页面显示源码实现

热门文章

  1. CHINAPLAS国际橡塑展落户深圳,扬帆启航踏新程
  2. Linux命令解读(一):head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 22
  3. linux .trash,linux下trash代替rm
  4. Element Table 反选
  5. java-net-php-python-ssm个人理财管理系统登陆计算机毕业设计程序
  6. sgx是什么要开吗_绝了!滑滑梯设计在顶楼,上去一滑不就是直接跳…楼…吗??...
  7. 纽约大学计算机博士奖学金如何,斑马博士捷报|纽约大学(NYU) MS Computer Engineering录取+7000美金奖学金!...
  8. Linux“挂载”是什么意思
  9. Java智能合约工具包|Java调用智能合约|Java调用ERC20、ERC721、ERC1155合约
  10. 高斯曲线拟合推导过程