国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于MODBUS協議用STM32F103做從機接收發送數據包實驗

汽車電子技術 ? 來源:qq_34471646 ? 作者:qq_34471646 ? 2022-06-14 17:47 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

給大家分享一個網友qq_34471646做的實驗,用STM32做從機接收主機發送過來的數據包(也是基于modbus協議),而后從機將一些數據發送給主機。

首先呢還是介紹下modbus協議。其實modbus協議你不需要了解太多。既然是要使用,那么你只需要明白一點,modbus協議就是在你要發送的數據的基礎上,在數據前面加上一個幀頭,數據后面加一個幀尾。嗯,是不是還是有點迷?舉個例子吧。


寄存器108的內容表示為兩個十六進制字節值02 2B,或十進制555. 將寄存器109--110的內容分別表示為十六進制的00 00和 00 64;或十進制的0 和100.

所以主機會發過來一幀數據:01 03 00 6B 00 03 17 74(這個01是我假設主機的地址,這個域名的作用就是用來判斷是否是主機發送過來的數據。因為通信過程可能因為各種原因而導致主機發送過來的數據異常,故而我們從機接收到數據之后會先對數據進行分析主機發過來的數據是否正常,正常從機再發送數據過去,異常則不對這幀數據進行響應即從機不發數據。17 74是根據01 03 00 6B 00 03計算出來的CRC校驗值。)

當從機接收到這串數據,并且判斷數據正常則發送一幀數據到主機:02 03 06 02 2B 00 00 00 64 11 8A(同樣的02是我假設的這個從機的地址,需注意的是咱們假設自己的從機地址不要與主機的地址相同。)在這幀數據中幀頭就是02 03 06,11 8A是根據02 03 06 02 2B 00 00 00 64計算出來的CRC 校驗值也是幀尾。

那么問題來了。。。程序中我們怎么去計算CRC校驗值呢???這個嘛 ,下方我會貼上整個實驗的例程,其中CRC.c中h函數unsigned int GetCRC16(unsigned char *ptr, unsigned char len)我們只需要調用這個函數就可以算出CRC校驗值了。有興趣的也可以去額外了解下CRC校驗具體是怎么實現的。

整個實驗例程如下:

main.c:

#include "stm32f10x.h"
#include "bsp_485.h"
#include "bsp_led.h"
#include "crc16.h"
/*描述:硬件:RS485接口 協議:Modbus RTU
*功能:采用DMA方式發送數據,中斷方式接收數據。
*注: 接收到指令之后,判斷是否是相應指令而進行DMA數據發送。
*/
/*DMA:開啟DMA,DMA發送完一幀數據后產生發送完成中斷,
* 在DMA發送完成中斷中,開啟USART接收中斷(字節)
* 在USART接收中斷中保存接收到的數據。
*注: 本程序額外開啟了USART空閑中斷,在空閑中斷中將
* USART接收中斷中接收到的數據發送至串口調試助手顯示
* 并開啟DMA請求
*/
extern uint8_t u3Temp;
extern uint16_t uart3_p;
extern uint16_t ReceivedUsart3Flag,tempU3,uart3_RXbuff[];
extern uint8_t SendU3Buff[SENDU3BUFF_SIZE];
uint16_t len,iU3;
uint8_t u2_Temp;
char *pbuf;
void SendUsart3Buff(void);
void SendU3DatatoDebug(void);
void load_U3_SendBuff(void);
int main(void)
{
load_U3_SendBuff();
LED_GPIO_Config();
USART3_Config();
while(1)
{
}
}
/*Description:調試通信程序專用,用于將接收到的數據再發送到串口調試助手顯示*/
void SendU3DatatoDebug()
{
for(uart3_p= 1; uart3_p <= u3Temp; uart3_p++)
{
Usart_SendByte(USART3,uart3_RXbuff[uart3_p]);
}
uart3_p = 1;
RS485_RX_EN();
ReceivedUsart3Flag = 0;
}
/*將USART3需要發送的數據存放在SendU3Buff[]中*/
void load_U3_SendBuff()
{
uint16_t CRCtemp;
SendU3Buff[0]=0x01;//ID
SendU3Buff[1]=0x03;//功能碼
SendU3Buff[2]=0x0C;//內容數據字節數
/*填充將要發送的數據(兩個字節為一個寄存器的值)*/
SendU3Buff[3]=0x00; //數據1(slave地址0,網站上地址40001)
SendU3Buff[4]=0x64;
SendU3Buff[5]=0x00;//數據2(slave地址1,網站上地址40002)
SendU3Buff[6]=0x96;
SendU3Buff[7]=0x00;//數據3
SendU3Buff[8]=0xC8;
SendU3Buff[9]=0x00; //4
SendU3Buff[10]=0xFA;
SendU3Buff[11]=0x01;//5頁面未添加該數據
SendU3Buff[12]=0x2B;
SendU3Buff[13]=0x01;//6
SendU3Buff[14]=0x5E;
CRCtemp = GetCRC16(SendU3Buff, 15);
/*CRC校驗值*/
SendU3Buff[15] = CRCtemp;//存放CRCl
SendU3Buff[16] = (CRCtemp >> 8); //保存CRCh//SendBuff[i] = ((CRCtemp<<8)|(CRCtemp>>8)); //保存CRCh
}
485.c:

#include "bsp_485.h"
uint8_t SendU3Buff[SENDU3BUFF_SIZE];
static void NVIC_USART3_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中斷控制器組選擇 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART為中斷源 */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
/* 搶斷優先級*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子優先級 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中斷 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
static void NVIC_DMA1_2_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中斷控制器組選擇 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART為中斷源 */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
/* 搶斷優先級*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子優先級 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
/* 使能中斷 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
//static void NVIC_DMA1_2_Configuration(void)
//{
// NVIC_InitTypeDef NVIC_InitStructure; /* Configure one bit for preemption priority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//}
/**
* U3:TX:PB10 RX:PB11 TXRXEN:PD3
* U5:TX:PC12 RX:PD1 TXRXEN:PD0
*
*/
void USART3_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打開串口GPIO的時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//TX、RX是時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//EN時鐘
// 打開串口外設的時鐘
DEBUG_USART_APBxClkCmd(RCC_APB1Periph_USART3, ENABLE);//USART時鐘
// 將USART Tx的GPIO配置為推挽復用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 將USART Rx的GPIO配置為浮空輸入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 設置485收發控制管腳為推挽輸出Out_PP */
GPIO_InitStructure.GPIO_Pin = RS485_RE_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD , &GPIO_InitStructure);
// 配置串口的工作參數
// 配置波特率
USART_InitStructure.USART_BaudRate = 115200;
// 配置 針數據字長
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校驗位
USART_InitStructure.USART_Parity = USART_Parity_No ;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收發一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(USART3, &USART_InitStructure);
// 串口中斷優先級配置
NVIC_USART3_Configuration();
// 使能串口接收中斷
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// 使能串口空閑中斷(用于檢測一幀數據接收完畢)
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
// 使能串口
USART_Cmd(USART3, ENABLE);
/*控制 485 芯片進入接收模式*/
RS485_RX_EN();//
}
void USART3_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// 開啟DMA時鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* 復位初始化 DMA 數據流 */
DMA_DeInit(DMA1_Channel2);
// 設置DMA外設地址:串口數據寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;
// 內存地址(要傳輸的變量的指針)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendU3Buff;
// 方向:從內存到外設
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
// 傳輸大小
DMA_InitStructure.DMA_BufferSize = SENDU3BUFF_SIZE;
// 外設地址不增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 內存地址自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外設數據單位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
// 內存數據單位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
// DMA模式,一次或者循環模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
// 優先級:中
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
// 禁止內存到內存的傳輸
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// 配置DMA通道
DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure);
NVIC_DMA1_2_Configuration();
//開啟DMA通道的TC中斷:傳輸完成中斷
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
// 使能DMA
DMA_Cmd (DMA1_Channel2,ENABLE);
}
/***************** 發送一個字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 發送一個字節數據到USART */
USART_SendData(pUSARTx,ch);
/* 等待發送數據寄存器為空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/***************** 發送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do
{
Usart_SendByte( pUSARTx, *(str + k) );
k++;
} while(*(str + k)!='\0');
/* 等待發送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
{}
}
/***************** 發送一個16位數 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
uint8_t temp_h, temp_l;
/* 取出高八位 */
temp_h = (ch&0XFF00)>>8;
/* 取出低八位 */
temp_l = ch&0XFF;
/* 發送高八位 */
USART_SendData(pUSARTx,temp_h);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
/* 發送低八位 */
USART_SendData(pUSARTx,temp_l);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/*
Desc:接收中斷時,將接收到的所有數據用數組保存。
*/
//中斷緩存串口數據
#define UART_BUFF_SIZE 1024
uint16_t uart3_p = 1;
uint16_t uart3_RXbuff[UART_BUFF_SIZE];
uint8_t u3Temp;
uint8_t tempU3;
uint8_t ReceivedUsart3Flag = 0;
uint16_t clr;
uint16_t a=0x00;
void bspU3_RS485_IRQHandler(void)
{
if (USART_GetITStatus( USART3, USART_IT_RXNE) != RESET) //收到一個字節的數據
{//保存接收到的數據
uart3_RXbuff[uart3_p] = USART_ReceiveData(USART3);
uart3_p++;
}
if (USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //收到一幀的數據
{//將接收到的數據發送到串口調試助手上以便觀察數據是否正確
u3Temp = uart3_p-1;
clr = USART3->SR;
clr = USART3->DR;
ReceivedUsart3Flag = 1;
RS485_TX_EN() ;
// for(uart3_p= 1; uart3_p <= u3Temp; uart3_p++)//調試通信程序專用,用于將接收到的數據再發送到串口調試助手顯示
// {
// Usart_SendByte(USART3,uart3_RXbuff[uart3_p]);
// }
uart3_p = 1;
// LED1_OFF;
// LED2_OFF;
// LED3_OFF;
// LED4_OFF;
LED1_ON;
LED2_ON;
LED3_ON;
LED4_ON;
if(uart3_RXbuff[1]==0x01&&uart3_RXbuff[2]==0x03&&uart3_RXbuff[3]==0x00&&uart3_RXbuff[4]==0x00&&
uart3_RXbuff[5]==0x00&&uart3_RXbuff[6]==0x06&&uart3_RXbuff[7]==0xC5&&uart3_RXbuff[8]==0xC8)
// uart3_RXbuff[9]==0x00&&uart3_RXbuff[10]==0x01&&uart3_RXbuff[11]==0x03&&uart3_RXbuff[12]==0x9C&&
// uart3_RXbuff[13]==0x41&&uart3_RXbuff[14]==0x00&&uart3_RXbuff[15]==0x02&&uart3_RXbuff[16]==0x17&&
{
/* DMA發送使能 */
USART3_DMA_Config();
RS485_TX_EN() ;
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);//這個放在最后
}
}
}
void bspU3_RS485_DMA_IRQHandler()
{
if(DMA_GetITStatus(DMA1_IT_TC2))
{
//清TC標志
DMA_ClearITPendingBit(DMA1_IT_GL2); //清除全部中斷標志 //DMA_ClearFLAG(DMA1_FLAG_TC2); //清除全部中斷標志(這種寫法也可以)
while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); //等待USART1發送完成標志TC置1
USART_ClearFlag(USART3, USART_FLAG_TC); //清除發送完成標志
}
//關閉DMA通道
DMA_Cmd(DMA1_Channel2, DISABLE);
RS485_RX_EN();
}

CRC16.c:

#include "crc16.h"
unsigned int GetCRC16(unsigned char *ptr, unsigned char len)
{
uint16_t index;
uint8_t crcl = 0xFF; //高CRC字節
uint8_t crch = 0xFF; //低CRC字節
uint8_t TabH[] = { //CRC高位字節值表
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
u8 TabL[] = { //CRC低位字節值表
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
while (len--) //計算指定長度的CRC
{
index = crcl ^ *ptr++;
crcl = crch ^ TabH[index];
crch = TabL[index];
}
return ((crch<<8) | crcl);??
}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • MODBUS
    +關注

    關注

    28

    文章

    2457

    瀏覽量

    83228
  • STM32
    +關注

    關注

    2309

    文章

    11162

    瀏覽量

    373472
  • ModBus協議
    +關注

    關注

    3

    文章

    190

    瀏覽量

    35325
  • STM32F103
    +關注

    關注

    34

    文章

    495

    瀏覽量

    67719
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Modbus協議的深度剖析

    ,幫助讀者深入理解這一經典工業通信協議。 一、協議起源與發展歷程 Modbus協議誕生于1979年,由Modicon公司(現為施耐德電氣旗下品牌)為PLC通信而設計。其最初目的是實現工業設備間的簡單可靠的
    的頭像 發表于 11-07 07:43 ?874次閱讀
    <b class='flag-5'>Modbus協議</b>的深度剖析

    Modbus協議轉HTTP協議,實現JSON格式對接MES等系統平臺

    ),左邊選擇(PLC數據對接: ...),右邊選擇對應的PLC驅動(本案選Modbus協議集),點 確定當前選擇; 2. 進入數據配置表(功能->數據轉發/平臺對接):根據PLC
    發表于 10-27 10:33

    SPI主機/接收發送都開啟DMA通信

    AT32_SPI主機/接收發送都開啟DMA通信 示例目的 本示例代碼展示了如何使用 AT32 的 DMA 進行 SPI 數據傳輸。SPI 作為主機時,
    發表于 09-10 16:56

    【RA4M2-SENSOR】—— 10.實現modbus協議

    modbus協議在工業控制領域有著廣泛的應用,很多機器人控制和PLC伺服控制器都是使用modbus協議來通信的。 本次測評就是使用我自己實現的modbus slave
    發表于 09-01 07:06

    STM32F103長時間運行,串口發送失敗怎么解決?

    STM32F103長時間運行,串口發送失敗,目前定位到一致卡在USART_FLAG_TC判斷那里,我們采用輪詢的方式發送數據,然后判斷USART_FLAG_TC是否
    發表于 07-30 07:55

    STM32F103c8上DLQR最優控制算法的C編程資料

    這是我近期的一個項目--基于STM32F103c8的DLQR控制算法的C編程,涉及DLQR最優控制算法、嵌入式STM32F103編程、CMSIS-DSP庫使用。? ??附有完整的程序。
    發表于 07-23 15:30 ?0次下載

    Modbus協議轉換:讓工業設備輕松“對話”

    在工業自動化中,Modbus協議是設備通信的關鍵。本文將聚焦于Modbus協議的串口與網口轉換需求,并通過ZLG致遠電子PXB-6030D的案例,展示如何輕松實現協議轉換。Modbus協議
    的頭像 發表于 07-15 11:47 ?659次閱讀
    <b class='flag-5'>Modbus協議</b>轉換:讓工業設備輕松“對話”

    大彩講堂:VisualTFT軟件modbus協議下的告警應用

    VisualTFT軟件modbus協議下的告警應用
    的頭像 發表于 07-01 17:40 ?1213次閱讀
    大彩講堂:VisualTFT軟件<b class='flag-5'>modbus協議</b>下的告警應用

    STM32F103 I2C接收數據的問題

    我使用STM32F103做一個I2C接收數據的功能,通過查閱函數手冊,使用了2種方法 方法1: 1、調用HAL_I2C_EnableLi
    發表于 06-06 12:29

    CS32F103RB有無驅動例程,是否可用stm32F103的驅動代碼?

    如果不能使用stm32F103驅動的話,請把驅動例程發送1830665518@qqcom
    發表于 05-15 10:54

    STM32F103x8 STM32F103xB單片數據手冊

    STM32F103x8STM32F103xB單片數據手冊
    發表于 04-14 14:55 ?8次下載

    SEI實現BiSS-C協議發送TIMEOUT期間CDM如何接收

    SEI實現BiSS-C協議發送TIMEOUT期間CDM如何接收
    發表于 04-07 11:09

    為UART、MCXA142實現ISP通信的主機端,發送Ping數據包并收到預期的響應,發送接收數據包的典型順序是什么?

    我想為 UART、MCXA142 實現 ISP 通信的主機端。我發送 Ping 數據包并收到預期的響應。發送接收數據包的典型順序是什么?
    發表于 04-03 08:05

    STM32F103×8/STM32F103×B MCU手冊

    參考第2.2節:整個系列的完全兼容性。中密度STM32F103xx數據手冊必須與低、中、高密度STM 32 f 10 xx參考手冊一起閱讀。有關數據手冊和參考手冊的設備勘誤表信息,請參
    發表于 03-18 16:37 ?0次下載

    STM32F103站 上電過程,上位不斷發送數據造成,通訊失敗怎么解決?

    主機上掛了多個STM32 485站, 主機不斷輪詢發送數據STM32上電過程中如果主站已經在不斷發送
    發表于 03-13 08:11