OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5133|回复: 12

串口数据接收过载问题

[复制链接]

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
发表于 2018-3-16 16:47:43 | 显示全部楼层 |阅读模式
3金钱
我用STM32F030串口USART1,接收上位机发过来的一组数组,程序在进了中断服务函数之后就卡在里面出不去了,串口配置都正确,下面是我的中断服务函数和串口配置,本人新手,这是我第一个程序,百度了很多仍然没有解决,请各位大神帮忙看看

中断服务函数

中断服务函数

串口配置续

串口配置续

串口配置

串口配置
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 16:55:38 | 显示全部楼层
有人帮忙回答一下吗,谢谢了
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2018-3-16 17:08:08 | 显示全部楼层
打断点一步一步看
回复

使用道具 举报

12

主题

330

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2294
金钱
2294
注册时间
2016-5-21
在线时间
954 小时
发表于 2018-3-16 17:16:44 | 显示全部楼层
我想你定义的数组会溢出,可能就卡机了,应该if(count>20)count=0;
DUVG`}K`3SJ[]AV{5}8$%]E.png
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 17:31:55 | 显示全部楼层
xxssl 发表于 2018-3-16 17:16
我想你定义的数组会溢出,可能就卡机了,应该if(count>20)count=0;

试过了,还是不可以
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 17:33:02 | 显示全部楼层
HXYDJ 发表于 2018-3-16 17:08
打断点一步一步看

看了,就是接收中断溢出错误,但是百度了很多方法并不能使用
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-3-16 18:27:15 | 显示全部楼层
if(_BIT_TST(USART1->SR, 3))
        {
                _BIT_CLR(USART1->SR, 3);
        }
查看USART寄存器,就知道为啥这么做了
一分耕耘一分收获。
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 20:50:32 | 显示全部楼层
本帖最后由 摘星怪 于 2018-3-16 20:51 编辑

GPFSZFCZF081P_N}`E$@U.png 这个是清除中断过载错误标志位吧?我之后清楚了,可是问题还是没有解决
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 20:52:18 | 显示全部楼层
yklstudent 发表于 2018-3-16 18:27
if(_BIT_TST(USART1->SR, 3))
        {
                _BIT_CLR(USART1->SR, 3);

这个是清除中断过载错误标志位吧?我之后清楚了,可是问题还是没有解决
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2018-3-16 21:19:24 | 显示全部楼层
#ifndef __USART1_H
#define __USART1_H

#include "sys.h"
#include "stdio.h"       
#include <stdarg.h>


#define    USART1_MAX_RECV_LEN                100                             //最大接收缓存字节数
#define    USART1_MAX_SEND_LEN                200                             //最大发送缓存字节数
extern u8  USART1_RX_BUF[USART1_MAX_RECV_LEN]; //接收缓冲,最大USART1_MAX_RECV_LEN字节
extern u8  USART1_TX_BUF[USART1_MAX_SEND_LEN]; //发送缓冲,最大USART1_MAX_SEND_LEN字节
extern u16 USART1_RX_STA;                                  //接收状态标记       


void USART1_Init(u32 bound);
void USART1_printf (char *fmt, ...);
#endif





#include "usart1.h"


u8  USART1_TX_BUF[USART1_MAX_SEND_LEN];                 //发送缓冲,最大USART1_MAX_SEND_LEN字节
u8  USART1_RX_BUF[USART1_MAX_RECV_LEN];                 //接收缓冲,最大USART1_MAX_RECV_LEN字节

//接收状态
//bit15,        接收完成标志
//bit14,        接收到0x0d
//bit13~0,        接收到的有效字节数目
u16 USART1_RX_STA=0;       //接收状态标记          


//printf 实现
#pragma import(__use_no_semihosting)                    
struct __FILE {int handle;}; //标准库需要的支持函数
FILE __stdout;         
//_sys_exit(int x) {x = x;} //定义_sys_exit()以避免使用半主机模式    未开启c99
void  _sys_exit(int x){x = x;}//定义_sys_exit()以避免使用半主机模式  开启c99时 c99取消了函数返回类型默认为 int 的规定
int fputc(int ch, FILE *f)//重定义fputc函数
{      
        while(!((USART1->ISR)&(1<<7))){}
  USART1->TDR=ch;
  return (ch);
}       



void USART1_Init(u32 bound)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStruct;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //使能GPIOA的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能USART的时钟
        /* USART1的端口配置 */
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);//配置PA9成第二功能引脚        TX
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);//配置PA10成第二功能引脚  RX       

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       

        /* USART1的基本配置 */
        USART_InitStructure.USART_BaudRate = bound;              //波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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);               
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);           //使能接收中断
        USART_Cmd(USART1, ENABLE);                             //使能USART1
       
        /* USART1的NVIC中断配置 */
        NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelPriority = 0x02;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStruct);
}

void USART1_printf (char *fmt, ...)
{
                u8 i = 0;
                va_list arg_ptr;
                va_start(arg_ptr, fmt);
                vsnprintf(USART1_TX_BUF, USART1_MAX_SEND_LEN+1, fmt, arg_ptr);
                va_end(arg_ptr);
                while ((i < USART1_MAX_SEND_LEN) && USART1_TX_BUF[i])
                {
                                USART_SendData(USART1, (u8) USART1_TX_BUF[i++]);
                                while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                }
}


回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-10-27
在线时间
6 小时
 楼主| 发表于 2018-3-16 21:30:57 | 显示全部楼层
275891381 发表于 2018-3-16 21:19
#ifndef __USART1_H
#define __USART1_H

您的意思是我要定义最大缓冲字节数吗
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2019-12-12
在线时间
2 小时
发表于 2019-12-12 14:57:09 | 显示全部楼层
if((USART1->ISR&0x08) == 0x08|(USART1->ISR&0x04) == 0x04|(USART1->ISR&0x02) == 0x02)//串口接收过载清除;
                {
                        R = USART1->ICR |= 1<<1;
                        R = USART1->ICR |= 1<<2;
                        R = USART1->ICR |= 1<<3;                       
                        R = R ;                       
                }

在定时器中断或在串口中断里(只要CPU假死后还能正常运行的函数都可以)加入上面的就可以,把ORE过载、        NE、FE,3个错误 标志都清除就可以。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-12-13 02:04:13 | 显示全部楼层
仿真找问题,你这个串口中断能出去才对。另外,看看我们例程吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-21 21:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表