马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
串口汲取,环形缓冲区+剖析
环形缓冲区存储布局体
- #define RX_RING_SIZE 256
- typedef struct {
- uint8_t buf[RX_RING_SIZE]; // 实际存数据
- volatile uint16_t head; // 写指针(中断在改),(volatile)防止编译器优化导致 中断/主循环不同步
- volatile uint16_t tail; // 读指针(主循环在改)
- } ring_buf_t;
复制代码 初始化串口
- void USART3_IRQHandler(void);//提前声明串口接收中断
- void uart3_Init(u32 baud)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStruct;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
-
- 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_InitStructure.USART_BaudRate = baud;
- 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_InitStruct.NVIC_IRQChannel = USART3_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
- NVIC_Init(&NVIC_InitStruct);//配置NVIC
-
- USART_Cmd(USART3, ENABLE);
-
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
- USART_ITConfig(USART3, USART_IT_ERR, ENABLE);
-
- BSP_IntVectSet(BSP_INT_ID_USART3,USART3_IRQHandler);
- BSP_IntEn(BSP_INT_ID_USART3);
-
- }
复制代码 设置布局体
- ring_buf_t rx_ring3 = {0, 0, 0};
复制代码 串口汲取制止(底子)
- void USART3_IRQHandler(void)
- {
- if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
- uint8_t ch = (uint8_t)USART_ReceiveData(USART3);
- uint16_t next = (rx_ring3.head + 1) % RX_RING_SIZE;
- // 如果缓冲区没满,存入 数据
- if (next != rx_ring3.tail) {
- rx_ring3.buf[rx_ring3.head] = ch;
- rx_ring3.head = next;
- }
- USART_ClearITPendingBit(USART3, USART_IT_RXNE);
- }
- }
复制代码 剖析函数(放循环,壅闭期待)
- void Extract_select_Data(void)//判断数据包
- {
- static uint8_t state_r4 = 0;
- static uint8_t data_len_r4 = 0;
- static uint8_t count_r4 = 0;
- static uint8_t frame_buf[32];
- // 只要缓冲区里有数据,就一直处理
- while (rx_ring3.head != rx_ring3.tail)
- {
- // 1. 从环形缓冲区读取一个字节
- uint8_t ch = rx_ring3.buf[rx_ring3.tail];
- rx_ring3.tail = (rx_ring3.tail + 1) % RX_RING_SIZE;
- switch (state_r4)
- {
- case 0: // 等待帧头
- if (ch == 0x2A)
- {
- frame_buf[0] = ch;
- count_r4 = 1;
- state_r4 = 1;
- }
- break;
- case 1: // 校验 CMD
- if (ch == 0x11)
- {
- frame_buf[count_r4++] = ch;
- state_r4 = 2;
- }
- else
- {
- state_r4 = 0; // CMD 不匹配,丢弃
- }
- break;
- case 2: // 校验 LEN
- if (ch == 0x04)
- {
- data_len_r4 = ch;
- frame_buf[count_r4++] = ch;
- state_r4 = 3;
- }
- else
- {
- state_r4 = 0; // LEN 不匹配,丢弃
- }
- break;
- case 3: // 接收 DATA(4字节) + CRC
- frame_buf[count_r4++] = ch;
- // 1(2E) + 1(CMD) + 1(LEN) + 4(DATA) + 1(CRC) = 8
- if (count_r4 >= 8)
- {
- /* ========= 业务判断 ========= */
- uint8_t byte6 = frame_buf[5]; // DATA2
- if (byte6 & 0x04) // bit2 = 1
- {
- select_bit2_flag = 1;//解析结果
- BLE_TO_MCU_OK_FLAG=1;
- }
- else
- {
- BLE_TO_MCU_OK_FLAG=0;
- select_bit2_flag = 0;
- }
- /* ============================ */
- state_r4 = 0; // 准备下一帧
- }
- break;
- default:
- state_r4 = 0;
- break;
- }
- }
- }
复制代码 打扫缓存区
- void RingBuf3_ClearAndResetParser(void)
- {
- // __disable_irq(); // 关中断,保证原子性
- // 1. 清空环形缓冲区数据
- memset(rx_ring3.buf, 0, RX_RING_SIZE);
- // 2. 重置 head/tail
- rx_ring3.head = 0;
- rx_ring3.tail = 0;
- // 3. 重置解析器状态
- state_r3 = 0;
- count_r3 = 0;
- data_len_r3 = 0;
- pkg_ready = 0;
- // __enable_irq(); // 重新使能中断
- }
复制代码 |