keil5rs485接受u16数据
时间: 2023-07-29 12:07:02 浏览: 200
以下是在 Keil μVision5 中使用 RS485 接收 16 位数据的示例代码:
```c
#include <stdio.h>
#include <stdint.h>
#define BUFSIZE 64
volatile uint16_t data_received = 0;
volatile uint8_t rx_buffer[BUFSIZE];
volatile uint8_t rx_wr_index = 0;
volatile uint8_t rx_rd_index = 0;
volatile uint8_t rx_counter = 0;
void USART_IRQHandler(void) {
uint16_t rx_data;
if ((USART1->SR & USART_SR_RXNE) != 0) { // Received data is ready to be read
USART1->SR &= ~USART_SR_RXNE; // Clear the RXNE flag
rx_data = (uint16_t)(USART1->DR & 0x01FF);
if (rx_counter < BUFSIZE) { // Check if buffer is not full
rx_buffer[rx_wr_index++] = (uint8_t)rx_data; // Store the received data in buffer
rx_wr_index %= BUFSIZE;
++rx_counter;
}
}
}
void receive_data(void) {
while (rx_counter > 1) { // Check if buffer has at least 2 bytes of data
if (rx_buffer[rx_rd_index] == 0xAA && rx_buffer[(rx_rd_index + 1) % BUFSIZE] == 0xBB) {
// Start of data frame
data_received = ((uint16_t)rx_buffer[(rx_rd_index + 2) % BUFSIZE] << 8) | rx_buffer[(rx_rd_index + 3) % BUFSIZE];
rx_rd_index += 4;
rx_rd_index %= BUFSIZE;
rx_counter -= 4;
} else {
// Not start of data frame, discard the first byte and shift buffer by 1 byte
rx_rd_index += 1;
rx_rd_index %= BUFSIZE;
--rx_counter;
}
}
}
int main(void) {
USART_InitTypeDef USART_InitStructure;
// Enable USART1 clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// Configure USART1 pins
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); // PA10 = USART1_RX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); // PA9 = USART1_TX
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure USART1
USART_InitStructure.USART_BaudRate = 9600;
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(USART1, &USART_InitStructure);
// Enable USART1 interrupt
NVIC_EnableIRQ(USART1_IRQn);
// Enable USART1
USART_Cmd(USART1, ENABLE);
while (1) {
receive_data();
if (data_received != 0) {
// Do something with received data
printf("Received data: %u\n", data_received);
data_received = 0;
}
}
}
```
在上面的代码中,我们使用了 USART1 来接收 RS485 数据,接收到的数据存储在一个缓冲区中,直到缓冲区中有至少 2 字节的数据时,我们才开始检查是否接收到了一个完整的数据帧。在本例中,我们假设帧起始标志为 0xAA 和 0xBB,数据帧中紧随起始标志后的 2 个字节为 16 位数据。如果检测到起始标志,我们从缓冲区中读取 2 个字节作为数据,并清除已读取的数据。如果没有检测到起始标志,则将缓冲区中的第一个字节丢弃,并将缓冲区中的数据向左移动一个字节。最后,我们可以在主循环中处理接收到的数据。
阅读全文