中断方式的数据接收2

Echo实验

回忆之前的实验因为数据处理的过程可以瞬间完成所以可以把数据处理的操作放在中断服务函数中执行
但是数据处理要是时间过长就将数据缓存处理
在这里插入图片描述
在这里插入图片描述
当使用中断方式接收数据的时候 一般有两种方式 数据处理的时间较短可放在中断服务函数内处理(就地处理) 第二种就是数据处理时间较长需要缓存数据来延时处理
就地处理
在这里插入图片描述
当RXNE每次由0变为1就表示有一个数据传入 (一个字符的传入) 第一个字符为H 存入数组a[0] 接着接收剩余的字符 直到满足条件 数组a的倒数第二个位存放的是字符\r 最后一个位置存放的是字符\n 就发送数据 同时清空数组
在这里插入图片描述
但是发送数据的操作太占时间了 无法瞬间处理 所以需要延时处理数据
在发送数据的时候因为时间过长 无法做到瞬间处理 如果这时候有数据传输进来就会造成数据的丢失 所以不能使用就地处理的方式
队列简介
在这里插入图片描述
队列的工作原理
在这里插入图片描述
队列c语言的实现

在这里插入图片描述
注意Tail最开始的位置指向就是数组的第一个位置
其中出队的操作 返回值为errorstatus 传入参数为记录出队的数据
当队列为空的时候 出队错误 返回ERROR 只有队列不为空才可以正常出队

头文件主要是声明结构体和函数的 源文件主要是实现函数的原型的

queue.h

#ifndef _QUEUE_H_
#define _QUEUE_H_


#include "stm32f10x.h"
typedef struct
{
	uint8_t Data[100];
	uint16_t Tail;//队尾

}Queue_HandleTypeDef;


void Queue_Init(Queue_HandleTypeDef *hQueue); //队列的初始化
void Queue_Enqueue(Queue_HandleTypeDef *hQueue,uint8_t Element);//进队操作
ErrorStatus Queue_Dequeue(Queue_HandleTypeDef *hQueue, uint8_t *pElement);//出队操作

#endif //防止头文件被重复引用

queue.c

#include "queue.h"
void Queue_Init(Queue_HandleTypeDef *hQueue)
{
			hQueue ->Tail = 0;//初始化指针指向数组的第一个位置
		

}

void Queue_Enqueue(Queue_HandleTypeDef *hQueue,uint8_t Element)
{

		hQueue ->Data[hQueue->Tail ++] = Element; //进队操作

}

ErrorStatus Queue_Dequeue( Queue_HandleTypeDef *hQueue ,uint8_t *pElement) //把一个元素移出队列
{
			uint16_t i;
		if(hQueue ->Tail == 0) return ERROR; //队列空操作无效
		*pElement = hQueue ->Data[0]; //输出的元素用变量pElement接收
			for(i=0;i<hQueue->Tail-1;i++)
				{
					hQueue->Data[i] = hQueue->Data[i+1];//把第一个元素从队列中拿走 就将队列中的剩余元素全都向前移一个位 右边的变为左边的
				}
				hQueue->Tail--; //指针右移一个位
				return SUCCESS;
}


延迟处理
在这里插入图片描述
在触发中断后 在中断服务函数中把数据存放到缓冲区 然后在进程函数中把数据从缓冲区取出 进行处理
为了防止在进程函数中出队的过程被中断函数打断
进程函数

static void USART_Echo_Proc(void)
{
	uint8_t c;
	
	USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //为了防止在进程函数中出队的过程被中断函数打断
	ErrorStatus error = Queue_Dequeue(&hQueue, &c);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	if(error == SUCCESS)
	{
		a[cursor++] = c;
		
		if(cursor>2 && a[cursor-2] == '\r'&& a[cursor - 1] == '\n') // 收到新行
		{
			// 发送出去
			a[cursor] = 0;
			USART1_SendString((const char *)a);
			cursor=0;
		}
	}
}

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值