Follow+Star Public Account, don’t miss out on exciting content
Author | strongerHuang
WeChat Official Account | strongerHuang
Before sharing the main content, I would like to recommend some embedded-related positions:

What is a communication protocol?
A communication protocol refers to the rules and agreements that both parties must follow to complete communication or services. In a data communication system with multiple different geographic locations interconnected through communication channels and devices, they must have a common language to work together to achieve information exchange and resource sharing. What to communicate, how to communicate, and when to communicate must follow mutually acceptable rules. This rule is the communication protocol.
Frame Head | Temperature Value | Frame Tail |
---|---|---|
5A | One Byte Value | 3B |
Problems Caused by Overly Simple Communication Protocols
Common Contents of Communication Protocols
Code Implementation of Communication Protocol
#define DGUS_FRAME_HEAD1 0xA5 // DGUS screen frame head 1#define DGUS_FRAME_HEAD2 0x5A // DGUS screen frame head 2
#define DGUS_CMD_W_REG 0x80 // DGUS write register command
#define DGUS_CMD_R_REG 0x81 // DGUS read register command
#define DGUS_CMD_W_DATA 0x82 // DGUS write data command
#define DGUS_CMD_R_DATA 0x83 // DGUS read data command
#define DGUS_CMD_W_CURVE 0x85 // DGUS write curve command
/* DGUS Register Addresses */
#define DGUS_REG_VERSION 0x00 // DGUS version
#define DGUS_REG_LED_NOW 0x01 // LED backlight brightness
#define DGUS_REG_BZ_TIME 0x02 // Buzzer duration
#define DGUS_REG_PIC_ID 0x03 // Display page ID
#define DGUS_REG_TP_FLAG 0x05 // Touch coordinate update flag
#define DGUS_REG_TP_STATUS 0x06 // Coordinate status
#define DGUS_REG_TP_POSITION 0x07 // Coordinate position
#define DGUS_REG_TPC_ENABLE 0x0B // Touch enable
#define DGUS_REG_RTC_NOW 0x20 // Current RTC
// Write one byte data to the specified register of DGUS screen
void DGUS_REG_WriteWord(uint8_t RegAddr, uint16_t Data){ DGUS_SendByte(DGUS_FRAME_HEAD1); DGUS_SendByte(DGUS_FRAME_HEAD2); DGUS_SendByte(0x04);
DGUS_SendByte(DGUS_CMD_W_REG); // Command DGUS_SendByte(RegAddr); // Address
DGUS_SendByte((uint8_t)(Data>>8)); // Data DGUS_SendByte((uint8_t)(Data&0xFF));}
// Write one byte data to the specified address of DGUS screen
void DGUS_DATA_WriteWord(uint16_t DataAddr, uint16_t Data){ DGUS_SendByte(DGUS_FRAME_HEAD1); DGUS_SendByte(DGUS_FRAME_HEAD2); DGUS_SendByte(0x05);
DGUS_SendByte(DGUS_CMD_W_DATA); // Command
DGUS_SendByte((uint8_t)(DataAddr>>8)); // Address DGUS_SendByte((uint8_t)(DataAddr&0xFF));
DGUS_SendByte((uint8_t)(Data>>8)); // Data DGUS_SendByte((uint8_t)(Data&0xFF));}
static uint8_t sDGUS_SendBuf[DGUS_PACKAGE_LEN];
// Write one byte data to the specified register of DGUS screen
void DGUS_REG_WriteWord(uint8_t RegAddr, uint16_t Data){ sDGUS_SendBuf[0] = DGUS_FRAME_HEAD1; // Frame head sDGUS_SendBuf[1] = DGUS_FRAME_HEAD2; sDGUS_SendBuf[2] = 0x06; // Length sDGUS_SendBuf[3] = DGUS_CMD_W_CTRL; // Command sDGUS_SendBuf[4] = RegAddr; // Address sDGUS_SendBuf[5] = (uint8_t)(Data>>8); // Data sDGUS_SendBuf[6] = (uint8_t)(Data&0xFF);
DGUS_CRC16(&sDGUS_SendBuf[3], sDGUS_SendBuf[2] - 2, &sDGUS_CRC_H, &sDGUS_CRC_L); sDGUS_SendBuf[7] = sDGUS_CRC_H; // Checksum sDGUS_SendBuf[8] = sDGUS_CRC_L;
DGUSSend_Packet_ToQueue(sDGUS_SendBuf, sDGUS_SendBuf[2] + 3);}
// Write one byte data to the specified address of DGUS screen
void DGUS_DATA_WriteWord(uint16_t DataAddr, uint16_t Data){ sDGUS_SendBuf[0] = DGUS_FRAME_HEAD1; // Frame head sDGUS_SendBuf[1] = DGUS_FRAME_HEAD2; sDGUS_SendBuf[2] = 0x07; // Length sDGUS_SendBuf[3] = DGUS_CMD_W_DATA; // Command sDGUS_SendBuf[4] = (uint8_t)(DataAddr>>8); // Address sDGUS_SendBuf[5] = (uint8_t)(DataAddr&0xFF); sDGUS_SendBuf[6] = (uint8_t)(Data>>8); // Data sDGUS_SendBuf[7] = (uint8_t)(Data&0xFF);
DGUS_CRC16(&sDGUS_SendBuf[3], sDGUS_SendBuf[2] - 2, &sDGUS_CRC_H, &sDGUS_CRC_L); sDGUS_SendBuf[8] = sDGUS_CRC_H; // Checksum sDGUS_SendBuf[9] = sDGUS_CRC_L;
DGUSSend_Packet_ToQueue(sDGUS_SendBuf, sDGUS_SendBuf[2] + 3);}
typedef struct{ uint8_t Head1; // Frame head 1 uint8_t Head2; // Frame head 2 uint8_t Len; // Length uint8_t Cmd; // Command uint8_t Data[DGUS_DATA_LEN]; // Data uint16_t CRC16; // CRC check}DGUS_PACKAGE_TypeDef;
void DGUS_ISRHandler(uint8_t Data){ static uint8_t sDgus_RxNum = 0; // Count static uint8_t sDgus_RxBuf[DGUS_PACKAGE_LEN]; static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
sDgus_RxBuf[gDGUS_RxCnt] = Data; gDGUS_RxCnt++;
/* Check Frame Head */ if(sDgus_RxBuf[0] != DGUS_FRAME_HEAD1) // Received Frame Head 1 { gDGUS_RxCnt = 0; return; } if((2 == gDGUS_RxCnt) && (sDgus_RxBuf[1] != DGUS_FRAME_HEAD2)) { gDGUS_RxCnt = 0; return; }
/* Determine One Frame Data Length */ if(gDGUS_RxCnt == 3) { sDgus_RxNum = sDgus_RxBuf[2] + 3; }
/* Received One Frame Data */ if((6 <= gDGUS_RxCnt) && (sDgus_RxNum <= gDGUS_RxCnt)) { gDGUS_RxCnt = 0;
if(xDGUSRcvQueue != NULL) // Parse successful, add to queue { xQueueSendFromISR(xDGUSRcvQueue, &sDgus_RxBuf[0], &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } }}
b. Adding Timeout Detection
Receiving data might be interrupted for some reason; thus, timeout detection is very necessary.
For example: use an extra MCU timer to handle timeout counting; when receiving data, start counting, and if no data is received for over 1ms, discard the previous data package.
static void DGUS_TimingAndUpdate(uint16_t Nms){ sDGUSTiming_Nms_Num = Nms; TIM_SetCounter(DGUS_TIM, 0); // Set counter value to 0 TIM_Cmd(DGUS_TIM, ENABLE); // Start timer}
void DGUS_COM_IRQHandler(void){ if((DGUS_COM->SR & USART_FLAG_RXNE) == USART_FLAG_RXNE) { DGUS_TimingAndUpdate(5); // Update timeout (to prevent timeout) DGUS_ISRHandler((uint8_t)USART_ReceiveData(DGUS_COM)); }}
c. More
Similar to sending, there are many implementation methods for receiving, such as using the struct method. However, all implementations need to be tailored to your specific needs.
Conclusion
———— END ————
● Column “Embedded Tools”
● Column “Embedded Development”
● Column “Keil Tutorial”
● Selected Tutorials from Embedded Column
Follow the public account and reply “Join Group” to join the technical exchange group according to the rules, reply “1024” for more content.
