串口接收不定长数据

2023-05-16

这个通用的方法,其实原理就是传输两个字节间是否超过了指定时间,如果超过了一定的时间,就认为是接收完一帧数据了。首先我们要知道,串口是接收一个字节,就会发生一次中断,如果一帧数据包含10个字节,就会发生10次中断。在接收一个字节以后,会紧跟着接收下一个字节,如果时间超了一定值,就代表一帧数据已经发完了

 比如.波特率为9600,8位(数据位)+2位(开始位+停止位)=10位 :每个串口中断时间为10位 *(1000/9600),那么传一个字节1MS左右,

/*----------------------------------*/
/*-------- 定时器3 操作函数 --------*/
/*----------------------------------*/
void t3int() interrupt 19 using 1          //中断入口
{
if(uart2Ri_start){
 uart2Ri_start_time++;
  if(uart2Ri_start_time>12){
	uart2Ri_start=0;
	uart2Ri_start_time=0;
	uart2Ri_frame_flat=1;
	uart2Ri_cnt=0;
	}
  }
 	time_ms_pwm++;	
	time500ms_tmp1++;

		//时间点切换计时
		//脉冲宽度调制	
		if(time_ms_pwm <= pwm){
			OE =0;
		}else{
			OE =1;
			if(time_ms_pwm >= 14 ){
				time_ms_pwm =0;
				OE =1;
			}
		}
		RunLed++;
		if(RunLed>200){
			RunLed=0;
		RunState=~RunState;
		
		}
		
}




/*----------------------------
 串口中断2 中断服务程序
-----------------------------*/
#define S2RI  0x01              //S2CON.0
#define S2TI  0x02              //S2CON.1
#define S2RB8 0x04              //S2CON.2
#define S2TB8 0x08              //S2CON.3
char Count=0;
int uart1TimeOut=0;

char data1;
void Uart2() interrupt 8 using 1
{
	   unsigned char dat =0;                            //暂存接收的数据   
    //接收操作
    if (S2CON & S2RI){
			 S2CON &= 0xfe;
		   uart2Ri_start=1;                           //串口接收开始计时
		  
			
    if(uart2Ri_cnt<uart2Ri_maxCnt){
		    rxd_buf[uart2Ri_cnt++]=S2BUF;
		
		   }
		else
		{
		uart2Ri_cnt=uart2Ri_maxCnt;
		}
			 uart2Ri_start_time=0;
		}
    if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;         //清除S2TI位
        busy = 0;               //清忙标志
    }
		
}

 unsigned char time_ms =9;
/*******************************************************************
* 函数名 :  timer0_init
* 描述   : 1毫秒的中断。
* 参数   : ALL_INT_Enable -- 使能总中断
********************************************************************/
void tm0_isr() interrupt 1 using 1
{ 
   
		time_ms++;
		if(USART2_RX_STA & 0x40){
      uart_time_sta++;   //接收超时计时
			if( uart_time_sta >=12){
         // rx_cnt =0;
          USART2_RX_STA =0x80; //这里也清0了允许接收位
		 // USART2_485_Status_Rx_Tx=1;//接收发送标记位。
        
      }
			
		} 
	
		
}








以下是串口的部分,串口接收发送部分的调用过


#include "main.h"
#include "uart.h"
#include "protocol_process.h"
#include "stdio.h"


#define FOSC 11059200L          //系统频率
#define BAUD 115200               //串口波特率
//#define FOSC 11059200L          //系统频率
//#define BAUD 115200             //串口波特率

#define NONE_PARITY     0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY     2       //偶校验
#define MARK_PARITY     3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT EVEN_PARITY   //定义校验位

#define S2RI  0x01              //S2CON.0
#define S2TI  0x02              //S2CON.1
#define S2RB8 0x04              //S2CON.2
#define S2TB8 0x08              //S2CON.3

#define S2_S0 0x01              //P_SW2.0


bit busy;
//dong 2019-03-19
//unsigned char rx_max_len =256;
xdata unsigned char USART2_RX_BUF_test[ rx_max_len ];
xdata unsigned char USART2_RX_BUF[ rx_max_len ];
xdata unsigned char USART2_TX_BUF[ rx_max_len ];
unsigned char USART2_485_Status_Rx_Tx=0;

unsigned char USART2_RX_STA =0;    //位[7]-接收成功标志,位[6]-允许接收数据标志(包头正确标志) 
unsigned char uart_time_sta =0;    //用于串口接收计时
unsigned char rx_cnt =0;


void uart2_init(char ALL_INT_Enable)
{
    P_SW2 &= ~S2_S0;                 //S2_S0=0 (P1.0/RxD2, P1.1/TxD2)
       //P_SW2 |= S2_S0;             //S2_S0=1 (P4.6/RxD2_2, P4.7/TxD2_2)
    S2CON = 0x50;                    //8位可变波特率
    T2L = (65536 - (FOSC/4/BAUD));   //设置波特率及重装值
    T2H = (65536 - (FOSC/4/BAUD))>>8;
    AUXR |= 0x14;                    //T2为1T模式, 并启动定时器2
    IE2 = 0x01;                      //使能串口2中断
    if(ALL_INT_Enable){
      EA = 1; 
    }else{
      EA = 0; 
    }     
}

void UartInit(void)		//9600bps@11.0592MHz
{
  P_SW2 &= ~S2_S0;                 //S2_S0=0 (P1.0/RxD2, P1.1/TxD2)
	S2CON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xE0;		//设定定时初值
	T2H = 0xFE;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2

}


void SendData(unsigned char dat)  
{
    while (busy);          //等待前面的数据发送完成
    busy = 1;
    S2BUF = dat;                //写数据到UART2数据寄存器
}

void SendString(unsigned char *s, unsigned char len)   
{
    unsigned char i =0;
		for(i=0; i<len; i++){
			SendData(*s++);         //发送当前字符	
		}
		
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData2(char dat)
{
    while (busy);               //等待前面的数据发送完成
   // ACC = dat;               //获取校验位P (PSW.0)
  S2BUF = dat;                //写数据到UART2数据寄存器
    busy = 1;
}

/*----------------------------
发送字符串
----------------------------*/
void SendString2(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
    SendData2(*s++);         //发送当前字符
    }
}


//重写putchar函数
char putchar(char c)
{
     SendData2(c);
    return c;
}


//用于485接收完成数据后再发送数据
void Uart2() interrupt 8 using 1 /* UART2 中断服务程序 */
{
    unsigned char dat =0;                               //暂存接收的数据 
    unsigned char checksum =0;
    unsigned char offset =0;
  
    //接收操作
   if ( (S2CON & S2RI)  && (USART2_485_Status_Rx_Tx==0 )){  //当USART2_STA_RX_TX:0时为485数据线空闲状态。
 //   if ( (S2CON & S2RI) ){  //当USART2_STA_RX_TX:0时为485数据线空闲状态。
			 USART2_485_Status_Rx_Tx=1;
       //S2CON &= ~S2RI;        //清除S2RI位
        S2CON &= 0xfe;          //清除S2RI位
        dat = S2BUF;		   
        //数据包接收是否允许标志位检测
			   USART2_RX_STA |= 0x40;
		   //完成时不接收,清0了才能接收数据,主函数查询处理完成后置1,并将接收数据缓存清空掉待下次接收。
				if( !(USART2_RX_STA & 0x80) ){ 
            uart_time_sta =0x00;       //连续每来一字节间隔时间清0,达到不过超时时间,过了超时时间置1 
            //USART2_RX_STA的第二个位允许接收数据标志检测
            if(USART2_RX_STA & 0x40){
                if(rx_cnt < rx_max_len){
                   USART2_RX_BUF[rx_cnt++] =dat;
        }
				else
				{
                //数据包接收完成
                //  rx_cnt =0;
								//	USART2_485_Status_Rx_Tx=1; //大于最大长度退出时接收标志位为0:空闲
                  USART2_RX_STA =0x80;
                  uart_time_sta =12;
        }
        }
				}
		    }
    //发送操作
    if (S2CON & S2TI){
        //  S2CON &= ~S2TI;         //清除S2TI位
        S2CON &= 0xfd;                                  //清除S2TI位
      //  S2BUF=checksum;
        busy = 0;                                  //清忙标志
    }
		
}




void clear_rx_buf()
{
			unsigned char i =0;
			for(i=0; i<rx_max_len; i++){
				USART2_RX_BUF[i] =0;
			}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口接收不定长数据 的相关文章

  • 工业机器人主要核心

    主要核心为三部分 xff0c 控制器 xff08 就是用来控制机器人动作的那个手持设备 xff0c 可以用来编程 xff0c 一般用vxworks和linux xff0c wince来实现 xff09 伺服电机和减速器用来实现机器人的动作
  • 想搞工业机器人 这五大方面你必须了解

    origin http www robot china com news 201510 09 25754 html 1 工业机器人控制系统硬件结构 控制器是 机器人 系统的核心 xff0c 国外有关公司对我国实行严密封锁 近年来随着微电子技
  • 为什么我选择并且推崇用ROS开发机器人?

    origin http www leiphone com news 201701 zBHXGJcsRTioj4gH html 雷锋网 公众号 xff1a 雷锋网 按 xff1a 本文来自知乎 xff0c 作者贾子枫 xff0c 雷锋网已获授
  • 一飞智控CEO齐俊桐:一篇文章教你看透无人机飞控这十年

    origin http www leiphone com news 201702 YO2bskI7smE1U8TA html 无人机 又一个被国人玩坏了的单词 科幻电影里的无人机 10年前说自己是搞无人机的 xff0c 无不引来疑惑和赞叹的
  • 机器人框架

    ROS Rock Yarp Orocos
  • 列王的纷争-深度传感器已被巨头瓜分?

    origin http mt sohu com 20170325 n484729546 shtml 我们常常说苹果富可敌国 但是你这么说其实是在侮辱苹果 苹果可比美国政府有钱多了 根据最新消息 xff0c 美国政府账上的现金 xff0c 只
  • 不得不看!国内深度摄像头方案大起底

    origin http pieeco baijia baidu com article 517947 引言 xff1a 市场对深度视觉技术需求趋于井喷 xff0c 但可以提供产品和方案的公司寥寥无几 xff0c 本文分析了国内三家各具特点的
  • VR中的9轴传感器(重力加速度/陀螺仪/磁力计)

    origin http blog csdn net dabenxiong666 article details 53836503 前言 传感器的调试过程 xff0c 一般根据原厂提供demo代码 xff0c 调试数据接口 xff0c 将数据
  • STM32中AD采样的三种方法分析

    在进行STM32F中AD采样的学习中 xff0c 我们知道AD采样的方法有多种 xff0c 按照逻辑程序处理有三种方式 xff0c 一种是查询模式 xff0c 一种是中断处理模式 xff0c 一种是DMA模式 三种方法按照处理复杂方法DMA
  • 神经网络:比原来更容易学习了

    origin http geek csdn net news detail 195039 原文 xff1a NEURAL NETWORKS YOU VE GOT IT SO EASY 作者 xff1a Steven Dufresne 翻译
  • NuttX 编译系统

    origin http blog csdn net zhumaill article details 24400441 xff08 嵌入式 实时操作系统 rtos nuttx 7 1 makefile xff09 NuttX 编译系统 转载
  • NuttX 启动流程

    origin http blog csdn net zhumaill article details 23261543 xff08 嵌入式 实时操作系统 rtos nuttx 7 1 stm32 源代码分析 xff09 NuttX 启动流程
  • nuttx操作系统的移植以及下载

    origin http blog csdn net seawolfe article details 70244672 1 在ubuntu根目录下 xff1a root 64 ubuntu apt get update 更新包 2 root
  • 机器人峰会厂商

    origin http www chinarobtop com exhibition exhibition php 埃夫特 清能德创 芜湖瑞思 芜湖哈特 山东帅克机械 宁波慈兴轴承 A6 成都卡诺普 绿的谐波

随机推荐

  • 机器人公司

    1 螺趣科技 2 米兔机器人 3 360
  • 解:高性能MEMS IMU解决方案-ADXRS290

    origin https ezchina analog com message 34890 对于复杂且高动态惯性配置的MEMS IMU应用 xff0c 评估功能时需要考虑许多属性 在设计周期早期评估这些属性优于追逐开放性成果 xff0c 从
  • 关于DIY电池均衡器--被动均衡---蓄电池--电瓶车电池组电压均衡的经历

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 前言 随着电动车长时间的反复使用 xff0c 电池参数难免会发生变化 xff0c 当电池组中各节电池参数不一时 xff0c 便会出现充电时
  • CMakeLists.txt与Makefile 的区别

    我平时一般是在windows使用VS编程 xff0c 但是偶尔在网上查资料的时候也会下载一些别人的代码 xff0c 其中就经常对CMakeLists txt和Makefile文件产生疑惑 xff0c 下面我来分析一下这两个经常使用的地方 C
  • 链接提示 extern "C"

    在 C 43 43 中调用 C 代码时 xff0c 需要给编译器指定 xff23 代码要按照 xff23 语言的编译器编译 xff0c 否则编译器会将 xff23 代码按照默认的C 43 43 编译器来编译 xff23 代码 xff0c 这
  • C/C++实现你的浪漫表白:浪漫流星雨表白程序,

    想要讨女朋友欢心也巩固自己所学的知识 xff0c 各位小伙伴有自己的想法了吗 xff1f 准备好想要怎样实施了吗 xff1f 有什么美好的计划了吗 xff1f 如果没有的话那么别慌 xff0c 我知道 xff0c 在座的各位肯定都是有自己的
  • DDR4原理及硬件设计

    DDR4 DRAM的工作原理 其引脚按照功能可以分为7类 xff1a 前3类为电源 地 配置 后4类为 xff1a 控制信号 时钟信号 地址信号 数据信号 电源 地 配置信号的功能很简单 xff0c 在此不赘述 控制信号主要是用来完成DDR
  • RK3568最小系统四层板设计总结

    很久没有关注DDR4和DDR5相关知识了 xff0c 利用找工作在家休息间隙从网上下载了RK3568的原理图和6层板的PCB参考设计 xff0c 将6层板改为4层板设计 进行总结之前 xff0c 先将设计时关于Allegro设计小技巧进行总
  • 部门管理经验小结

    很久没有针对管理做总结了 xff0c 回武汉后一直做工程师 xff0c 现对管理知识体系进行总结 xff1a 部门管理按照如下框图1所示 图1
  • STM32驱动开发(二)--USB Device RNDIS虚拟网卡(usb hound抓包完整数据流分析)

    一 简介 抓包工具 xff1a usb hound xff0c 本例使用安卓手机作为device 使用RNDIS功能连接电脑虚拟网卡 抓取完整数据流包按流程进行分析 数据流程熟悉之后 xff0c 查看stm32或者其他厂家的USB库开发RN
  • 瑞芯微RK3568控制板设计总结

    本周刚使用瑞芯微RK3568设计完成一款军用控制PCB板 xff0c 特进行总结便于后续设计提升效率 一 布局相关 器件布局效率及结果对于PCB设计至关重要 xff0c 特别在使用一个新处理器如何高效的展开器件的布局设计非常重要 xff0c
  • xilinx ise 下载地址

    10 1i ed2k file Xilinx ISE DS v10 1 iso 6345773056 5211e011944e70e0e682b3f90a613695 9 1i http download xilinx com direct
  • 输出比较模式时的TIM_OCMode_PWM1和TIM_OCMode_PWM2区别

    配合结构体成员TIM OCInitTypeDef TIM OCPolarity来一起使用 现在假定TIM OCInitTypeDef TIM OCPolarity 61 TIM OCPolarity High 则起始波形为高电位 若TIM
  • 运放稳定性连载4:运放网络,SPICE分析(1)

    作者 xff1a Tim Green xff0c 德州仪器公司 2 0 引言 本系列第2部分将着重分析运放电路 xff08 尤其是两种常见运放网络 xff09 的稳定性 重要的是必须在进行SPICE 仿真前先进行1 阶分析 xff08 主要
  • 运放稳定性连载18:电容负载稳定性:输出引脚补偿(2)

    我们的CMOS RRO输出引脚补偿实例如图9 20所示 这种实际电源应用采用OPA569功率运算放大器作为可编程电源 为了在负载上提供精确的电源电压 xff0c 可以采用一种差动放大器INA152对负载电压实施差动监控 闭环系统可以补偿任何
  • 音响开关机POP声/爆破声最新解决消除方法(D类音频功放IC应用实例)

    POP声是指音频器件在上电 断电瞬间以及上电稳定后 xff0c 各种操作带来的瞬态冲击所产生的爆破声 下文结合自身在推广小功率D类音频功放IC的过程中遇到的设计问题 xff0c 就音频系统开关机POP声的解决思路和大家分享一下 降低或去除P
  • 单片机stm32 USART串口实际应用解析

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术 xff0c 相信大家都有所接触 xff0c 今天这篇就给大家详细的分析下有关于stm32的出口 xff0c 还不是很清楚的朋友要注意看看了哦 xff0c 在最后还会为大家分享有些关
  • 串口数据传输当中的共用体和结构体转换

    https www cnblogs com codecamel p 4703174 html
  • extern "C" 引起的 error C2059

    extern 34 C 34 引起的 error C2059 转 在扩展名为 C的源文件中使用 extern 34 C 34 会引发错误 C2059 xff0c 错误提示为 xff1a error C2059 syntax error 39
  • 串口接收不定长数据

    这个通用的方法 xff0c 其实原理就是传输两个字节间是否超过了指定时间 xff0c 如果超过了一定的时间 xff0c 就认为是接收完一帧数据了 首先我们要知道 xff0c 串口是接收一个字节 xff0c 就会发生一次中断 xff0c 如果