串口通信可以说很常用的一种通信方式,例如 蓝牙通信 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+队列的方式直接接收一帧完整的数据
#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 //´®¿ÚÊä³öPA9
GPIO_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 //´®¿ÚÊäÈëPA10
GPIO_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); //³õʼ»¯´®¿Ú1
USART_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;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //×ÓÓÅÏȼ¶3
NVIC_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;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ
}
}
}
}
}
#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
#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