最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決Python串口接收無標(biāo)識不定長數(shù)據(jù)

 更新時間:2023年09月06日 14:56:58   作者:我我我只會printf  
這篇文章主要介紹了解決Python串口接收無標(biāo)識不定長數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Python串口接收無標(biāo)識不定長數(shù)據(jù)

python串口讀取數(shù)據(jù)可以使用:

  • serial.read(n) n為讀取數(shù)據(jù)個數(shù),無參則讀取一個
  • serial.readline() 讀取到\n,讀不到則阻塞直到讀取到\n

在接收不定長數(shù)據(jù)時,沒有n可以指定,接收數(shù)據(jù)也未必有\(zhòng)n,python又沒有串口空閑中斷,但是可以用延時來解決。

import serial
from time import sleep
ser = serial.Serial(port="COM5",baudrate=9600,timeout=0.5)
if ser.isOpen() :
    print("open")
    while True :
        n = ser.inWaiting()
        if n :
            sleep(0.1)
            n = ser.inWaiting()
            data = ser.read(n)
            print(data)
else:
    print(" not open")
ser.close()

接收可以單開一個線程,在接收到數(shù)據(jù)后延時0.1s再查詢當(dāng)前緩沖區(qū)數(shù)據(jù)個數(shù),第一次查詢并不接收,所以不會清除緩存。

相當(dāng)于接收到數(shù)據(jù)后,延時0.1s后再取數(shù)據(jù)。

也就是下位機(jī)發(fā)送的數(shù)據(jù)需要在0.1s內(nèi)發(fā)送完成,發(fā)送間隔大于0.1s。

這個時間應(yīng)該根據(jù)下位機(jī)發(fā)送來定。

注意:

上位機(jī)與下位機(jī)數(shù)據(jù)收發(fā)時序需考慮

串口接收不定長數(shù)據(jù)的問題

這個通用的方法,其實(shí)原理就是傳輸兩個字節(jié)間是否超過了指定時間,如果超過了一定的時間,就認(rèn)為是接收完一幀數(shù)據(jù)了。

首先我們要知道,串口是接收一個字節(jié),就會發(fā)生一次中斷,如果一幀數(shù)據(jù)包含10個字節(jié),就會發(fā)生10次中斷。

在接收一個字節(jié)以后,會緊跟著接收下一個字節(jié),如果時間超了一定值,就代表一幀數(shù)據(jù)已經(jīng)發(fā)完了

比如.

波特率為9600,8位(數(shù)據(jù)位)+2位(開始位+停止位)=10位 :每個串口中斷時間為10位 *(1000/9600),那么傳一個字節(jié)1MS左右,

/*----------------------------------*/
/*-------- 定時器3 操作函數(shù) --------*/
/*----------------------------------*/
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++;
		//時間點(diǎn)切換計(jì)時
		//脈沖寬度調(diào)制	
		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 中斷服務(wù)程序
-----------------------------*/
#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;                            //暫存接收的數(shù)據(jù)   
    //接收操作
    if (S2CON & S2RI){
			 S2CON &= 0xfe;
		   uart2Ri_start=1;                           //串口接收開始計(jì)時
    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;               //清忙標(biāo)志
    }
}
 
 unsigned char time_ms =9;
/*******************************************************************
* 函數(shù)名 :  timer0_init
* 描述   : 1毫秒的中斷。
* 參數(shù)   : ALL_INT_Enable -- 使能總中斷
********************************************************************/
void tm0_isr() interrupt 1 using 1
{ 
		time_ms++;
		if(USART2_RX_STA & 0x40){
      uart_time_sta++;   //接收超時計(jì)時
			if( uart_time_sta >=12){
         // rx_cnt =0;
          USART2_RX_STA =0x80; //這里也清0了允許接收位
		 // USART2_485_Status_Rx_Tx=1;//接收發(fā)送標(biāo)記位。
      }
		} 
}
 

以下是串口的部分,串口接收發(fā)送部分的調(diào)用過

 
#include "main.h"
#include "uart.h"
#include "protocol_process.h"
#include "stdio.h"
#define FOSC 11059200L          //系統(tǒng)頻率
#define BAUD 115200               //串口波特率
//#define FOSC 11059200L          //系統(tǒng)頻率
//#define BAUD 115200             //串口波特率
#define NONE_PARITY     0       //無校驗(yàn)
#define ODD_PARITY      1       //奇校驗(yàn)
#define EVEN_PARITY     2       //偶校驗(yàn)
#define MARK_PARITY     3       //標(biāo)記校驗(yàn)
#define SPACE_PARITY    4       //空白校驗(yàn)
#define PARITYBIT EVEN_PARITY   //定義校驗(yàn)位
#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]-接收成功標(biāo)志,位[6]-允許接收數(shù)據(jù)標(biāo)志(包頭正確標(biāo)志) 
unsigned char uart_time_sta =0;    //用于串口接收計(jì)時
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));   //設(shè)置波特率及重裝值
    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位數(shù)據(jù),可變波特率
	AUXR |= 0x04;		//定時器2時鐘為Fosc,即1T
	T2L = 0xE0;		//設(shè)定定時初值
	T2H = 0xFE;		//設(shè)定定時初值
	AUXR |= 0x10;		//啟動定時器2
}
void SendData(unsigned char dat)  
{
    while (busy);          //等待前面的數(shù)據(jù)發(fā)送完成
    busy = 1;
    S2BUF = dat;                //寫數(shù)據(jù)到UART2數(shù)據(jù)寄存器
}
void SendString(unsigned char *s, unsigned char len)   
{
    unsigned char i =0;
		for(i=0; i<len; i++){
			SendData(*s++);         //發(fā)送當(dāng)前字符	
		}
}
/*----------------------------
發(fā)送串口數(shù)據(jù)
----------------------------*/
void SendData2(char dat)
{
    while (busy);               //等待前面的數(shù)據(jù)發(fā)送完成
   // ACC = dat;               //獲取校驗(yàn)位P (PSW.0)
  S2BUF = dat;                //寫數(shù)據(jù)到UART2數(shù)據(jù)寄存器
    busy = 1;
}
/*----------------------------
發(fā)送字符串
----------------------------*/
void SendString2(char *s)
{
    while (*s)                  //檢測字符串結(jié)束標(biāo)志
    {
    SendData2(*s++);         //發(fā)送當(dāng)前字符
    }
}
//重寫putchar函數(shù)
char putchar(char c)
{
     SendData2(c);
    return c;
}
//用于485接收完成數(shù)據(jù)后再發(fā)送數(shù)據(jù)
void Uart2() interrupt 8 using 1 /* UART2 中斷服務(wù)程序 */
{
    unsigned char dat =0;                               //暫存接收的數(shù)據(jù) 
    unsigned char checksum =0;
    unsigned char offset =0;
    //接收操作
   if ( (S2CON & S2RI)  && (USART2_485_Status_Rx_Tx==0 )){  //當(dāng)USART2_STA_RX_TX:0時為485數(shù)據(jù)線空閑狀態(tài)。
 //   if ( (S2CON & S2RI) ){  //當(dāng)USART2_STA_RX_TX:0時為485數(shù)據(jù)線空閑狀態(tài)。
			 USART2_485_Status_Rx_Tx=1;
       //S2CON &= ~S2RI;        //清除S2RI位
        S2CON &= 0xfe;          //清除S2RI位
        dat = S2BUF;		   
        //數(shù)據(jù)包接收是否允許標(biāo)志位檢測
			   USART2_RX_STA |= 0x40;
		   //完成時不接收,清0了才能接收數(shù)據(jù),主函數(shù)查詢處理完成后置1,并將接收數(shù)據(jù)緩存清空掉待下次接收。
				if( !(USART2_RX_STA & 0x80) ){ 
            uart_time_sta =0x00;       //連續(xù)每來一字節(jié)間隔時間清0,達(dá)到不過超時時間,過了超時時間置1 
            //USART2_RX_STA的第二個位允許接收數(shù)據(jù)標(biāo)志檢測
            if(USART2_RX_STA & 0x40){
                if(rx_cnt < rx_max_len){
                   USART2_RX_BUF[rx_cnt++] =dat;
        }
				else
				{
                //數(shù)據(jù)包接收完成
                //  rx_cnt =0;
								//	USART2_485_Status_Rx_Tx=1; //大于最大長度退出時接收標(biāo)志位為0:空閑
                  USART2_RX_STA =0x80;
                  uart_time_sta =12;
        }
        }
				}
		    }
    //發(fā)送操作
    if (S2CON & S2TI){
        //  S2CON &= ~S2TI;         //清除S2TI位
        S2CON &= 0xfd;                                  //清除S2TI位
      //  S2BUF=checksum;
        busy = 0;                                  //清忙標(biāo)志
    }
}
void clear_rx_buf()
{
			unsigned char i =0;
			for(i=0; i<rx_max_len; i++){
				USART2_RX_BUF[i] =0;
			}
}

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Pandas_cum累積計(jì)算和rolling滾動計(jì)算的用法詳解

    Pandas_cum累積計(jì)算和rolling滾動計(jì)算的用法詳解

    今天小編就為大家分享一篇Pandas_cum累積計(jì)算和rolling滾動計(jì)算的用法詳解,具有好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python實(shí)現(xiàn)將HTML轉(zhuǎn)換成doc格式文件的方法示例

    Python實(shí)現(xiàn)將HTML轉(zhuǎn)換成doc格式文件的方法示例

    這篇文章主要介紹了Python實(shí)現(xiàn)將HTML轉(zhuǎn)換成doc格式文件的方法,涉及Python htmlparser及docx模塊的相關(guān)使用技巧,需要的朋友可以參考下
    2017-11-11
  • Django框架模板用法入門教程

    Django框架模板用法入門教程

    這篇文章主要介紹了Django框架模板用法,結(jié)合簡單入門實(shí)例形式分析了Django框架模板標(biāo)簽、過濾器、模板繼承等概念與使用技巧,需要的朋友可以參考下
    2019-11-11
  • Flask入門之上傳文件到服務(wù)器的方法示例

    Flask入門之上傳文件到服務(wù)器的方法示例

    這篇文章主要介紹了Flask入門之上傳文件到服務(wù)器的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • 淺談Tensorflow由于版本問題出現(xiàn)的幾種錯誤及解決方法

    淺談Tensorflow由于版本問題出現(xiàn)的幾種錯誤及解決方法

    今天小編就為大家分享一篇淺談Tensorflow由于版本問題出現(xiàn)的幾種錯誤及解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 詳談tensorflow gfile文件的用法

    詳談tensorflow gfile文件的用法

    今天小編就為大家分享一篇詳談tensorflow gfile文件的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python列表推導(dǎo)式與生成器用法分析

    Python列表推導(dǎo)式與生成器用法分析

    這篇文章主要介紹了Python列表推導(dǎo)式與生成器用法,結(jié)合實(shí)例形式分析了列表推導(dǎo)式、生成器的原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-08-08
  • 利用python實(shí)現(xiàn)數(shù)據(jù)分析

    利用python實(shí)現(xiàn)數(shù)據(jù)分析

    為什么要利用python進(jìn)行數(shù)據(jù)分析?python擁有一個巨大的活躍的科學(xué)計(jì)算社區(qū),擁有不斷改良的庫,能夠輕松的集成C,C++,Fortran代碼(Cython項(xiàng)目),可以同時用于研究和原型的構(gòu)建以及生產(chǎn)系統(tǒng)的構(gòu)建。
    2017-01-01
  • Python selenium自動化測試模型圖解

    Python selenium自動化測試模型圖解

    這篇文章主要介紹了Python selenium自動化測試模型圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • pycharm2020.2 配置使用的方法詳解

    pycharm2020.2 配置使用的方法詳解

    這篇文章主要介紹了pycharm2020.2 配置使用的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09

最新評論

大埔县| 怀仁县| 舞钢市| 奉贤区| 彭水| 敦化市| 蓝山县| 旬阳县| 庄河市| 阳城县| 延吉市| 盐山县| 云南省| 方正县| 牡丹江市| 广宁县| 南充市| 界首市| 平阳县| 西丰县| 静宁县| 新民市| 宁明县| 姚安县| 河曲县| 岳西县| 汉源县| 宁强县| 南安市| 招远市| 益阳市| 融水| 丹棱县| 临泽县| 定西市| 共和县| 塔城市| 山阴县| 奇台县| 湖州市| 会宁县|