STM32应用开发实践教程:智能小车供电监测模块的应用开发

3.2.1 任务分析
本任务要设计一个可对智能小车供电电池的电压进行监测的应用程
序,智能小车供电电路如图 3-2-1 所示。
图 3-2-1 中,供电电池的电压为 12.6 V,通过“PIN”端接入。电池
电压经过分压后,通过“VM_ADC”与智能小车 MCU 的 PA6 引脚相连,
作为模数转换器(Analog-to-Digital Converter,ADC)采集输入。
要求每隔 3s 对电池电压值进行采集,并将采集到的电压值通过串口
发送至上位机显示,显示格式样例为“10.78 V”,数值须精确到小数点后
两位。
本任务涉及的知识点有:
 STM32F4 系列微控制器 ADC 外设的工作原理;
 ADC 外设的编程配置步骤。

3.2.2 知识链接
1.ADC 简介
ADC 是一种可将连续变化的模拟信号转换为离散的数字信号的器件,其可将温度、压力、
声音或者图像等模拟信号转换成更易存储、处理和发射的数字信号。
STM32F407ZGT6 型号微控制器有3 个ADC,可工作在独立、双重或三重模式下,以满足多种
不同的应用需求。每个ADC 都具有 19 个复用通道,可测量16 个外部信号源、2 个内部信号源以及V BAT 通道的信号,转换精度可配置为 12bit、10bit、8bit 或 6bit,转换结果存储在一个可左对齐或右
对齐的16 位数据寄存器中。图3-2-2 展示了单个STM32F4 系列微控制器ADC 的结构框图。

2.ADC 的功能分析
接下来对图 3-2-2 中的各部分功能进行分析。
(1)ADC 的输入电压范围
ADC 的输入电压 V IN 的范围是: V REF- ≤ V IN ≤ V REF+ ,由图 3-2-3 中的 V REF+ 、 V REF- 、 V DDA 和 V SSA
这 4 个外部引脚的电压决定,这 4 个外部引脚对应的输入电压范围如表 3-2-1 所示。 

(2)ADC 的输入通道
单个ADC的输入通道多达19个,其中包括16个外部通道,如图3-2-4中所示的ADCx_IN0、
ADCx_IN1、……、ADCx_IN15。这 16 个外部通道分别连接着不同的 GPIO 端口,如表 3-2-2
所示。

 

 

 

 (3)ADC 的转换顺序
STM32F4 系列微控制器的 ADC 转换分为两个通道:规则通道和注入通道。规则通道相当于
正常运行的程序,注入通道相当于中断。正如中断可以打断正常运行的程序,注入通道的 ADC
转换可以打断规则通道的 ADC 转换,只有等注入通道的 ADC 转换完成后,规则通道的 ADC 转
换才能继续运行。
规则通道的转换顺序由规则序列寄存器 SQR3、SQR2 和 SQR1 控制,注入通道的转换顺序
由注入序列寄存器(JSQR)控制。图 3-2-5 展示了 ADC 的两个通道。
(4)ADC 的输入时钟与采样周期
STM32F4 系列微控制器的 ADC 输入时钟如图 3-2-6 所示,由该图可知,STM32F4 的 ADC
输入时钟(ADCCLK)由 PCLK2 经过 ADC 预分频器产生。根据数据手册显示,当 V DDA 范围为
2.4 V~3.6 V 时,ADCCLK 最大值为 36 MHz,典型值为 30 MHz。分频系数由 ADC 通用控制寄
存器(ADC_CCR)中的“ADCPRE[1:0]”位段设置,可设置的值有 2、4、6 和 8。当 PCLK2
为 84 MHz 时,若设置 ADC 预分频器的分频系数为 4,则 ADCCLK 的时钟频率为 21 MHz,对
应一个时钟周期的时间 Tp(1/ADCCLK)等于 0.0476 μs。

A/D 转换需要若干个时钟周期才可完成采样,具体的采样时间可通过 ADC 采样时间寄存器
ADC_SMPR1 和 ADC_SMPR2 中的“SMP[2:0]”位段进行设置,允许设置为 3 个、15 个或 28
个时钟周期等,值越小代表采样时间越短,速度越快。
一次 A/D 转换所需的总时间 T conv =采样时间+数据处理时间(12 T p),因此当 ADCCLK 设置为
21 MHz,采样时间设置为3 个时钟周期,可计算出最短的转换时间 T conv = 15 ×  T p = 0.7142 μs。
(5)ADC 的触发方式
图 3-2-7 显示了 ADC 所支持的触发方式,从图中可以看到 ADC 支持多种外部事件触发方
式,包括定时器触发和外部 GPIO 中断。具体选择哪种触发方式,可通过 ADC 控制寄存器 2
(ADC_CR2)进行配置,即对规则组和注入组分别进行配置。另外,该寄存器还可对触发极性进
行配置,如上升沿检测、下降沿检测等。
除了图 3-2-7 中显示的触发方式外,ADC 还支持软件触发,该触发由 ADC_CR2 的
“SWSTART”位进行控制,控制的前提是“ADON”位先配置为 1。一次转换结束后,硬件会自
动将“SWSTART”位置零。 

 

(6)ADC 的数据寄存器
ADC 转换完毕后,结果数据存放在相应的数据寄存器中。ADC 的数据寄存器如图 3-2-8
所示,图中展示了两种 ADC 数据寄存器:规则数据寄存
器(ADC_DR)和注入数据寄存器(ADC_JDRx)。上述两种数据寄存器用于独立转换模式的结果存放,双重和三重转换模式的结果则存放于通用 ADC_CDR 中。ADC_DR 只有一个,32bit 长,低 16 位有效,仅适用于独立模式。由于 STM32F4 系列微控制器的 ADC 最大精度是 12 位,因此存放数据时允许设置左对齐或者右对齐,即左对齐存放在 ADC_DR 的[15:4]位,右对齐存放在 ADC_DR 的[11:0]位。由于只有一个,因此当使用多通道转换时,ADC_DR 中存放的数据应及时取走,否则将会被另一个通道转换结果覆盖。常用开启 DMA 传输的方式解决该问题,无须 MCU 参与即可直接将数据转移到内存空间中存放。 

ADC_JDRx 有 4 个,正好对应注入组的 4 个通道,因此不会出现类似的“数据被覆盖”的
情况。ADC_JDRx 在使用过程中也需要设置数据位左对齐或者右对齐。
(7)ADC 的中断控制
从图 3-2-9 中可以看到,ADC 转换结束后,支持产生 4 种中断:DMA 溢出中断、规则转
换结束中断、注入转换结束中断和模拟“看门狗”事件中断。它们的事件标志和使能控制位
如表 3-2-3 所示。

 

 

规则转换和注入转换结束后,除了可通过产生中断方式处理转换结果之外,还可产生 DMA 请求
以把转换好的数据直接转存至内存中。这对于独立模式、双重模式或三重模式的多通道转换而言是
非常必要的,既可简化程序又可提高运行效率 

3.STM32F4 系列微控制器的 ADC 编程配置步骤
(1)使能 ADC 时钟,配置外部通道对应的引脚为模拟输入模式
STM32F407 系列微控制器的 3 个 ADC 外设均挂载在 APB2 上,可调用以下函数使能 ADC1
外设时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 使能 ADC1  时钟
GPIO 工作模式的配置与前述各任务相似,需要注意的是:GPIO 复用为 ADC 外设需要将工
作模式设置为“模拟输入”,不需要调用 GPIO_PinAFConfig()函数以设置引脚复用映射。配置
PA6 引脚为模拟电压输入的参考代码如下:
GPIO_InitTypeDef GPIO_InitStructure; 

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PA6 为外部通道 6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  // 模拟输入(注意)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  // 不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化

(2)配置 ADC 的通用控制寄存器
ADC 的通用控制寄存器(ADC_CCR)主要对“ADC 工作模式”“两次采样中间的间隔时间”
“是否启用 DMA 传输”“ADC 预分频器分频系数”等内容进行配置。在标准外设库中,通过调用
ADC_CommonInit()函数来实现 ADC_CCR 的初始化,示例代码如下:

ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* ADC 工作在独立模式 */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
/*  两次采样中间的间隔时间为 5 个时钟周期 */
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
/*  禁用 DMA 传输 */
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
/* ADC 预分频器分频系数为 4 */
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInit(&ADC_CommonInitStructure);

(3)初始化 ADC 的参数
ADC 的参数通过控制寄存器 ADC_CR1 和 ADC_CR2 进行配置,下面给出一段使用软件触
发、启用单转换通道、分辨率为 12bit、禁用扫描模式、数据右对齐的配置示例。

        

ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // 分辨率 12bit 模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 关闭连续转换
/*  禁止触发检测,使用软件触发 */
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1; // 启用规则序列 1 个转换通道
ADC_Init(ADC1, &ADC_InitStructure);  //ADC 初始化

(4)设置 ADC 转换通道、转换顺序和采样周期
在标准外设库中,规则序列中的 ADC 转换通道、转换顺序和采样周期的配置可通过调用
ADC_RegularChannelConfig()函数完成,该函数的原型定义如下:

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,
uint8_t Rank, uint8_t ADC_SampleTime) ;
第一个参数配置 ADCx 外设,第二个参数配置 ADC 通道号,第三个参数配置转换顺序,第
四个参数配置采样周期。下列示例可配置 ADC1 的通道号为 6,转换顺序为 1,采样时间为 56
个时钟周期。
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_56Cycles);
(5)使能 ADC 转换结束中断
如果要在 ADC 转换结束后产生中断,且在中断服务程序中读取转换结果,则应调用标准外
设库的 ADC_ITConfig()函数使能 ADC 的转换结束中断 ADC_IT_EOC。使能中断后,还应使用
NVIC 配置中断源的优先级,示例代码如下:

ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);  // 使能 ADC 的转换结束中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  // 配置优先级
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn; // 配置中断源 ADC_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

(6)使能 ADC 并设置触发方式
配置好 ADC 的各项参数之后,使能 ADC 并设置相应的触发方式,相关示例代码如下:
ADC_Cmd(ADC1, ENABLE); // 使能 ADC1
ADC_SoftwareStartConv(ADC1);  // 开始 ADC 转换,软件触发
(7)编写 ADC 转换完成中断服务程序
一旦使能 ADC 转换结束中断,当 ADC 转换结束后,MCU 会执行中断服务程序。STM32F4
系列微控制器的 ADC 中断服务程序的入口均为“ADC_IRQHandler”,因此在中断服务程序的入
口应判断发生了哪种中断,并在其出口处清除中断标志位。具体程序框架如下:

void ADC_IRQHandler(void)
{
if (ADC_GetITStatus(ADC1,ADC_IT_EOC) == SET)
{
ADC_ConvertedValue = ADC_GetConversionValue(ADC1);
}
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}


在上述示例程序中,通过 ADC_GetITStatus()函数判断是否发生了 ADC 转换结束中断,如
果是,则读取 ADC 转换结果,并清除转换结束中断标志位。
3.2.3 任务实施
接下来分别用查询方式和中断方式实现智能小车电池电压的监测。
1.用查询方式实现智能小车电池电压的监测
(1)编写 ADC 外设的初始化程序
复制一份 task3.1_Timer_Interrupt_GetTrackData 工程,并将其重命名为“task3.2_ADC_
PowerMonitor”。在“HARDWARE”文件夹下新建“ADC”子文件夹,新建“adc.c”和“adc.h”
两个文件,将它们加入工程中,并配置头文件包含路径。
在“adc.c”文件中输入以下代码:

#include "adc.h"
#include "delay.h"
/**
* @brief  ADC 转换初始化
* @param  None
* @retval None
*/
void MyADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  // 使能 ADC1 时钟
/*  初始化 ADC 输入通道 GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PA5 通道 5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  // 模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  // 不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);  //ADC1 复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);  // 复位结束
/*  配置 ADC_CCR */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式
/*  两次采样之间的间隔时间为 5 个时钟周期 */
ADC_CommonInitStructure.ADC_TwoSamplingDelay =
ADC_TwoSamplingDelay_5Cycles;
/*  不使能 DMA */
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
/*  分频系数 4 ADCCLK=PCLK2/4=84/4=21Mhz , ADC 时钟不要超过 36 MHz */
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInit(&ADC_CommonInitStructure);
/*  初始化 ADC 相关参数 */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12 位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 关闭连续转换
/*  禁止外部触发检测,使用软件触发方式 */
ADC_InitStructure.ADC_ExternalTrigConvEdge =
ADC_ExternalTrigConvEdge_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1; // 启用 1 个转换通道
ADC_Init(ADC1, &ADC_InitStructure); //ADC 配置生效
ADC_Cmd(ADC1, ENABLE); // 使能 ADC
}
/**
* @brief  单次 ADC 采样
* @param  ch:ADC 的通道编号 (ADC_Channel_0 ~ ADC_Channel_16)
* @retval  单次采样结果
*/
uint16_t Get_Adc(uint8_t ch)
{
/*  设置指定 ADC 的规则组通道,一个序列,采样时间 480 个时钟周期 */
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
ADC_SoftwareStartConv(ADC1);// 使能指定的 ADC1 的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); // 等待转换结束
return ADC_GetConversionValue(ADC1); // 返回 ADC1 规则组的转换结果
}
/**
* @brief 多次 ADC 采样取平均值
* @param ch:ADC 的通道编号 (ADC_Channel_0 ~ ADC_Channel_16)
* @param times: 采样次数
* @retval 采样结果均值
*/
uint16_t Get_Adc_Average(uint8_t ch,uint8_t times)
{
u32 temp_val=0;
uint8_t t;
for(t=0; t<times; t++)
{
temp_val += Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}

对上述代码片段的关键点解析如下。
① 采用软件方式触发:代码第 43、60 和 61 行。
② 每次触发只进行一次 ADC 转换:代码第 41 行(关闭连续转换)。
③ 查询方式实现 ADC:代码第 62 行(查询 EOC 转换结束标志位是否被置 1)。
接下来在“adc.h”文件中输入以下代码:

#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void MyADC_Init(void); //ADC 通道初始化
uint16_t Get_Adc(uint8_t ch); // 单次 ADC 转换某个通道
uint16_t Get_Adc_Average(uint8_t ch,uint8_t times); // 多次 ADC 转换取平均值
void ADC_NVIC_Config(void); // 配置 ADC 中断优先级
#endif

(2)编写 main()函数
在“main.c”文件中输入以下代码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
uint16_t adcValue = 0; // 存放 ADC 采样的原始值 (0~4096)
float adcVoltage = 0; // 存放 ADC 采样计算后的电压值
char myString[50] = {0};
int main(void)
{
delay_init(168); // 延时函数初始化
LED_Init(); //LED 端口初始化
USART1_Init(115200);  //USART1 初始化
MyADC_Init();  //ADC 初始化
while(1)
{
/*  调用多次 ADC 采样取平均值函数,采样 ADC1 的通道 5 */
adcValue = Get_Adc_Average(ADC_Channel_5, 20);
/*  采样值转换为电压值 */
adcVoltage = adcValue * 3.3 / 4096 * 11;
sprintf(myString," 采样值为: %d, 电压值为: %.2f V\r\n", \
adcValue, adcVoltage);
printf("%s",myString);
delay_ms(250);
}
}

2.用中断方式实现智能小车电池电压的监测
相比于采用查询方式实现ADC,采用中断方式实现ADC需要对程序进行以下几方面的修改。
(1)开启 ADC 连续转换功能
采用中断方式实现 ADC 将不再调用“单次 ADC 转换函数 Get_Adc()”,因此可开启 ADC 连
续转换功能。将“adc.c”文件的第 41 行代码修改为:
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 开启连续转换
(2)增加 ADC 中断初始化相关代码
在“adc.c”文件的 MyADC_Init()函数结尾增加以下代码:

extern uint16_t ADC_ConvertedValue;
/**
* @brief ADC 中断优先级配置函数
* @param None
* @return None
*/
void ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief ADC 中断服务函数
* @param None
* @return None
*/
void ADC_IRQHandler(void)
{
if (ADC_GetITStatus(ADC1,ADC_IT_EOC) == SET)
{
ADC_ConvertedValue = ADC_GetConversionValue(ADC1);
}
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}

(3)编写 main()函数
在“main.c”中输入以下代码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
uint16_t adcValue = 0; // 存放 ADC 采样的原始值 (0~4096)
float adcVoltage = 0; // 存放 ADC 采样计算后的电压值
char myString[50] = {0};
uint16_t ADC_ConvertedValue = 0;
int main(void)
{
delay_init(168); // 延时函数初始化
LED_Init(); //LED 端口初始化
USART1_Init(115200);  //USART1 初始化
MyADC_Init();  //ADC 初始化
while(1)
{
adcVoltage = ADC_ConvertedValue * 3.3 / 4096;
sprintf(myString," 采样值为: %d, 电压值为: %.2f V \r\n", \
ADC_ConvertedValue, adcVoltage);
printf("%s",myString);
delay_ms(2000);
}
}

3.观察试验现象
应用程序编译无误后,将其下载至开发板运行。打开上位机的串口调试助手,可观察到如图
3-2-10 所示的电池电压监测结果。
注:采用查询方式与采用中断方式实现 ADC 的效果相同。

 

智能小车平台需要实现的功能:上位机无线遥控可发送速度、转向、行车时间、轨迹、测距、自动蔽障等控制命令,同时可以反馈实时速度、距离、电源电压、功率等状态数据。 硬件原理 1、电机驱动: 智能小车采用12V直流电机为后轮驱动力,6V步进电机为前轮转向控制提供动力,故智能车平台需驱动12V直流电机6V步进电机。由于需要控制小车的车速以及小车行驶的方向(包括转向以及前进、后退、停车),直流电机驱动采用常用的H桥电路,通过控制信号选通对管与否实现电机的正反转,并改变所加电压的占空比来改变电机转速。这里采用电机驱动专用芯片L298N,该芯片可驱动两路5-36V的直流电机或者一路四拍的步进电机。同时在L298N与主控芯片间通过四路光耦TLP521-4隔离消除干扰信号。 搭建好电路后不要直接在小车上调试,外界一只相同电压的电机测试模块。在STC12C5A60S2上配置好串口、PWM,实现串口接收的数据直接赋值给PWM定时器CCAP1L、CCAP1H。利用串口调试助手发送控制信息给STC12C5A60S2,同时辅助外界电源更改L298N的IN1IN2,共同完成L298N电机驱动模块的调试。 2、光电对管测速 光电对管采用TCRT5000,由一只特殊的发光二极管光电三极管构成,当二极管发出的光打在光电三极管的基极B上时三极管CE导通。而正常情况下二极管的光不能到达光电管的基极上,故通过在车轮上贴反射片即可实现对小车的测速。假设车轮均匀贴有n片反射片,测得光电三极管的输出脉冲频率为f,则车速=f/n。为了提高测速的精度,在信号后级添加比较器调理信号为标准的方波,调节比较器运放的偏置电压使方波信号最适合于测速。 同样适用外界电机(已配有自制的编码盘),给电机加电让其带动编码盘旋转,将光电对管靠近编码盘,用示波器观测输出脉冲信号的有无与好坏,调节比较器偏置电压使脉冲最接近于方波且幅度大于3.3V。 3、超声测距 超声波测距的方法有多种:如往返时间检测法、相位检测法、声波幅值检测法。本设计采用往返时间检测法测距。其原理是超声波传感器发射一定频率的超声波,借助空气媒质传播,到达测量目标或障碍物后反射回来,经反射后由超声波接收器接收脉冲,其所经历的时间即往返时间,往返时间与超声波传播的路程的远近有关。测试传输时间可以得出距离。假定s为被测物体到测距仪之间的距离,测得的时间为T,超声波传播速度为V表示,则有关系式S=VT/2 。 超声波发射部分是为了让超声波发射换能器TCT40-16T能向外界发出40 kHz左右的方波脉冲信号。编程由单片机端口输出40 kHz左右的方波脉冲信号,由于单片机端口输出功率不够,40 kHz方波脉冲信号分成两路,送给一个由74HC04组成的推挽式电路进行功率放大以便使发射距离足够远,满足测量距离要求,最后送给超声波发射换能器TCT40-16T以声波形式发射到空气中。发射部分的电路,如图4所示。图中输出端上拉电阻R31,R32,一方面可以提高反向器74HC04输出高电平的驱动能力,另一方面可以增加超声换能器的阻尼效果,缩短其自由振荡的时间。 上述TCT40-16T发射的在空气中传播,遇到障碍物就会返回,超声波接收部分是为了将反射波(回波)顺利接收到超声波接收换能器TCT40-16R进行转换变成电信号,并对此电信号进行放大、滤波、整形等处理后,这里用索尼公司生产的集成芯片CX20106,得到一个负脉冲送给单片机的INT0引脚,以产生一个中断。 接在CX20106的第五脚上的电阻,用以设置带通滤波器的中心频率f0,阻值越大,中心频率越低。电路中采用一只粗调的可变电阻一只精密调节的电阻串联而成。调节函数信号发生器产生40K的方波,接在超声发射电路的输入端,同时用示波器观测超声接收电路的输出端。用书本等模拟障碍物,调节两只电阻观测示波器看接收端否会产生电平跳变。 4、电源模块 对于小车而言电源是整个系统的咽喉,考虑到体积、重量、电能容量等。这里我们选取8节1.5V锂电池串联起来作为总电源输出(12V),采用LM78L05、LM317构成整个电源模块。 5、无线通信模块 无线通信采用现成的串行接口的蓝牙模块,只需要配置主从机、信道、通信密钥、波特率即可实现无线串行通信。这样PC主控STC12C5A60S2只需将通信理解为串行通信,给程序构架带来便利。不过需要考虑通信接口的问题:STC12C5A60S2是5V电压供电,TXDRXD的通信电信号自然是以5V为参考电平;蓝牙模块是3.3V电压供电,TXDRXD的通信电信号自然是以3.3V为参考电平。所以我们需要添加电平转换,实现STC12C5A60S2与蓝牙模块的正常通信。一般电平转换可以使用专用的芯片74xHCT或164245,电阻分压法、OC/OD 器件法、晶体管上拉电阻法等。不过对
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lee达森

创作不易,感谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值