在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

單片機(jī)接收數(shù)據(jù)幀幀頭幀尾校驗(yàn)數(shù)據(jù)解析

jf_pJlTbmA9 ? 來(lái)源:XR528787067 ? 作者:XR528787067 ? 2023-10-17 17:23 ? 次閱讀

前陣子一朋友使用單片機(jī)與某外設(shè)進(jìn)行通信時(shí),外設(shè)返回的是一堆格式如下的數(shù)據(jù):

AA AA 04 80 02 00 02 7B AA AA 04 80 02 00 08 75 AA AA 04 80 02 00 9B E2 AA AA 04 80 02 00 F6 87 AA AA 04 80 02 00 EC 91

其中 AA AA 04 80 02 是數(shù)據(jù)校驗(yàn)頭,后面三位是有效數(shù)據(jù),問(wèn)我怎么從外設(shè)不斷返回的數(shù)據(jù)中取出有效的數(shù)據(jù)。

對(duì)于這種問(wèn)題最容易想到的就是使用一個(gè)標(biāo)志位用于標(biāo)志當(dāng)前正解析到一幀數(shù)據(jù)的第幾位,然后判斷當(dāng)前接收的數(shù)據(jù)是否與校驗(yàn)數(shù)據(jù)一致,如果一致則將標(biāo)志位加一,否則將標(biāo)志位置0重新判斷,使用這種方法解析數(shù)據(jù)的代碼如下:

if(flag == 0)
{
	if(tempData == 0xAA)
		flag++;
	else
		flag = 0;
}
else if(flag == 1)
{
	if(tempData == 0xAA)
		flag++;
	else
		flag = 0;
}
else if(flag == 2)
{
	if(tempData == 0x04)
		flag++;
	else
		flag = 0;
}
else if(flag == 3)
{
	if(tempData == 0x80)
		flag++;
	else
		flag = 0;
}
else if(flag == 4)
{
	if(tempData == 0x02)
		flag++;
	else
		flag = 0;
}
else if(flag == 5 || flag == 6 || flag == 7)
{
	data[flag-5] = tempData;
	flag = (flag == 7) ? 0 : flag+1;
}

使用上述方法是最容易想到的也是最簡(jiǎn)單的方法了,百度了一下基本上也都是使用類似的方法進(jìn)行數(shù)據(jù)解析,但是使用這種方法有如下幾個(gè)缺點(diǎn):

1、 大量使用了判斷,容易導(dǎo)致出現(xiàn)邏輯混亂

2、 代碼重復(fù)率高,抽象程度低。從上述代碼可以看到一大堆代碼僅僅是判斷的數(shù)據(jù)不同,其他代碼都完全一致

3、 代碼可復(fù)用性差。寫好的代碼無(wú)法用在其他類似的外設(shè)上,如果有多個(gè)外設(shè)就需要編寫多份類似的代碼

4、 可擴(kuò)展性低。如果外設(shè)還有一個(gè)數(shù)據(jù)校驗(yàn)尾需要校驗(yàn)或者數(shù)據(jù)校驗(yàn)頭發(fā)生改變,就需要再次寫多個(gè)判斷重新用于校驗(yàn),無(wú)法在原有的代碼上進(jìn)行擴(kuò)展

5、 容易出現(xiàn)誤判

對(duì)此,這里提出了一種新的解決方案,可以通用與所有類似的數(shù)據(jù)解析,原理如下:

使用一個(gè)固定容量的隊(duì)列用來(lái)緩存接收到的數(shù)據(jù),隊(duì)列容量等于一幀數(shù)據(jù)的大小,每來(lái)一個(gè)數(shù)據(jù)就將數(shù)據(jù)往隊(duì)列里面加,當(dāng)完整接收到一幀數(shù)據(jù)時(shí)此時(shí)隊(duì)列中的全部數(shù)據(jù)也就是一幀完整的數(shù)據(jù),因此只需要判斷隊(duì)列是否是數(shù)據(jù)校驗(yàn)頭,隊(duì)列尾是否是數(shù)據(jù)校驗(yàn)尾就可以得知當(dāng)前是否已經(jīng)接收到了一幀完整的數(shù)據(jù),然后在將數(shù)據(jù)從隊(duì)列中取出即可。原理圖如下:

每來(lái)一個(gè)數(shù)據(jù)就往隊(duì)列里面加:

“單片機(jī)接收數(shù)據(jù)幀幀頭幀尾校驗(yàn)數(shù)據(jù)解析

當(dāng)接收到一幀完整數(shù)據(jù)時(shí)隊(duì)列頭和數(shù)據(jù)校驗(yàn)頭重合:

“單片機(jī)接收數(shù)據(jù)幀幀頭幀尾校驗(yàn)數(shù)據(jù)解析

此時(shí)只需要從隊(duì)列中取出有效數(shù)據(jù)即可。

如果有數(shù)據(jù)尾校驗(yàn),僅僅只需要添加一個(gè)校驗(yàn)尾即可,如下圖所示:

“單片機(jī)接收數(shù)據(jù)幀幀頭幀尾校驗(yàn)數(shù)據(jù)解析

好,分析結(jié)束,開始編碼。

首先需要一個(gè)隊(duì)列,為了保證通用性,隊(duì)列底層使用類似于雙向鏈表的實(shí)現(xiàn)(當(dāng)然也可以使用數(shù)組實(shí)現(xiàn)),需要封裝的結(jié)構(gòu)有隊(duì)列容量、隊(duì)列大小、隊(duì)頭節(jié)點(diǎn)和隊(duì)尾節(jié)點(diǎn),需要實(shí)現(xiàn)的操作有隊(duì)列初始化、數(shù)據(jù)入隊(duì)、數(shù)據(jù)出隊(duì)、清空隊(duì)列和釋放隊(duì)列,具體代碼如下:

/* queue.h */
 
#ifndef _QUEUE_H_
#define _QUEUE_H_
 
#ifndef NULL
#define	NULL	((void *)0)
#endif
 
typedef unsigned char uint8;
 
/* 隊(duì)列節(jié)點(diǎn) */
typedef struct Node
{
	uint8 data;
	struct Node *pre_node;
	struct Node *next_node;
} Node;
 
/* 隊(duì)列結(jié)構(gòu) */
typedef struct Queue
{
	uint8 capacity;     // 隊(duì)列總?cè)萘?	uint8 size;         // 當(dāng)前隊(duì)列大小
	Node *front;        // 隊(duì)列頭節(jié)點(diǎn)
	Node *back;         // 隊(duì)列尾節(jié)點(diǎn)
} Queue;
 
/* 初始化一個(gè)隊(duì)列 */
Queue *init_queue(uint8 _capacity);
/* 數(shù)據(jù)入隊(duì) */
uint8 en_queue(Queue *_queue, uint8 _data);
/* 數(shù)據(jù)出隊(duì) */
uint8 de_queue(Queue *_queue);
/* 清空隊(duì)列 */
void clear_queue(Queue *_queue);
/* 釋放隊(duì)列 */
void release_queue(Queue *_queue);
 
#endif
/* queue.c */
 
#include 
#include "parser.h"
 
/**
 * 初始化一個(gè)隊(duì)列
 *
 * @_capacity: 隊(duì)列總?cè)萘? */
Queue *init_queue(uint8 _capacity)
{
	Queue *queue = (Queue *)malloc(sizeof(Queue));
	queue->capacity = _capacity;
	queue->size = 0;
	return queue;
}
 
/**
 * 數(shù)據(jù)入隊(duì)
 *
 * @_queue: 隊(duì)列
 * @_data: 數(shù)據(jù)
 **/
uint8 en_queue(Queue *_queue, uint8 _data)
{
	if(_queue->size < _queue->capacity)
	{
		Node *node = (Node *)malloc(sizeof(Node));
		node->data = _data;
		node->next_node = NULL;
 
        if(_queue->size == 0)
        {
            node->pre_node = NULL;
            _queue->back = node;
            _queue->front = _queue->back;
        }
        else
        {
            node->pre_node = _queue->back;
 
            _queue->back->next_node = node;
            _queue->back = _queue->back->next_node;
        }
		_queue->size++;
	}
	else
	{
		Node *temp_node = _queue->front->next_node;
		_queue->front->pre_node = _queue->back;
		_queue->back->next_node = _queue->front;
		_queue->back = _queue->back->next_node;
		_queue->back->data = _data;
		_queue->back->next_node = NULL;
		_queue->front = temp_node;
	}
	return _queue->size-1;
}
 
/**
 * 數(shù)據(jù)出隊(duì)
 *
 * @_queue: 隊(duì)列
 *
 * @return: 出隊(duì)的數(shù)據(jù)
 */
uint8 de_queue(Queue *_queue)
{
    uint8 old_data = 0;
 
    if(_queue->size > 0)
    {
        old_data = _queue->front->data;
        if(_queue->size == 1)
        {
            free(_queue->front);
            _queue->front = NULL;
            _queue->back = NULL;
        }
        else
        {
            _queue->front = _queue->front->next_node;
            free(_queue->front->pre_node);
            _queue->front->pre_node = NULL;
        }
        _queue->size--;
    }
    return old_data;
}
 
/**
 * 清空隊(duì)列
 *
 * @_queue: 隊(duì)列
 */
void clear_queue(Queue *_queue)
{
    while(_queue->size > 0)
    {
        de_queue(_queue);
    }
}
 
/**
 * 釋放隊(duì)列
 *
 * @_queue: 隊(duì)列
 */
void release_queue(Queue *_queue)
{
    clear_queue(_queue);
    free(_queue);
    _queue = NULL;
}

其次是解析器,需要封裝的結(jié)構(gòu)有解析數(shù)據(jù)隊(duì)列、數(shù)據(jù)校驗(yàn)頭、數(shù)據(jù)校驗(yàn)尾、解析結(jié)果以及指向解析結(jié)果的指針,需要實(shí)現(xiàn)的操作有解析器初始化、添加數(shù)據(jù)解析、獲取解析結(jié)果、重置解析器和釋放解析器,具體代碼如下:

/* parser.h */
 
#ifndef _PARSER_H_
#define _PARSER_H_
 
#include "queue.h"
 
typedef enum
{
    RESULT_FALSE,
    RESULT_TRUE
} ParserResult;
 
/* 解析器結(jié)構(gòu) */
typedef struct DataParser
{
    Queue *parser_queue;			// 數(shù)據(jù)解析隊(duì)列
    Node *resule_pointer;			// 解析結(jié)果數(shù)據(jù)指針
    uint8 *data_header;				// 數(shù)據(jù)校驗(yàn)頭指針
    uint8 header_size;				// 數(shù)據(jù)校驗(yàn)頭大小
    uint8 *data_footer;				// 數(shù)據(jù)校驗(yàn)尾指針
    uint8 footer_size;				// 數(shù)據(jù)校驗(yàn)尾大小
    uint8 result_size;				// 解析數(shù)據(jù)大小
    ParserResult parserResult;		// 解析結(jié)果
} DataParser;
 
/* 初始化一個(gè)解析器 */
DataParser *parser_init(uint8 *_data_header, uint8 _header_size, uint8 *_data_footer, uint8 _foot_size, uint8 _data_frame_size);
/* 將數(shù)據(jù)添加到解析器中進(jìn)行解析 */
ParserResult parser_put_data(DataParser *_parser, uint8 _data);
/* 解析成功后從解析器中取出解析結(jié)果 */
int parser_get_data(DataParser *_parser, uint8 _index);
/* 重置解析器 */
void parser_reset(DataParser *_parser);
/* 釋放解析器 */
void parser_release(DataParser *_parser);
 
#endif
/* parser.c */
 
#include 
#include "parser.h"
 
/**
 * 初始化一個(gè)解析器
 *
 * @_data_header: 數(shù)據(jù)頭指針
 * @_header_size: 數(shù)據(jù)頭大小
 * @_data_footer: 數(shù)據(jù)尾指針
 * @_foot_size: 數(shù)據(jù)尾大小
 * @_data_frame_size: 一幀完整數(shù)據(jù)的大小
 *
 * @return: 解析器
 */
DataParser *parser_init(uint8 *_data_header, uint8 _header_size, uint8 *_data_footer, uint8 _foot_size, uint8 _data_frame_size)
{
    if((_header_size+_foot_size) > _data_frame_size || (_header_size+_foot_size) == 0)
        return NULL;
 
    DataParser *parser = (DataParser *)malloc(sizeof(DataParser));
    parser->parser_queue = init_queue(_data_frame_size);
    parser->resule_pointer = NULL;
    parser->data_header = _data_header;
    parser->header_size = _header_size;
	parser->data_footer = _data_footer;
	parser->footer_size = _foot_size;
    parser->result_size = _data_frame_size - parser->header_size - parser->footer_size;
    parser->parserResult = RESULT_FALSE;
 
    while(_data_frame_size-- > 0)
    {
        en_queue(parser->parser_queue, 0);
    }
 
    return parser;
}
 
/**
 * 將數(shù)據(jù)添加到解析器中進(jìn)行解析
 *
 * @_parser: 解析器
 * @_data: 要解析的數(shù)據(jù)
 *
 * @return: 當(dāng)前解析結(jié)果,返回 RESULT_TRUE 代表成功解析出一幀數(shù)據(jù)
 */
ParserResult parser_put_data(DataParser *_parser, uint8 _data)
{
    uint8 i;
    Node *node;
 
	if(_parser == NULL)
		return RESULT_FALSE;
 
    en_queue(_parser->parser_queue, _data);
 
	/* 校驗(yàn)數(shù)據(jù)尾 */
	node = _parser->parser_queue->back;
	for(i = _parser->footer_size; i > 0; i--)
	{
		if(node->data != _parser->data_footer[i-1])
            goto DATA_FRAME_FALSE;
        node = node->pre_node;
	}
 
	/* 校驗(yàn)數(shù)據(jù)頭 */
    node = _parser->parser_queue->front;
    for(i = 0; i < _parser->header_size; i++)
    {
        if(node->data != _parser->data_header[i])
            goto DATA_FRAME_FALSE;
        node = node->next_node;
    }
 
    if(_parser->resule_pointer == NULL    _parser->result_size > 0)
        _parser->resule_pointer = node;
    if(_parser->parserResult != RESULT_TRUE)
    	_parser->parserResult = RESULT_TRUE;
    return _parser->parserResult;
 
DATA_FRAME_FALSE:
    if(_parser->resule_pointer != NULL)
        _parser->resule_pointer = NULL;
    if(_parser->parserResult != RESULT_FALSE)
        _parser->parserResult = RESULT_FALSE;
    return _parser->parserResult;
 
}
 
/**
 * 解析成功后從解析器中取出解析結(jié)果
 *
 * @_parser: 解析器
 * @_index: 解析結(jié)果集合中的第 _index 個(gè)數(shù)據(jù)
 *
 * @return: 獲取解析成功的數(shù)據(jù),返回 -1 代表數(shù)據(jù)獲取失敗
 */
int parser_get_data(DataParser *_parser, uint8 _index)
{
    Node *node;
    if(_parser == NULL
	|| _parser->parserResult != RESULT_TRUE
    || _index >= _parser->result_size
    || _parser->resule_pointer == NULL)
        return -1;
    node = _parser->resule_pointer;
    while(_index > 0)
    {
        node = node->next_node;
        _index--;
    }
    return node->data;
}
 
/**
 * 重置解析器
 *
 * @_parser: 解析器
 */
void parser_reset(DataParser *_parser)
{
	uint8 _data_frame_size;
 
	if(_parser == NULL)
		return;
 
	_data_frame_size = _parser->parser_queue->size;
	while(_data_frame_size-- > 0)
    {
        en_queue(_parser->parser_queue, 0);
    }
    _parser->resule_pointer = NULL;
    _parser->parserResult = RESULT_FALSE;
}
 
/**
 * 釋放解析器
 *
 * @_parser: 解析器
 */
void parser_release(DataParser *_parser)
{
	if(_parser == NULL)
		return;
    release_queue(_parser->parser_queue);
    free(_parser);
    _parser = NULL;
}

接下來(lái)編寫測(cè)試代碼測(cè)試一下:

/* main.c */
 
#include 
#include "parser.h"
 
int main()
{
    uint8 i;
    // 數(shù)據(jù)頭
    uint8 data_header[] = {0xAA, 0xAA, 0x04, 0x80, 0x02};
    // 要解析的數(shù)據(jù),測(cè)試用
    uint8 data[] = {
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0x02, 0x7B, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x00, 0x08, 0x75, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0x9B, 0xE2,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0xF6, 0x87, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x00, 0xEC, 0x91, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x15, 0x67,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x49, 0x33, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x00, 0xE7, 0x96, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0x68, 0x15,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0x3C, 0x41, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x00, 0x66, 0x17, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0xA5, 0xD8,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x26, 0x56, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x01, 0x73, 0x09, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x64, 0x18,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x8B, 0xF1, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x01, 0xC6, 0xB6, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0x01, 0x7B, 0x01,
        0xAA, 0xAA, 0x04, 0x80, 0x02, 0x00, 0xCB, 0xB2, 0xAA, 0xAA, 0x04, 0x80,
        0x02, 0x00, 0x2C, 0x51, 0xAA, 0xAA, 0x04, 0x80, 0x02, 0xFF, 0xE5, 0x99
    };
 
    /**
     * 初始化一個(gè)解析器
     * 第一個(gè)參數(shù)是數(shù)據(jù)頭
     * 第二個(gè)參數(shù)是數(shù)據(jù)頭長(zhǎng)度
     * 第三個(gè)參數(shù)是數(shù)據(jù)尾指針
     * 第四個(gè)參數(shù)是數(shù)據(jù)尾大小
     * 第五個(gè)參數(shù)是一整幀數(shù)據(jù)的大小
     */
    DataParser *data_parser = parser_init(data_header, sizeof(data_header), NULL, 0, 8);
 
    // 將要解析的數(shù)據(jù)逐個(gè)取出,添加到解析器中
    for(i = 0; i < sizeof(data); i++)
    {
        // 解析數(shù)據(jù),返回 RESULT_TRUE 代表成功解析出一組數(shù)據(jù)
        if(parser_put_data(data_parser, data[i]) == RESULT_TRUE)
        {
            printf("成功解析出一幀數(shù)據(jù)...n");
 
            /* 一位一位取出解析后的數(shù)據(jù) */
            printf("第一個(gè)數(shù)據(jù)是:0x%xn", parser_get_data(data_parser, 0));
            printf("第二個(gè)數(shù)據(jù)是:0x%xn", parser_get_data(data_parser, 1));
            printf("第三個(gè)數(shù)據(jù)是:0x%xnnn", parser_get_data(data_parser, 2));
        }
    }
 
    // 當(dāng)不再需要解析器時(shí),應(yīng)該把解析器釋放掉,回收內(nèi)存,避免造成內(nèi)存泄漏
    parser_release(data_parser);
 
    return 0;
}

測(cè)試結(jié)果如下:

“單片機(jī)接收數(shù)據(jù)幀幀頭幀尾校驗(yàn)數(shù)據(jù)解析

從上面可以看出,解析的結(jié)果與目標(biāo)一致。

github地址:https://github.com/528787067/DataFrameParser
————————————————
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理


審核編輯 黃宇
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6043

    文章

    44621

    瀏覽量

    638567
  • 數(shù)據(jù)解析
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    3522
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    EtherCAT數(shù)據(jù)結(jié)構(gòu)解析

    物理層和常規(guī)的以太網(wǎng)卡,通過(guò)獨(dú)特的數(shù)據(jù)結(jié)構(gòu)和處理機(jī)制,實(shí)現(xiàn)了基于EtherNet的實(shí)時(shí)控制。本文將深入探討EtherCAT的數(shù)據(jù)結(jié)構(gòu),從
    的頭像 發(fā)表于 02-02 17:42 ?169次閱讀

    CAN總線通信中的數(shù)據(jù)結(jié)構(gòu)解析

    CAN總線由Bosch公司在1980年代開發(fā),旨在為汽車電子系統(tǒng)提供一個(gè)可靠的通信網(wǎng)絡(luò)。隨著技術(shù)的發(fā)展,CAN總線已經(jīng)被廣泛應(yīng)用于各種工業(yè)和自動(dòng)化領(lǐng)域。 2. CAN總線數(shù)據(jù)概述 CAN總線的數(shù)據(jù)
    的頭像 發(fā)表于 11-12 10:12 ?1205次閱讀

    以太網(wǎng)格式和功能詳解

    以太網(wǎng)(Ethernet Frame)是以太網(wǎng)(Ethernet)協(xié)議用于在局域網(wǎng)(LAN)中傳輸數(shù)據(jù)的基本單位。理解以太網(wǎng)的結(jié)構(gòu)和傳輸過(guò)程對(duì)于掌握局域網(wǎng)通信的原理至關(guān)重要。以下將從以太網(wǎng)
    的頭像 發(fā)表于 10-08 10:03 ?2312次閱讀

    以太網(wǎng)結(jié)構(gòu)是怎樣的

    以太網(wǎng)(Ethernet Frame)是以太網(wǎng)(Ethernet)協(xié)議用于在局域網(wǎng)(LAN)中傳輸數(shù)據(jù)的基本單位。理解以太網(wǎng)的結(jié)構(gòu)對(duì)于掌握局域網(wǎng)通信的原理至關(guān)重要。
    的頭像 發(fā)表于 10-08 10:00 ?1404次閱讀

    can標(biāo)準(zhǔn)和擴(kuò)展能否共存

    CAN(Controller Area Network)是一種用于汽車和工業(yè)自動(dòng)化領(lǐng)域的現(xiàn)場(chǎng)總線通信協(xié)議。CAN協(xié)議具有多種格式,包括標(biāo)準(zhǔn)和擴(kuò)展。在實(shí)際應(yīng)用中,標(biāo)準(zhǔn)和擴(kuò)展
    的頭像 發(fā)表于 07-24 15:24 ?2089次閱讀

    can標(biāo)準(zhǔn)和擴(kuò)展的區(qū)別

    景上有所不同。以下是對(duì)這兩種類型的比較: 結(jié)構(gòu) 標(biāo)準(zhǔn)和擴(kuò)展的基本結(jié)構(gòu)都是由起始、仲裁場(chǎng)、控制場(chǎng)、
    的頭像 發(fā)表于 07-24 15:20 ?2145次閱讀

    can網(wǎng)絡(luò)數(shù)據(jù)的特點(diǎn)

    特點(diǎn),在分布式系統(tǒng)中得到了廣泛應(yīng)用。 數(shù)據(jù)的重要性 :數(shù)據(jù)是CAN網(wǎng)絡(luò)中用于數(shù)據(jù)傳輸?shù)幕締卧浣Y(jié)構(gòu)設(shè)計(jì)和特性直接關(guān)系到整個(gè)網(wǎng)絡(luò)的通信
    的頭像 發(fā)表于 07-24 15:18 ?434次閱讀

    can數(shù)據(jù)有哪幾個(gè)域組成

    CAN(控制器局域網(wǎng)絡(luò))是一種基于消息傳遞的通信協(xié)議,廣泛應(yīng)用于汽車、工業(yè)自動(dòng)化和嵌入式系統(tǒng)等領(lǐng)域。CAN協(xié)議的數(shù)據(jù)是用于傳輸信息的基本單位。 1. CAN數(shù)據(jù)概述 CAN
    的頭像 發(fā)表于 07-24 15:14 ?1194次閱讀

    CAN數(shù)據(jù)的各個(gè)域及其作用

    CAN(Controller Area Network)是一種用于汽車電子系統(tǒng)中的通信協(xié)議,它具有高可靠性、實(shí)時(shí)性和靈活性等特點(diǎn)。在CAN通信中,數(shù)據(jù)是最基本的通信單元,用于傳輸信息。 概述
    的頭像 發(fā)表于 07-24 15:10 ?1658次閱讀

    CAN數(shù)據(jù)為什么要分這么多段,每一段都有什么作用?

    CAN(Controller Area Network)是一種用于汽車和工業(yè)控制系統(tǒng)的通信協(xié)議。它具有高可靠性、實(shí)時(shí)性和靈活性等特點(diǎn),被廣泛應(yīng)用于汽車、工業(yè)、醫(yī)療等領(lǐng)域。CAN數(shù)據(jù)是CAN通信
    的頭像 發(fā)表于 07-24 15:03 ?967次閱讀

    如何判斷USART接收到一幀數(shù)據(jù)

    如何判斷USART接收到一幀數(shù)據(jù)
    發(fā)表于 05-16 07:31

    stm8串口通信接收數(shù)據(jù),如何判斷是否接收完畢?

    stm8串口通信接收數(shù)據(jù)。已有的協(xié)議是只有,沒(méi)有,最后一個(gè)字節(jié)是
    發(fā)表于 05-06 07:24

    EtherCAT 數(shù)據(jù)格式和尋址方式簡(jiǎn)介

    EtherCAT是一個(gè)高實(shí)時(shí)性,高速和高效率的工業(yè)以太網(wǎng)技術(shù),數(shù)據(jù)根據(jù)自身獨(dú)有的數(shù)據(jù)格式進(jìn)行可靠傳輸,本文主要針對(duì)EtherCAT的數(shù)據(jù)
    的頭像 發(fā)表于 04-12 08:25 ?1068次閱讀
    EtherCAT <b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>幀</b>格式和尋址方式簡(jiǎn)介

    如何采用“狀態(tài)機(jī)解析UART數(shù)據(jù)

    如果一個(gè)系統(tǒng)接收上述“不定長(zhǎng)度”的協(xié)議,將會(huì)有一個(gè)挑戰(zhàn)--如何高效接收解析。 為簡(jiǎn)化系統(tǒng)設(shè)計(jì),我們強(qiáng)烈建議您采用“狀態(tài)機(jī)”來(lái)
    的頭像 發(fā)表于 03-25 14:29 ?792次閱讀
    如何采用“狀態(tài)<b class='flag-5'>機(jī)</b>”<b class='flag-5'>解析</b>UART<b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>幀</b>

    下位機(jī)CY7C68013A發(fā)送數(shù)據(jù),上位機(jī)C#讀取數(shù)據(jù),會(huì)丟幀或者內(nèi)錯(cuò)位的原因?

    下位機(jī)CY7C68013A發(fā)送數(shù)據(jù),上位機(jī)C#在1個(gè)while循環(huán)內(nèi)不斷地讀取數(shù)據(jù),510字節(jié)1,1秒333
    發(fā)表于 02-27 07:31
    主站蜘蛛池模板: 在线免费亚洲 | 资源种子在线观看 | 色啦啦影院 | 亚洲成在| 97影院理论 | 久久夜色精品国产噜噜小说 | 欧美日韩高清一本大道免费 | 婷婷综合五月天 | 波多野结衣福利 | 亚洲五月综合缴情婷婷 | 日韩免费三级 | 日日夜操 | 亲女乱h文小兰第一次 | 天天爽夜夜爽视频 | 久久午夜精品 | 亚洲福利视频一区二区 | 久久国产免费福利永久 | 狠狠狠色丁香婷婷综合久久五月 | 久久频这里精品99香蕉久网址 | 亚洲一区三区 | baoyu污污网站入口免费 | 欧美午夜在线视频 | 青草午夜精品视频在线观看 | 亚洲男人的天堂在线观看 | 我想看一级播放片一级的 | 窝窝午夜在线观看免费观看 | 色老板在线视频一区二区 | a毛片免费观看完整 | ww欧洲ww在线视频看 | 五月婷婷激情网 | 欧美一区二区三区免费高 | 男人午夜视频 | 大色综合| 丁香六月啪啪 | 色综合网址 | 欧美三级免费观看 | 亚洲伊人久久网 | 婷婷开心六月久久综合丁香 | 1000部啪啪未满十八勿入中国 | 国产ccc| 亚洲先锋资源 |