#include "stm32f10x.h"
#include <stdio.h>
// -------------------------- 宏定义 --------------------------
#define USART_REC_LEN 200
#define VL53L0X_ADDR 0x52
// -------------------------- 全局变量 --------------------------
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA;
u32 SystemCoreClock = 72000000; // 系统时钟72MHz
// -------------------------- 延时函数(SysTick) --------------------------
static u8 fac_us=0;
static u16 fac_ms=0;
void Delay_Init(void) {
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us = SystemCoreClock / 8000000;
fac_ms = (u16)fac_us * 1000;
}
void delay_us(u32 nus) {
u32 temp;
SysTick->LOAD = nus * fac_us;
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
do { temp = SysTick->CTRL; } while((temp&0x01) && !(temp&(1<<16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0X00;
}
void delay_ms(u16 nms) {
u32 temp;
SysTick->LOAD = (u32)nms * fac_ms;
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
do { temp = SysTick->CTRL; } while((temp&0x01) && !(temp&(1<<16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0X00;
}
// -------------------------- 硬件I2C初始化(I2C1) --------------------------
void I2C1_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// PB6=SCL, PB7=SDA(硬件I2C1引脚)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏复用
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000; // 400kHz
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
// -------------------------- 硬件I2C写字节 --------------------------
void I2C_WriteByte(u8 addr, u8 reg, u8 data) {
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, reg);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
// -------------------------- 硬件I2C读字节 --------------------------
u8 I2C_ReadByte(u8 addr, u8 reg) {
u8 data;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, reg);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
data = I2C_ReceiveData(I2C1);
return data;
}
// -------------------------- VL53L0X初始化 --------------------------
u8 VL53L0X_Init(void) {
I2C_WriteByte(VL53L0X_ADDR, 0x80, 0x01); // 软复位
delay_ms(10);
I2C_WriteByte(VL53L0X_ADDR, 0x80, 0x00);
delay_ms(10);
u8 id = I2C_ReadByte(VL53L0X_ADDR, 0xC0);
if(id != 0xEE) return 1; // ID验证失败
I2C_WriteByte(VL53L0X_ADDR, 0x00, 0x01); // 启动连续测量
return 0;
}
// -------------------------- VL53L0X读距离 --------------------------
u16 VL53L0X_ReadDistance(void) {
delay_ms(20);
u16 dist = I2C_ReadByte(VL53L0X_ADDR, 0x14) << 8;
dist |= I2C_ReadByte(VL53L0X_ADDR, 0x15);
return dist;
}
// -------------------------- USART1初始化(printf重定向) --------------------------
void USART1_Init(u32 bound) {
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// PA9=TX, PA10=RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
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);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
// -------------------------- printf重定向到USART1 --------------------------
int fputc(int ch, FILE *f) {
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1, (u8)ch);
return ch;
}
// -------------------------- USART1中断服务函数 --------------------------
void USART1_IRQHandler(void) {
u8 res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
res = USART_ReceiveData(USART1);
if((USART_RX_STA&0x8000)==0) {
if(USART_RX_STA&0x4000) {
if(res!=0x0a) USART_RX_STA=0;
else USART_RX_STA|=0x8000;
} else {
if(res==0x0d) USART_RX_STA|=0x4000;
else {
USART_RX_BUF[USART_RX_STA&0X3FFF] = res;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1)) USART_RX_STA=0;
}
}
}
}
}
// -------------------------- 系统时钟初始化(72MHz) --------------------------
void Stm32_Clock_Init(void) {
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
}
// -------------------------- main函数 --------------------------
int main(void) {
Stm32_Clock_Init(); // 初始化系统时钟72MHz
Delay_Init(); // 初始化延时
USART1_Init(115200); // 初始化串口(波特率115200)
I2C1_Init(); // 初始化硬件I2C1
printf("VL53L0X仿真测试开始...\r\n");
if(VL53L0X_Init()) {
printf("VL53L0X初始化失败!\r\n");
while(1);
}
printf("VL53L0X初始化成功!\r\n");
while(1) {
u16 dist = VL53L0X_ReadDistance();
printf("测量距离:%d mm\r\n", dist);
delay_ms(500);
}
}Loading
stm32-bluepill
stm32-bluepill