目录
本博客将采用标准库和HAL库实现
所用设备选择
引脚说明
与单片机的接线表
标准库实现
HAL库实现
本博客将采用标准库和HAL库实现
所用设备选择
单片机型号:STM32F103C8T6
激光测距传感器型号:WT-VL53L0 L1
采用串口TTL电平输出,可以接USB-TTL串口到电脑,或者直接接MCU的串口,实时输出距离数据(ASCII码)。
该模块可以直接接收串口数据。
本博文任务是将数据提取出来,以便其它模块使用。
引脚说明
模块的引脚说明:
序号 | 激光测距模块 | 引脚颜色 |
1 | VCC | 红色 |
2 | RXD | 绿色 |
3 | TXD | 黄色 |
4 | SCL | - |
5 | SDA | - |
6 | GND | 黑色 |
与单片机的接线表
序号 | 激光测距模块 | 引脚颜色 | 单片机STM32 |
1 | VCC | 红色 | VCC/5V |
2 | RXD | 绿色 | PA2(USART2_TX) |
3 | TXD | 黄色 | PA3(USART2_RX) |
4 | SCL | - | |
5 | SDA | - | |
6 | GND | 黑色 | GND |
7 | - | - | PA9(USART1_TX) |
8 | - | - | PA10(USART1_RX) |
这里选用了两个串口
串口1的作用是将数据测得数据显示在电脑端(串口助手显示)
串口2采集测得的数据,并进行处理。
标准库实现
usart.c
void uart1_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启串口接受中断 串口1暂时不需要接收数据,只需要发送数据即可
USART_Cmd(USART1, ENABLE); //使能串口1
}
void uart2_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART2时钟
//USART1_TX GPIOA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
//USART1_RX GPIOA.3初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART2, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART2, ENABLE); //使能串口1
}
void USART2_IRQHandler(void) //串口2中断服务程序
{
int i = 0; // 循环变量
int n = 0; // 循环变量
int Dis = 0; // 距离
char InStr[20]=""; // 存放整数字符串
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
aRxBuffer =USART_ReceiveData(USART2);//(USART1->DR); //读取接收到的数据
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; // 接收数据
if( 'm' == RxBuffer[Uart1_Rx_Cnt-1] && 'm' == RxBuffer[Uart1_Rx_Cnt-2] )
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭串口接受中断 为了处理数据
if(NULL != strstr(RxBuffer, "Valid")) // 判断是否是有效数据
{
// for(i=0;i<strlen(RxBuffer);i++) /// 调试代码 可删除
// {
// USART_SendData(USART1, RxBuffer[i]);
// delay_ms(1);
// }
for(i = 15;i<strlen(RxBuffer);i++)
{
TxBuffer[i-15] = RxBuffer[i];
}
for(i = 0;i<strlen(TxBuffer);i++)
{
if(TxBuffer[i]<='9' && TxBuffer[i]>='0')
{
InStr[n++] = TxBuffer[i];
}
}
Dis = atoi(InStr); // 距离 一个整数 可以直接使用
///****调试 串口1 输出**开始**********
sprintf(TxBuffer,"%d\r\n",Dis);
for(i=0;i<strlen(TxBuffer);i++)
{
USART_SendData(USART1, TxBuffer[i]);
delay_ms(1);
}
///****调试 串口1 输出**结束**********
}
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
memset(TxBuffer,0x00,sizeof(TxBuffer)); //清空数组
memset(InStr,0x00,sizeof(InStr)); //清空数组
Uart1_Rx_Cnt = 0;
n = 0;
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 为了处理数据
}
}
}
实现效果:
HAL库实现
核心代码就在回调函数这个地方:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
int i = 0; // 循环变量
int n = 0; // 循环变量
int Dis = 0; // 距离
char InStr[20]=""; // 存放整数字符串
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(aRxBuffer != 0)
{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; // 接收数据
}
if( 'm' == RxBuffer[Uart1_Rx_Cnt-1] && 'm' == RxBuffer[Uart1_Rx_Cnt-2] )
{
if(NULL != strstr(RxBuffer, "Valid")) // 判断是否是有效数据
{
// HAL_UART_Transmit(&huart1, (uint8_t *)RxBuffer, strlen(RxBuffer),0xFFFF); //将收到的信息发送出去
// while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //检测UART发送结束
// HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", strlen("\r\n"),0xFFFF); //将收到的信息发送出去
// while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //检测UART发送结束
for(i = 15;i<strlen(RxBuffer);i++)
{
TxBuffer[i-15] = RxBuffer[i];
}
for(i = 0;i<strlen(TxBuffer);i++)
{
if(TxBuffer[i]<='9' && TxBuffer[i]>='0')
{
InStr[n++] = TxBuffer[i];
}
}
Dis = atoi(InStr); // 距离 一个整数 可以直接使用
sprintf(TxBuffer,"%d\r\n",Dis);
HAL_UART_Transmit(&huart1, (uint8_t *)TxBuffer, strlen(TxBuffer),0xFFFF); //将收到的信息发送出去
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
}
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
memset(TxBuffer,0x00,sizeof(TxBuffer)); //清空数组
memset(InStr,0x00,sizeof(InStr)); //清空数组
Uart1_Rx_Cnt = 0;
n = 0;
}
while(HAL_OK != HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1)); //开启接收中断,并保证开启成功
}
实现效果如下:
如有问题或需求可私信交流
源码链接(标准库与HAL库):
(1条消息) STM32F103实现激光测距传感器测距WT-VL53L0L1-C文档类资源-CSDN文库
吾芯电子工作室