• STM32F103实现激光测距传感器测距WT-VL53L0 L1


    目录

    本博客将采用标准库和HAL库实现

    所用设备选择

    引脚说明

    与单片机的接线表

    标准库实现

     HAL库实现


    本博客将采用标准库HAL库实现

    所用设备选择

    单片机型号:STM32F103C8T6

     激光测距传感器型号:WT-VL53L0 L1

     

    采用串口TTL电平输出,可以接USB-TTL串口到电脑,或者直接接MCU的串口,实时输出距离数据(ASCII码)。

    该模块可以直接接收串口数据

    本博文任务是将数据提取出来,以便其它模块使用。

    引脚说明

    模块的引脚说明:

    序号激光测距模块引脚颜色
    1VCC红色
    2RXD绿色
    3TXD黄色
    4SCL-
    5SDA-
    6GND黑色

    与单片机的接线表

    序号激光测距模块引脚颜色单片机STM32
    1VCC红色VCC/5V
    2RXD绿色PA2(USART2_TX)
    3TXD黄色PA3(USART2_RX)
    4SCL-
    5SDA-
    6GND黑色GND
    7--PA9(USART1_TX)
    8--PA10(USART1_RX)

    这里选用了两个串口

    串口1的作用是将数据测得数据显示在电脑端(串口助手显示)

    串口2采集测得的数据,并进行处理。

    标准库实现

     usart.c

    1. void uart1_init(u32 bound){
    2. //GPIO端口设置
    3. GPIO_InitTypeDef GPIO_InitStructure;
    4. USART_InitTypeDef USART_InitStructure;
    5. NVIC_InitTypeDef NVIC_InitStructure;
    6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
    7. //USART1_TX GPIOA.9
    8. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    9. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    11. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
    12. //USART1_RX GPIOA.10初始化
    13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    15. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
    16. //Usart1 NVIC 配置
    17. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    18. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    19. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
    20. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    21. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
    22. //USART 初始化设置
    23. USART_InitStructure.USART_BaudRate = bound;//串口波特率
    24. USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    25. USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    26. USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    27. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    28. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
    29. USART_Init(USART1, &USART_InitStructure); //初始化串口1
    30. USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启串口接受中断 串口1暂时不需要接收数据,只需要发送数据即可
    31. USART_Cmd(USART1, ENABLE); //使能串口1
    32. }
    33. void uart2_init(u32 bound){
    34. //GPIO端口设置
    35. GPIO_InitTypeDef GPIO_InitStructure;
    36. USART_InitTypeDef USART_InitStructure;
    37. NVIC_InitTypeDef NVIC_InitStructure;
    38. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
    39. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART2时钟
    40. //USART1_TX GPIOA.2
    41. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
    42. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    43. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    44. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
    45. //USART1_RX GPIOA.3初始化
    46. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    47. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    48. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
    49. //Usart1 NVIC 配置
    50. NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    51. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    52. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
    53. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    54. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
    55. //USART 初始化设置
    56. USART_InitStructure.USART_BaudRate = bound;//串口波特率
    57. USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    58. USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    59. USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    60. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    61. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
    62. USART_Init(USART2, &USART_InitStructure); //初始化串口1
    63. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
    64. USART_Cmd(USART2, ENABLE); //使能串口1
    65. }
    66. void USART2_IRQHandler(void) //串口2中断服务程序
    67. {
    68. int i = 0; // 循环变量
    69. int n = 0; // 循环变量
    70. int Dis = 0; // 距离
    71. char InStr[20]=""; // 存放整数字符串
    72. if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    73. {
    74. USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
    75. aRxBuffer =USART_ReceiveData(USART2);//(USART1->DR); //读取接收到的数据
    76. RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; // 接收数据
    77. if( 'm' == RxBuffer[Uart1_Rx_Cnt-1] && 'm' == RxBuffer[Uart1_Rx_Cnt-2] )
    78. {
    79. USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭串口接受中断 为了处理数据
    80. if(NULL != strstr(RxBuffer, "Valid")) // 判断是否是有效数据
    81. {
    82. // for(i=0;i<strlen(RxBuffer);i++) /// 调试代码 可删除
    83. // {
    84. // USART_SendData(USART1, RxBuffer[i]);
    85. // delay_ms(1);
    86. // }
    87. for(i = 15;i<strlen(RxBuffer);i++)
    88. {
    89. TxBuffer[i-15] = RxBuffer[i];
    90. }
    91. for(i = 0;i<strlen(TxBuffer);i++)
    92. {
    93. if(TxBuffer[i]<='9' && TxBuffer[i]>='0')
    94. {
    95. InStr[n++] = TxBuffer[i];
    96. }
    97. }
    98. Dis = atoi(InStr); // 距离 一个整数 可以直接使用
    99. ///****调试 串口1 输出**开始**********
    100. sprintf(TxBuffer,"%d\r\n",Dis);
    101. for(i=0;i<strlen(TxBuffer);i++)
    102. {
    103. USART_SendData(USART1, TxBuffer[i]);
    104. delay_ms(1);
    105. }
    106. ///****调试 串口1 输出**结束**********
    107. }
    108. memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
    109. memset(TxBuffer,0x00,sizeof(TxBuffer)); //清空数组
    110. memset(InStr,0x00,sizeof(InStr)); //清空数组
    111. Uart1_Rx_Cnt = 0;
    112. n = 0;
    113. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 为了处理数据
    114. }
    115. }
    116. }

    实现效果:

     HAL库实现

     核心代码就在回调函数这个地方:

    1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    2. {
    3. int i = 0; // 循环变量
    4. int n = 0; // 循环变量
    5. int Dis = 0; // 距离
    6. char InStr[20]=""; // 存放整数字符串
    7. /* Prevent unused argument(s) compilation warning */
    8. UNUSED(huart);
    9. /* NOTE: This function Should not be modified, when the callback is needed,
    10. the HAL_UART_TxCpltCallback could be implemented in the user file
    11. */
    12. if(aRxBuffer != 0)
    13. {
    14. RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; // 接收数据
    15. }
    16. if( 'm' == RxBuffer[Uart1_Rx_Cnt-1] && 'm' == RxBuffer[Uart1_Rx_Cnt-2] )
    17. {
    18. if(NULL != strstr(RxBuffer, "Valid")) // 判断是否是有效数据
    19. {
    20. // HAL_UART_Transmit(&huart1, (uint8_t *)RxBuffer, strlen(RxBuffer),0xFFFF); //将收到的信息发送出去
    21. // while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //检测UART发送结束
    22. // HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", strlen("\r\n"),0xFFFF); //将收到的信息发送出去
    23. // while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //检测UART发送结束
    24. for(i = 15;i<strlen(RxBuffer);i++)
    25. {
    26. TxBuffer[i-15] = RxBuffer[i];
    27. }
    28. for(i = 0;i<strlen(TxBuffer);i++)
    29. {
    30. if(TxBuffer[i]<='9' && TxBuffer[i]>='0')
    31. {
    32. InStr[n++] = TxBuffer[i];
    33. }
    34. }
    35. Dis = atoi(InStr); // 距离 一个整数 可以直接使用
    36. sprintf(TxBuffer,"%d\r\n",Dis);
    37. HAL_UART_Transmit(&huart1, (uint8_t *)TxBuffer, strlen(TxBuffer),0xFFFF); //将收到的信息发送出去
    38. while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
    39. }
    40. memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
    41. memset(TxBuffer,0x00,sizeof(TxBuffer)); //清空数组
    42. memset(InStr,0x00,sizeof(InStr)); //清空数组
    43. Uart1_Rx_Cnt = 0;
    44. n = 0;
    45. }
    46. while(HAL_OK != HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1)); //开启接收中断,并保证开启成功
    47. }

    实现效果如下:

    如有问题或需求可私信交流

    源码链接(标准库与HAL库):

    (1条消息) STM32F103实现激光测距传感器测距WT-VL53L0L1-C文档类资源-CSDN文库
    吾芯电子工作室

  • 相关阅读:
    FPGA与ASIC有什么差异?二者该如何选用?
    解决nginx反向代理web service的soap:address location问题
    目标文件格式
    基于Docker的JMeter分布式压测实战讲解
    【前端】 Vscode 搭建基础开发环境
    计算机毕业设计(附源码)python在线宠物救助平台
    「优选算法刷题」:删除字符串中的所有相邻重复项
    java File、io篇
    监控易:IT基础资源监控的解决方案和价值
    “蔚来杯“2022牛客暑期多校训练营(加赛) G题: Good red-string
  • 原文地址:https://blog.csdn.net/XiaoCaiDaYong/article/details/127575373