我们继续学习
下面是蓝牙部分,直接上原理图
接着是代码部分,大家应该都会没啥说的
/****************************** BT04.c ********************************************/
#include "stm32f10x.h" // Device header
void BT04_Init(void)
{
//GPIO端口设置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
//USART1_TX GPIOA_2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX GPIOA_3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
//Usart2 NVIC 配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART2 初始化设置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;//串口波特率
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); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
}
u8 Res;
void USART2_IRQHandler(void) //串口2中断服务程序
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res = USART_ReceiveData(USART2); //读取接收到的数据
// USART_SendData(USART2, Res);
}
}
/****** 蓝牙遥控 *******/
u8 car;
void BT04_Control(void)
{
car = 0;
if(Res == 'E') car = 0;
if(Res == 'A') car = 1;
if(Res == 'B') car = 2;
if(Res == 'C') car = 3;
if(Res == 'D') car = 4;
}
/****************************** BT04.h ********************************************/
#ifndef __BT04_H
#define __BT04_H
void BT04_Init(void);
void USART2_IRQHandler(void);
void BT04_Control(void);
#endif
=======================================================================
接下来是AD数模转换获取电压值,你们应该比较感兴趣,还是比较准确的
原理图
VBAT_IN是 7 - 12V 输入电压注意一下
下面上代码
/****************************** AD.c ********************************************/
#include "stm32f10x.h" // Device header
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //分频 72MHZ / 6 = 12MHz
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //AIN模式是ADC专属模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_55Cycles5);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //内部软件触发
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //开始复位校准
while(ADC_GetResetCalibrationStatus(ADC1) == SET); //获取复位校准状态
ADC_StartCalibration(ADC1); //启动校准
while(ADC_GetCalibrationStatus(ADC1) == SET); //等待校准完成
}
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET); //等待转换完成
return ADC_GetConversionValue(ADC1); //ADC获取转换值
}
注意这一句:
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_55Cycles5);
我用的 PA_4 所以才是 ADC_Channel_4
/****************************** AD.h ********************************************/
#ifndef __AD_H
#define __AD_H
void AD_Init(void);
uint16_t AD_GetValue(void);
#endif
最后加上照片
还是比较可以的
接下来是超声波
原理图
下面是代码
/****************************** SR04. c ********************************************/
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "sys.h"
void SR04_GPIO_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Trig
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//Echo
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void SR04_TIM2_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 5000 - 1;
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2, DISABLE);
}
int Distance_SR04(void)
{
uint16_t count = 0;
uint16_t Distance = 0;
PAout(0)=0;//预先拉低Trig引脚
PAout(0)=1;
Delay_us(13);
PAout(0)=0;//发出13us的脉冲
TIM2->CNT = 0;
while(PAin(1) == 0)
{
if(TIM2->CNT >= 100)
break;
}
TIM_Cmd(TIM2, ENABLE);
while(PAin(1) == 1)
{
if(TIM2->CNT >= 1500)
break;
}
TIM_Cmd(TIM2, DISABLE);
count = TIM2->CNT;//us
//单位cm
//v = 340m/s = 34000cm/s = 34000cm/10^6us = 0.034cm/us
//s = vt/2 = t*0.034/2 = t*0.017 ≈ t/58
Distance = (int)count/58;
return Distance;
}
/****************************** SR04. h ********************************************/
#ifndef __SR04_H
#define __SR04_H
void SR04_GPIO_Init(void);
void SR04_TIM2_Init(void);
int Distance_SR04(void);
#endif
它只能探测30cm,要想更远,把下面的代码删去
我这么做的原因下一篇控制方面在解释