基于STM32F103C8T6最小系统板的两轮平衡小车的创作(三、软件部分)

我们继续学习

下面是蓝牙部分,直接上原理图

 

接着是代码部分,大家应该都会没啥说的

 /******************************                    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,要想更远,把下面的代码删去

 我这么做的原因下一篇控制方面在解释

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值