stm32应用-简单的串口接收与发送程序
单片机&嵌入式
单片机应用
嵌入式操作系统
学习工具&教程
学习和开发单片机的必备工具
(有问必答)
(带你轻松入门)
电子元件&电路模块
当前位置: >>
>> 浏览文章
stm32应用-简单的串口接收与发送程序
与上位机的串口通信是一个很常用的程序。碧海蓝天在刚刚接触stm32芯片时写的第一个简单程序就是串口通信,现在把程序代码甩出来与大家分享。完整的程序哦~一般人我不告诉他
&库版本& :ST3.0.0
文件:mian.c
//功能:串口初始化、打开定时器中断,然后一直接收数据状态就好了。发送在中断中实现
#include "stm32f10x.h"
#include "usart.h"
u8 USART_rx_
int main(void)
&&RCC_Configuration();&&&&&
//系统时钟配置
&&GPIO_Configuration();&&&&&
//端口初始化
&&NVIC_Configuration();&&&&&
//中断源配置
&&USART_Configuration();&
&&&//串口1初始化
&&Time_Init();&&&&&&&&&&&
//定时器初始化
&&#ifdef DEBUG
&&&&&&debug();
&&TIM_Cmd(TIM3,ENABLE);&
&& while(1)
文件:usart.c
#include "stm32f10x.h"
#include "stdio.h"
#include "usart.h"
&&unsigned char auchCRCHi [256]
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
&&0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40};
&&unsigned char auchCRCLo [256]
&&0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
&&0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
&&0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
&&0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
&&0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
&&0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
&&0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
&&0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
&&0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
&&0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
&&0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
&&0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
&&0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
&&0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
&&0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
&&0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40};
unsigned short CRC16(unsigned char* puchMsg, unsigned short
usDataLen)
&&unsigned char uchCRCHi = 0xFF
&&unsigned char uchCRCLo = 0xFF
&&unsigned char uI
&&while (usDataLen--)
&&&&uIndex
= uchCRCHi^*puchMsg++;
&&&&uchCRCHi
= uchCRCLo^auchCRCHi[uIndex];
&&&&uchCRCLo
= auchCRCLo[uIndex];
&&return (uchCRCHi && 8 |
uchCRCLo) ;
void RCC_Configuration(void)
& ErrorStatus
HSEStartUpS&&
&&&//枚举变量,定义高速时钟的启动状态
RCC_DeInit();&&&&&&&&&&&&&&&&&&
//RCC系统重置,用于Debug目的
RCC_HSEConfig(RCC_HSE_ON);&&&&&&&&&&&&&&&&
//使能高速时钟源HSE&&
& HSEStartUpStatus =
RCC_WaitForHSEStartUp();&&&
//等待HSE稳定
& if(HSEStartUpStatus == SUCCESS)
FLASH_SetLatency(FLASH_Latency_2);&&&&&
&FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);&&&&&
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
// PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);&&&&&&&&
///PCLK1 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08){}
& RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1
|RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOB ,
& RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,
//------------------------------------------------------------------
//函数名:void GPIO_Configuration()
//输入参数:null
//返回参数:null
//说明:GPIO初始化函数
//------------------------------------------------------------------
void GPIO_Configuration(void)
& GPIO_InitTypeDef
GPIO_InitS&&&&&//GPIO初始化结构体声明
& GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_9;&&&&&&&&&
//USART1 TX
& GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AF_PP;&&&
//复用推挽输出
& GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;&&
& GPIO_Init(GPIOA,
&GPIO_InitStructure);&&&&&
& GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_10;&&&&&&&&&
//USART1 RX
& GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_IN_FLOATING;&&
//复用浮空输入
& GPIO_Init(GPIOA,
&GPIO_InitStructure);&&&&&&&&&&
&GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_6;&
&GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_Out_PP;&&
&GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
&GPIO_Init(GPIOB, &GPIO_InitStructure);
//------------------------------------------------------------------
//函数名:void NVIC_Configuration()
//输入参数:null
//返回参数:null
//说明:NVIC初始化函数
//------------------------------------------------------------------
void NVIC_Configuration(void)
{&&&&&&&&&&&&&&
& NVIC_InitTypeDef
NVIC_InitS&&&&&&
//NVIC初始化结构体声明
VECT_TAB_RAM&&&&&&&
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
//如果程序在RAM中调试那么定义中断向量表在RAM中否则在Flash中
NVIC_SetVectorTable(NVIC_VectTab_FLASH,
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
& NVIC_InitStructure.NVIC_IRQChannel =
USART1_IRQn;&&&&&&&
&//设置串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =
0;&&&&&&&&
//抢占优先级 0
& NVIC_InitStructure.NVIC_IRQChannelSubPriority =
0;&&&&//子优先级为0
& NVIC_InitStructure.NVIC_IRQChannelCmd =
ENABLE;&&&&&//使能
& NVIC_Init(&NVIC_InitStructure);
& NVIC_InitStructure.NVIC_IRQChannel =
TIM3_IRQn;
//设置定时器3全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =
//抢占优先级 1
& NVIC_InitStructure.NVIC_IRQChannelSubPriority =
//子优先级为0
& NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& NVIC_Init(&NVIC_InitStructure);
//------------------------------------------------------------------
//函数名:void USART_Configuration()
//输入参数:null
//返回参数:null
//说明:串口初始化函数
//------------------------------------------------------------------
void USART_Configuration(void){
& USART_InitTypeDef
USART_InitS&&&&&&&&&&&&&&&&&&
//串口初始化结构体声明
& USART_ClockInitTypeDef
USART_ClockInitS
& USART_InitStructure.USART_BaudRate =
115200;&&&&&&//设置波特率为115200bps
& USART_InitStructure.USART_WordLength =
USART_WordLength_8b;&&//数据位8位
& USART_InitStructure.USART_StopBits =
USART_StopBits_1;&&&//停止位1位
& USART_InitStructure.USART_Parity =
USART_Parity_No;&&&&//无校验位
& USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_N&&
//无硬件流控
& USART_InitStructure.USART_Mode = USART_Mode_Rx |
USART_Mode_Tx;&&&&&//接受和发送模式都打开
USART_ClockInitStruct.USART_Clock=USART_Clock_D&&&&&
//串口时钟禁止
USART_ClockInitStruct.USART_CPOL=USART_CPOL_L&&&&&&&
//数据低电平有效
USART_ClockInitStruct.USART_CPHA=USART_CPHA_2E&&&&//配置CPHA使数据在第2个边沿的时候被捕获
USART_ClockInitStruct.USART_LastBit=USART_LastBit_D&&//
禁用最后一位,使对应的时钟脉冲不会再输出到SCLK引脚
& USART_ClockInit(USART1,
&USART_ClockInitStruct);
&&&&&//配置USART与时钟相关的设置
& USART_Init(USART1,
&USART_InitStructure);&&&&&&&//配置串口参数函数
& USART_ITConfig(USART1, USART_IT_RXNE,
ENABLE);&&&&&&
//使能接收中断
//USART_ITConfig(USART1, USART_IT_TXE,
ENABLE);&&&&//使能发送缓冲空中断
//USART_ITConfig(USART1, USART_IT_TC,
ENABLE);&&&&//使能发送完成中断
USART_ClearFlag(USART1,USART_FLAG_TC);&&&&&&&&
//清除发送完成标志位
& USART_Cmd(USART1,
ENABLE);&&&&&&&&&//使能串口1
//------------------------------------------------------------------
//函数名:void Time_Init()
//输入参数:null
//返回参数:null
//说明:定时器初始化函数
//------------------------------------------------------------------
void Time_Init(void)
& TIM_TimeBaseInitTypeDef
TIM_TimeBaseS
TIM_DeInit(TIM3);&&&&&&&&&&&&//复位TIM3定时器
& TIM_TimeBaseStructure.TIM_Period
=7999;&&&&&&&&
&//设置自动重装载寄存器锁存值,1ms溢出&&&&&&
& TIM_TimeBaseStructure.TIM_Prescaler =
8;&&&&&&//9分频&
& TIM_TimeBaseStructure.TIM_ClockDivision =
0x0;&&&&&&
//时钟分频因子
& TIM_TimeBaseStructure.TIM_CounterMode =
TIM_CounterMode_Up;&//计数器向上计数模式
&&&&&&&&&&&&
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);&&&&//写TIM3各寄存器参数
& TIM_ClearFlag(TIM3,TIM_FLAG_Update);
& TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
文件:usart.h
#ifndef _USART_H
#define _USART_H
#include "stm32f10x.h"
void RCC_Configuration(void);&&
//声明RCC初始化函数
void GPIO_Configuration(void);&&
//声明GPIO初始化函数
void NVIC_Configuration(void);&&
//声明NVIC初始化函数
void USART_Configuration(void);&&
//声明串口初始化函数
Time_Init(void);&&&&
//声明定时器初始化函数
unsigned short CRC16(unsigned char* puchMsg, unsigned short
usDataLen);
文件:stm32f103x_it.c
//需要设置串口接收中断和定时器3中断,中断时间为1ms
//------------------------------------------------------------------
//函数名:void USART1_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:串口接收中断服务
//------------------------------------------------------------------
void USART1_IRQHandler(void)
&&if(USART_GetITStatus(USART1,
USART_IT_RXNE) !=
RESET)&&&&&&&&&
//判断读寄存器是否非空
&&&GPIO_SetBits(GPIOB,GPIO_Pin_6);
&&&&rx_data[RbufCounter++]=USART_ReceiveData(USART1);&
& //接收字节到接收缓冲区
&&&&if(USART_Rsv_Status==0)
&&&&&&if(RbufCounter&1)
&&&&&&&&if(rx_data[0]==0xA5&&rx_data[1]==0x5A)&&&
//当接收到的数据帧头两个字节同时为0xA5和0x5A时
&&&&&&&&&&USART_Rsv_Status=1;
&&&&&&&&&&USART_SendData(USART1,
rx_data[0]);
&&&&&&&&else
&&&&&&&&&&rx_data[0]=rx_data[1];
&&&&&&&&&&RbufCounter=1;
&&&&&&USART_1ms_Cnt=0;
&&&&}&&&&&&&&&&&&
&&}&&&&&&&&&
//------------------------------------------------------------------
//函数名:void TIM2_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:定时器2中断服务
//------------------------------------------------------------------
void TIM2_IRQHandler(void)
//------------------------------------------------------------------
//函数名:void TIM3_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:定时器3中断服务
//------------------------------------------------------------------
void TIM3_IRQHandler(void)
&&if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)&&&&&&&
//判断是否为定时器3溢出中断
&&&&GPIO_SetBits(GPIOB,GPIO_Pin_6);
&&&&TIM_ClearITPendingBit(TIM3,
TIM_IT_Update);&&//清中断标记
&&&&if(USART_Rsv_Status==1)
&&&&USART_1ms_Cnt++;
&&&&if(USART_1ms_Cnt&5)
&&&&&USART_SendData(USART1,0xAA);
&&&&&&USART_Rsv_Status=0;&&&&&//连续计数超过5次对USART_Rsv_Status置0,继续等待接收
&&&&&&USART_1ms_Cnt=0;&&&&&&&&
//当USART_1ms_Cnt&5时对USART_1ms_Cnt重新清零&
&&&&&&if(RbufCounter==(u16)rx_data[4]+7)&&&&&&&&&&&&&
//检验数据的完整性
//定义循环变量
&&&&&&&&int
&&&&&&&&data_length=rx_data[4];
&&&&&&&&for(i=0;i
&&&&&&&&&&data[i]=rx_data[i];
&&&&&&&&}&
&&&&&&&&CRC_data_Hi=rx_data[RbufCounter-1];
&&&&&&&&CRC_data_Lo=rx_data[RbufCounter-2];
&&&&&&&&CRC_data=CRC16((unsigned
char*)data,data_length+5);
&&&&&&&&CRC_data_Hi1=CRC_data&&8;
&&&&&&&&CRC_data_Lo1=CRC_data&0x00
&&&&&&&&&if(CRC_data_Hi==(u8)CRC_data_Hi1
&& CRC_data_Lo==CRC_data_Lo1)
&&&&&&&&&{
&&&&&&&&&&&for(j=0;rx_data[j]!='\0';j++)&&
//循环逐字输出,到结束字'\0'
&&&&&&&&&&&{&&&&&&&
&&&&&&&&&&&&&USART_SendData(USART1,
rx_data[j]);&&&&
//发送字符
&&&&&&&&&&&&&while(USART_GetFlagStatus(USART1,
USART_FLAG_TXE) == RESET)
&&&&&&&&&&&&&{
&&&&&&&&&&&&&}
//等待字符发送完毕
&&&&&&&&&&&}
&&&&&&RbufCounter=0;
&&&&}&&&&&
【】【】【】【】
上一篇:下一篇:
CopyRight @
单片机教程网 51hei.com , All Rights Reserved51单片机串口通信上位机接收数据丢失,怎么解决 - STM32/STM8技术论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
51单片机串口通信上位机接收数据丢失,怎么解决
22:38:54
& && &上位机发送数据,单片机接收后再将同样的数据发送出来,但是发送出来的数据会丢失1~2个数据,不知道怎么回事,望解答!
#include®52.h&
#include&intrins.h&
#define uchar unsigned char
#define uint unsigned int
uchar flag,i;
uchar code table[] = &I get &;
void initial();
void main()
{
& & & & initial();
& & & & while(1)
& & & & {
& & & & & & & & if(flag == 1)
& & & & & & & & {
& & & & & & & & & & & & ES = 0;
& & & & & & & & & & & & /*for(i=0;i&6;i++)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & SBUF = table[i];
& & & & & & & & & & & & & & & & while(!TI);
& & & & & & & & & & & & & & & & TI = 0;
& & & & & & & & & & & & }*/
& & & & & & & & & & & & SBUF =
& & & & & & & & & & & & while(!TI);
& & & & & & & & & & & & TI = 0;
& & & & & & & & & & & & ES = 1;
& & & & & & & & & & & & flag = 0;
& & & & & & & & }
& & & & }
}
void serial()interrupt 4
{
& & & & temp = SBUF;
& & & & flag = 1;
& & & & RI = 0;
}
void initial()
{
& & & & TMOD = 0x20;
& & & & TH1 = 0
& & & & TL1 = 0
& & & & TR1 = 1;
& & & & REN = 1;
& & & & SM0 = 0;
& & & & SM1 =1;
& & & & EA = 1;
& & & & ES = 1;
}复制代码
已退回2积分
14:53:36
你说的1~2个数据,指的是1~2个字节,还是1~2个bit.还有你用的是串口助手之类的发的么?如果这样你还丢失的话,你可以在发送的字节中间加一个delay(30)之类的延时就应该好了
等待验证会员
20:54:39
void serial()interrupt 4
{& & if (RI) {
& && &&&temp = SBUF;& && &&&flag = 1;
& && &&&RI = 0;
改成这样试试。
21:38:21
void serial()interrupt 4
{& & if (RI) {
& && &&&temp = SBUF;& && &&&flag = 1;
发送中断时关闭了,接收的时候进入中断已经是RI=1啦,我也试了下还是有丢数据的问题。
比如我发送字符串“123”。接收后发出来只有12或13
21:40:08
你说的1~2个数据,指的是1~2个字节,还是1~2个bit.还有你用的是串口助手之类的发的么?如果这样你还丢失的话,你可以在发送的字节中间加一个delay(30)之类的延时就应该好了
比如:发送字符串“1234”,单片机接收后再发送出来可能只有123,或124,或者134等等;
我在发送数据的时候,添加了:
while(!TI);这个应该一样的效果吧
21:46:22
你说的1~2个数据,指的是1~2个字节,还是1~2个bit.还有你用的是串口助手之类的发的么?如果这样你还丢失的话,你可以在发送的字节中间加一个delay(30)之类的延时就应该好了
在SBUF = temp的后面加吗,加了无论接收到的数据是多少,发出后只有一位
22:00:01
发送中断时关闭了,接收的时候进入中断已经是RI=1啦,我也试了下还是有丢数据的问题。
比如我发送字符串“123”。接收后发出来只有12或13
就是这种状况。
(49.93 KB, 下载次数: 3)
21:59 上传
上位机收发截图
08:23:58
发送中断时关闭了,接收的时候进入中断已经是RI=1啦,我也试了下还是有丢数据的问题。
比如我发送字符串“123”。接收后发出来只有12或13
你试过加延时了,还是不正常么?
WHILE(!TI)这句话一般是放到你发送之前,就是SBUF=...这条之前。肯定是先判断串口闲置,才会发送的啊
21:55:40
你试过加延时了,还是不正常么?
WHILE(!TI)这句话一般是放到你发送之前,就是SBUF=...这条之前。肯定是先判断串口闲置,才会发送的啊
后面我把flag=0放在了ES=1之前就没有问题了。。。。。
11:11:33
后面我把flag=0放在了ES=1之前就没有问题了。。。。。
你这个flag除了占一个系统时钟,什么用都没有,所以你还得找找原因
17:42:10
应该不是flag位置的问题,你可是试试吧flag再换换位置,看看有没有什么变化
助理工程师
02:18:15
我看你的串口助手上勾选是以ASCII格式发送的,你想想看以ASCII格式发送123会得到什么?以十进制发送试试看
助理工程师
08:56:36
如果一定要用ASCII发送,把发送程序放到中断中
20:07:04
你这个flag除了占一个系统时钟,什么用都没有,所以你还得找找原因
原因我认为是:
20:15:02
你这个flag除了占一个系统时钟,什么用都没有,所以你还得找找原因
我认为原因是:
flag=0放在ES=1之后的话,在发送数据的同时,已完成另外一个字节数据的接收,RI置1;
然后执行完ES=1之后瞬间进入中断,flag=1;
退出中断服务程序,再执行flag=0;
这样,在/* ES=1;flag=0;*/中间多执行了一个/* flag=1;*/,这样就丢失了一字节的数据;
工程师职场
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司扫一扫体验手机阅读
stm32发送数据给上位机用串口调试助手接收为什么只接收到第一个字节数据?
<span type="1" blog_id="1970157" userid='
22篇文章,2W+人气,0粉丝
<span type="1" blog_id="1970157" userid='STM32上位机通过串口发送大数据返回接收异常 - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 3711|回复: 12
STM32上位机通过串口发送大数据返回接收异常
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
通过串口助手发送一串很长的数据如下上传的图所示,然后下位机原样返回串口助手发送的数据,当发送的字符串超过62个左右时,返回接收的数据在固定位置出现异常,如下图所示。发送的数据不超过62个时,发送的数据与返回数据没有异常,
1.串口中断接收的程序:
void USART1_IRQHandler(void)& && && && && & & & & &
& & & & & & & & & & & & char Res1=0; & & & && & //(USART_GetFlagStatus)
& & & & & & & & & & & &
& & & &&&if(USART_GetFlagStatus(USART1, USART_FLAG_ORE ) ==SET)//数据过载错误 。USART_IT_ORE & & & &&&USART_GetFlagStatus
& & & & & & & & {
& & & & & & & && &&&USART_ClearFlag(USART1, USART_FLAG_ORE );
& & & & & & & & & & & & USART_ReceiveData(USART1);
& & & & & & & & //& & & & Res1 =USART_ReceiveData(USART1);
& & & & & & & & //& & & & Uart1_Buf[First_Int1] = Res1;&&& & & && &//将接收到的字符串存到缓存中& & & & & & & &
& & & & & & & & //& & & & First_Int1++;
& & & & & & & & }
& & & &&&if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生
& & & && & {
& & & & & & & && &&&USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志
& & & & & & & & & & & & Res1 =USART_ReceiveData(USART1);&&
& & & & & & & & & & & & Uart1_Buf[First_Int1] = Res1;&&& & & && &//将接收到的字符串存到缓存中& & & & & & & &
& & & & & & & & & & & & First_Int1++;& && && && && & & & & & & & & & & & & & //缓存指针向后移动
& & & & & & & & }
& & & &&&if(First_Int1 & Buf1_Max )& && & & & & & & & & & //如果缓存满,将缓存指针指向缓存的首地址
& & & & & & & & {
& & & & & & & & & & & & First_Int1 = 0;
& & & & & & & & }& &
& & & & & & & &&&
2.接收到上位机数据后原样输出的程序:
& & & & if(Find1(&901A905300&))& &//901A905300检查电话卡属于哪个网络
& & & &&&{& & & && &
& & & && &UART1_SendString(Uart1_Buf);
& && && & }
**************************************************************************************************
***************************************************************************************************
希望版主能帮忙看看。。这问题困扰了我两个多星期,希望大伙能顶起。。
(177.49 KB, 下载次数: 3)
14:29 上传
红色框框位异常的位置
            
      
在线时间605 小时
ST金币3658
该用户从未签到主题帖子精华
找到Windos系统中的串口设备,设置Buffer长度.
在线时间991 小时
该用户从未签到主题帖子精华
本帖最后由 Paderboy 于
15:31 编辑
换个串口软件试试
我这有个,你试试看。。。
(687.84 KB, 下载次数: 37)
15:31 上传
点击文件名下载附件
下载积分: ST金币 -1
            
      
在线时间150 小时
该用户从未签到主题帖子精华
金牌会员, 积分 2228, 距离下一级还需 2772 积分
每个字符回传前加入延时
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
找到Windos系统中的串口设备,设置Buffer长度.
怎么在Windos系统中的串口设备,设置Buffer长度啊?
            
      
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
换个串口软件试试
我这有个,你试试看。。。
你给的那个串口软件很好用,功能更及全,但是还是出现一样的问题哦。。不知如何是好,总感觉是在缓存出现问题,但不知道怎么解决。。
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
每个字符回传前加入延时
这个我试过,但是没用还是在固定位置出现错误,在第63个字符的位置出现异常,(字符超过63个字符时就出现错误了)
            
      
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
以上问题已经解决,原先是用IFIO的方式接收缓存的数据,不知道其占用很大的存空间和时间,超过一定的存贮量数据时会使接收返回数据出错。
正确接收程序:
void USART1_IRQHandler(void)& && && && && & & & & &
& &&&char Res1=0; & & & && & & & & & & & & & & & & &
& & & &&&if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生
& & & && & {
& & & & & & & && &&&USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志
& & & & & & & & & & & & Res1 =USART_ReceiveData(USART1);//缓存指针向后移动& && && && && &&&& & & & & & & & & & & &
& & & && && && &USART_SendData(USART1, Res1);
& && &&&& & & & while (!(USART1-&SR & USART_FLAG_TXE));
& & & & & & & & }& & & & & & & &&&
在线时间4 小时
该用户从未签到主题帖子精华
初级会员, 积分 57, 距离下一级还需 143 积分
解决。。。。。。。。。。。。。。。。。。。。。。。。。
(74.18 KB, 下载次数: 0)
22:58 上传
            
      
在线时间991 小时
该用户从未签到主题帖子精华
解决就好。。
STMCU-Logo.png (21.38 KB, 下载次数: 0)
08:25 上传
STM32粉丝勋章Ⅳ
狂欢节专属(智多星)
STM32粉丝勋章Ⅲ
狂欢节专属(分享宝宝)
STM32粉丝勋章Ⅱ
狂欢节专属(研讨会问答)
STM32粉丝勋章Ⅰ
狂欢节专属(微信上墙)
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered by