当前位置: 首页 > article >正文

中断方式的数据接收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;
		}
	}
}


http://www.kler.cn/news/155159.html

相关文章:

  • 在 AlmaLinux9 上安装Oracle Database 23c
  • 回归预测 | MATLAB实现基于LightGBM算法的数据回归预测(多指标,多图)
  • 壹财基金杨振骏:资本如何做好Web3布局?
  • 整数转罗马数字算法(leetcode第12题)
  • 单片机第三季-第六课:STM32标准库
  • sql27(Leetcode1729求关注者的数量)
  • 国家数据局首次国考招聘12人
  • vue面试题整理(1.0)
  • 深入理解 Vue 中的指针操作(二)
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • 跟我学c++高级篇——动态反射之一遍历
  • 代码浅析DLIO(四)---位姿更新
  • LeetCode(49)用最少数量的箭引爆气球【区间】【中等】
  • 基本计算器[困难]
  • 【日常踩坑】Debug 从入门到入土
  • 完美解决:wget命令下载时遇到“错误 308:Permanent Redirect。”
  • 大数据Hadoop-HDFS_架构、读写流程
  • 【小沐学Python】Python实现Web服务器(Flask+celery,生产者-消费者)
  • LeetCode每日一题 | LeetCode-1094.拼车
  • 栈实现队列,力扣
  • ESP32-Web-Server 实战编程-通过网页控制设备的 GPIO
  • MVCC-
  • 【.NET全栈】.net的微软API接口与.NET框架源码
  • LLM推理部署(三):一个强大的LLM生态系统GPT4All
  • AI - FlowField(流场寻路)
  • 2023年第十二届数学建模国际赛小美赛B题工业表面缺陷检测求解分析
  • 外包干了2年,技术退步明显。。。
  • solidity案例详解(五)能源电力竞拍合约
  • FDM3D打印系列——天秤座黄金圣斗士模型制作全过程视频
  • 微服务的流量管理-服务网格