[单片机芯片] 【CH32F207VCT6】开发例程+13使用队列的方式读取噪音传感器数据

[复制链接]
109|0
聪聪哥哥 发表于 2025-10-27 19:29 | 显示全部楼层 |阅读模式
一:队列的基础知识分享:
队列是一种先进先出(FIFO)的线性数据结构,只允许在队尾插入元素,在队头删除元素。对于队列的操作包括:入队,出队,查看队头元素,判断队列是否为空的操作。
   基本特性:先进先出的原则,最先进入队列的元素,最先被移除队列。
   主要操作:
   入队(enqueue):在队列的尾端添加元素。
 出队(dequeue):在队列的首端移除元素。
 队列的实现方式如下所示:
1:数组实现:
使用固定大小的数组
需要处理循环队列的情况以避免空间浪费
2:链表实现:
使用单向链表,头指针指向队首,尾指针指向队尾
不需要预先分配固定大小
二:队列相关代码分享:
2.1 队列的初始化:
  1. /**************************************************************************
  2. - 功能描述:队列初始化
  3. - 参数说明:*s 队列句柄                *buf 队列结构体数据地址
  4. - 返回说明:-1 失败                0 成功
  5. **************************************************************************/
  6. int  Initquene(squene *s, QelemType *buf)
  7. {
  8.         s->base=buf;
  9.         if(!s->base)
  10.                 return -1;
  11.         s->front=0;
  12.         s->rear=0;
  13.         return 0;
  14. }
2.2 入队列操作
  1. /**************************************************************************
  2. - 功能描述:入队列
  3. - 参数说明:*s 队列句柄                *e 要入队列数据的地址
  4. - 返回说明:无
  5. **************************************************************************/
  6. void enquene(squene *s,QelemType *e)
  7. {
  8.         if(((s->rear)+1)%MAXSIZE==s->front)
  9.         {
  10.                 return ;
  11.         }
  12.         memcpy(&(s->base[s->rear]), e, sizeof(QelemType));
  13.         s->rear=((s->rear)+1)%MAXSIZE;
  14. }
2.3 出队列操作:
  1. /**************************************************************************
  2. - 功能描述:出队列
  3. - 参数说明:*s 队列句柄                *e 出队列数据要写入的地址
  4. - 返回说明:-1 失败                0 成功
  5. **************************************************************************/
  6. int dequene(squene *s,QelemType *e)
  7. {
  8.         if(s->rear==s->front)
  9.         {
  10.                 return -1;
  11.         }
  12.         memcpy(e, &(s->base[s->front]), sizeof(QelemType));
  13.         memset(&(s->base[s->front]), 0, sizeof(QelemType));
  14.         s->front=((s->front)+1) % MAXSIZE;
  15.         return 0;
  16. }
2.4 初始化所用的队列
  1. /**************************************************************************
  2. - 功能描述:初始化所有应用的队列
  3. - 参数说明:void
  4. - 返回说明:void
  5. **************************************************************************/
  6. void Queue_Init(void)
  7. {
  8.         Initquene(&QUsart4Tx, QUsart4TxData);
  9. }
三:噪音传感器如下所示:
AS11-x是采用原装进口声音传感器开发的直读式噪音分贝检测模块
多点标定工艺制作、检测精度高、灵敏度高独特的不绣钢探头
独立封装设计、方便嵌入其它的设备或机壳!
主控板电路核心器件完全屏蔽、不仅美观更加强抗干扰能力
预留多种输出 TTL/I2C、标准 Modbus Rtu 通讯 485 接口可选,适用于各种应用集成。
1027-1.png
modbus 协议如下所示:
1027-2.png
四:CH32代码如下所示:
4.1 串口3的初始化:
  1. void USART3_Init(int baud)
  2. {
  3.     GPIO_InitTypeDef  GPIO_InitStructure = {0};
  4.     USART_InitTypeDef USART_InitStructure = {0};
  5.     NVIC_InitTypeDef  NVIC_InitStructure  = {0};

  6.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3 , ENABLE );
  7.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );

  8.     /* USART3 TX-->B.10   RX-->B.11 */
  9.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  12.     GPIO_Init( GPIOB, &GPIO_InitStructure );
  13.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  14.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  15.     GPIO_Init( GPIOB, &GPIO_InitStructure );

  16.     USART_InitStructure.USART_BaudRate = 9600;
  17.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  18.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  19.     USART_InitStructure.USART_Parity = USART_Parity_No;
  20.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  21.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

  22.   /* Enable USART3 Receive and Transmit interrupts */
  23.     USART_DMACmd(USART3, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);  //使能USART2的收发DMA
  24.     USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);

  25.                 USART_ITConfig(USART3, USART_IT_TC, ENABLE);//开启发送完成中断

  26.     USART_Init( USART3, &USART_InitStructure );
  27.     DMA_USART3_TX_Configuration(2);//发送2个空字节
  28.     DMA_USART3_RX_Configuration();

  29.     DMA_Cmd( DMA1_Channel2, ENABLE );                                  /* USART3 Tx */
  30.     DMA_Cmd( DMA1_Channel3, ENABLE );                                  /* USART3 Rx */

  31.     NVIC_InitStructure.NVIC_IRQChannel                   = USART3_IRQn;
  32.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  33.     NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;
  34.     NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  35.     NVIC_Init(&NVIC_InitStructure);

  36.     USART_Cmd( USART3, ENABLE );
  37. }
4.2 串口3的发送函数:
  1. /*******************************************************************************
  2. * Function Name  : bool SendDataToUSART2(char length)
  3. * Description    : Enable Transimt Interrupt and sart Send                          
  4. * Input          : Send data Buf Length
  5. * Output         : None
  6. * Return         : NOne        
  7. *******************************************************************************/
  8. bool SendDataToUSART3(char length)
  9. {
  10. //等待DMA发送完毕后,即可以启动发送
  11.   /* Wait until DMA1_Channel 7 Transfer Complete */
  12.   volatile u16 uDataCounter;

  13.   uDataCounter = DMA_GetCurrDataCounter(DMA1_Channel2);
  14.   while (uDataCounter > 0)
  15.   {
  16.      uDataCounter = DMA_GetCurrDataCounter(DMA1_Channel2);
  17.   }
  18.   DMA_USART3_TX_Configuration(length);
  19.   DMA_Cmd(DMA1_Channel2, ENABLE);        //开启DMA发送
  20.   return TRUE;
  21. }
4.3 读取噪音传感器的指令如下所示:
  1. /***********************************************************************
  2. 函数名:Read_Register_Modbus()
  3. 函数功能:读取寄存器
  4. 参数: modbus_addr  //从机地址
  5.        addr         //起始寄存器地址
  6.        ucount       //寄存器数量
  7. *****************************************************************/
  8. void Read_Register_Modbus(unsigned char modbus_addr,unsigned int addr,unsigned int ucount)
  9. {
  10.         uint16_t CRCData;
  11.         QelemType Data = {0};       
  12.         Data.uLength =8;       
  13.         Data.buffer[0] = modbus_addr;
  14.         Data.buffer[1] = 0x03;
  15.         Data.buffer[2] = addr   >>8;
  16.         Data.buffer[3] = addr;
  17.         Data.buffer[4] = ucount >>8;
  18.         Data.buffer[5] = ucount;        //SUM
  19.         CRCData = mb_crc16(&Data.buffer[0],6);
  20.         Data.buffer[6] = CRCData >>8;
  21.         Data.buffer[7] = CRCData;        //SUM
  22.         enquene(&QUsart4Tx,&Data);
  23. }
4.4 直接在串口的空闲中断将RS485收到的数据进行解析
  1. void UART3_Rec_Deal(void)
  2. {
  3.         if(usart3_Flag == 1)
  4.         {
  5.                 usart3_Flag = 0 ;
  6.                 if((Usart3_DEAL_RX_Buf[0] == 0x01)&&(Usart3_DEAL_RX_Buf[1] == 0x03))
  7.                 {
  8.                         EnvirMentPara.uiNoise        =  ( Usart3_DEAL_RX_Buf[3] << 8 ) +Usart3_DEAL_RX_Buf[4] ;
  9.                 }
  10.                 memset(Usart3_DEAL_RX_Buf,0,reclength3);
  11.         }
  12. }
五:实物测试如下所示:



您需要登录后才可以回帖 登录 | 注册

本版积分规则

109

主题

313

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部