STM32蓝牙智能小车

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_20539533/article/details/102645395

这两周的实训课程,制作一个蓝牙控制的STM32智能小车。代码是给的。

硬件:

1.STM32板卡

2.电机驱动板L298N

3.小车套件(轮子,板材,电机等)

4.蓝牙JDY-30

5.18650锂电池

(巡线,超声波选配,代码有)

先测试电机是否能够正常运行(直接用STM32上的供电),组装小车,连接蓝牙,初始化配置蓝牙(AT指令),

最后烧录小车程序,测试小车能否正常运行。

需要学习这方面的知识:

蓝牙、串口、中断、GPIO、定时器、PWM。(过,不会的自己百度,看书,CSDN都一堆)

接线:

驱动电机与L298N:这还要我教?电机接对应的output,不对就反过来。

JDY-30与STM32连接 :

  JDY-30             STM32

VCC   <---------------->  +5V

GND <---------------->  GND

TXD   <---------------->  U1_Rx(PD2)

RXD   <---------------->  U1_Tx(PC12)

L298N与STM32连接 :

L298N              STM32

 GND  <---------------->  GND

+5V   <---------------->  +5V

IN1   <---------------->  PB4

IN2   <---------------->  PB3

IN3   <---------------->  PB5

IN4   <---------------->  PC11

L298N 与18650锂电池连接:

 L298N            18650锂电池

 GND   <---------------->   GND    (黑色线)        

 +12V   <---------------->   VCC     (红色线)

 

注意事项

电源线和地线切勿接反!!(如果反了可能烧掉MCU)。在烧录代码的时候,请不要外部锂电池给板卡供电!!!

主函数main.c

#include "stm32f10x.h"
#include "drv_rgb.h"
#include "drv_uart.h"
#include "SysTick.h"
#include <stdio.h>
#include "misc.h"
#include "Front_hc04.h"
#include "drv_time.h"
#include "drv_car.h"
#include "drv_serchLine.h"

float retDate = 0;

int main(void)
{	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SysTick_init(72);
	RGB_Configuration();
	Uart1_Configuration();
	Uart5_Configuration();
	TIM_InitConfig();
	Hc_Sr04_Init();
	TIM3_Configuration();
	TIM_SetSpeed(0, 0);
	SERCHLINE_Configuration();
	
	Hc_Sr04_Start();

	while(1)
	{	
		if (AutoDriver_IsAutoDriverFlag())
		{
			// ×Ô¶¯Ñ°¼£
			SERCHLINE_AutoRun();
			
			// ×Ô¶¯±ÜÕÏ
			if (HCSR04_IsGetDistantFlag())
			{
				HCSR04_ClearIsGetDistantFlag();
				retDate = HC_SR04_Get_Distance();
				printf("retDate = %f\n",retDate);
				if (retDate < 3)
					TIM_SetSpeed(0, 0);
				delay_ms(50);
				Hc_Sr04_Start();
			}
		}
		
	}
}

中断函数stm32f10x_it.c:(手机APP自定义命令,16位那个,a的那个填是0A,b的是0B)

/**
  ******************************************************************************
  * @file    GPIO/IOToggle/stm32f10x_it.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and peripherals
  *          interrupt service routine.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "stm32f10x_gpio.h"
#include "drv_uart.h"
#include "Front_hc04.h"
#include "SysTick.h"
#include "math.h"
#include "stm32f10x_exti.h"
#include "stdio.h"
#include "drv_time.h"
#include "drv_rgb.h"
/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup GPIO_IOToggle
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************/
/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSV_Handler exception.
  * @param  None
  * @retval None
  */
void PendSV_Handler(void)
{
}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
}

/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
void USART1_IRQHandler(void)
{
	if(SET == USART_GetITStatus(USART1, USART_IT_RXNE))
	{
		USART_SendData(UART5, USART_ReceiveData(USART1));
		//USART_SendData(USART1, USART_ReceiveData(USART1));
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}	
}

void UART5_IRQHandler(void)
{
	if(SET == USART_GetITStatus(UART5, USART_IT_RXNE))
	{
		USART_ClearITPendingBit(UART5, USART_IT_RXNE);
		RGB_B_OPEN();
   	USART_SendData(USART1, USART_ReceiveData(UART5));
		if (!AutoDriver_IsAutoDriverFlag())
		{
			switch (USART_ReceiveData(UART5))
			{
			// 占空比100%(前进)
			case 0x01:
				TIM_SetSpeed(100, 100);
				break;
			
			// 70%占空比(前进)
			case 0x02:
				TIM_SetSpeed(70, 70);
				break;
			
			// 50%占空比(前进)
			case 0x03:
				TIM_SetSpeed(50, 50);
				break;
			
			// 占空比100%(后退)
			case 0x04:
				TIM_SetSpeed(-100, -100);
				break;
			
			// 70%占空比(后退)
			case 0x05:
				TIM_SetSpeed(-70, -70);
				break;
			
			// 50%占空比(后退)
			case 0x06:
				TIM_SetSpeed(-50, -50);
				break;
			
			// 停止
			case 0x07:
				TIM_SetSpeed(0, 0);
				break;
			
			// 左转
			case 0x08:
				TIM_SetSpeed(-50, 50);
				break;
			
			// 右转
			case 0x09:
				TIM_SetSpeed(50, -50);
				break;

			// 开启自动驾驶
			case 0x0a:
				AutoDriver_SetIsAutoDriverFlag();
				break;
			
			// 关闭自动驾驶
			case 0x0b:
				AutoDriver_ClearAutoDriverFlag();
				break;
				
			default:
				break;
			}
		}
		else
		{
			switch (USART_ReceiveData(UART5))
			{
			// 开启自动驾驶
			case 0x0a:
				AutoDriver_SetIsAutoDriverFlag();
				break;
			
			// 关闭自动驾驶
			case 0x0b:
				AutoDriver_ClearAutoDriverFlag();
				break;
				
			default:
				break;
			}
		}
		
	}	
}

void TIM6_IRQHandler(void) 
{ 
	if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET) 
	{ 
		count_HcSr04++;
		TIM_ClearITPendingBit(TIM6,TIM_IT_Update); 
	} 
}

void EXTI15_10_IRQHandler(void)
{
	if (SET == EXTI_GetITStatus(EXTI_Line12))
	{
		if (!(TIM6->CR1 & 0x01))
		{
			//上升沿,清计时时间,开定时器
			count_HcSr04 = 0;
			TIM6->CNT = 0;
			TIM6->CR1 |= 0x01;
			Ex_NVIC_Config(GPIO_A,12,FTIR);
		}
		else
		{
			// 下降沿,关定时器
			TIM6->CR1 &= (~0x01);
			HCSR04_SetIsGetDistantFlag();
			Ex_NVIC_Config(GPIO_A,12,RTIR);
		}
		EXTI_ClearITPendingBit(EXTI_Line12);
	}
}
/*void PPP_IRQHandler(void)
{
}*/

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

drv_rgb.c



#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "drv_rgb.h"
void RGB_Configuration(void)
{
	
	//开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure; 
	//初始化GPIO口
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	//初始化灭灯
	GPIO_SetBits(GPIOC, GPIO_Pin_8);
}



//开灯
void RGB_B_OPEN(void)
{
    GPIO_ResetBits(GPIOC, GPIO_Pin_8);
}

//灭灯
void RGB_B_CLOSE(void)
{
    GPIO_SetBits(GPIOC, GPIO_Pin_8);
}

drv_uart.c

/*
**	À¶ÑÀÄ£¿é½ÓÏß·½Ê½£º	
**			PD2-------TXD
**			PC12------RXD
**				
*/
#include "stm32f10x.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include <stdio.h>
#include "drv_uart.h"

void Uart1_Configuration(void)
{
		GPIO_InitTypeDef GPIO_InitStructure; 
		USART_InitTypeDef USART_InitStructure; 
		NVIC_InitTypeDef NVIC_InitStructure;
		//开时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
		//初始化GPIO
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
		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);
	
	  //初始化串口
		USART_InitStructure.USART_BaudRate = 9600; 
		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_Tx | USART_Mode_Rx; 
		USART_Init(USART1, &USART_InitStructure);
		
		//配置接收中断
		USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	  //指定中断优先级
		NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		
		NVIC_Init(&NVIC_InitStructure);
	
		//使能串口
		USART_Cmd(USART1,ENABLE);
}

void Uart5_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
	USART_InitTypeDef USART_InitStructure; 
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 9600; 
	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_Tx | USART_Mode_Rx; 
	USART_Init(UART5, &USART_InitStructure);
	
	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);

	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	//ʹÄÜ´®¿Ú
	USART_Cmd(UART5,ENABLE);
}

void USART1_SendStr(char *str)
{
	while(*str != '\0')
	{
		USART_SendData(USART1, *str++);
		while(SET != USART_GetFlagStatus(USART1, USART_FLAG_TXE));
	}
}


//重定向printf
int fputc(int ch, FILE *fp)
{
		USART_SendData(USART1, ch);
		while(SET != USART_GetFlagStatus(USART1, USART_FLAG_TXE));
	
		return ch;
}

超声波测距

Front_hc04.c

/*
**	
**			PA11-------TRIG
**			PA12-------ECHO
**				
*/
#include "Front_hc04.h"
#include "SysTick.h"
#include "math.h"
#include "drv_uart.h"
#include "drv_rgb.h"
#include <stdio.h>

#define HCSR04_TRIG					GPIO_Pin_11
#define HCSR04_ECHO					GPIO_Pin_12
#define HCSR04_PORT					GPIOA

#define HCSR04_APBPERIPH_CLK_FUNC	RCC_APB2PeriphClockCmd
#define HCSR04_APBPERIPH_PORT		(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO)

static volatile uint8_t isGetDistant = 0;
volatile uint32_t count_HcSr04 = 0;
static volatile uint8_t isAutoDriver = 0;

void Hc_Sr04_Init(void)
{
	EXTI_InitTypeDef EXTI_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	
	HCSR04_APBPERIPH_CLK_FUNC(HCSR04_APBPERIPH_PORT, ENABLE);
	
	// trig
	GPIO_InitStruct.GPIO_Pin = HCSR04_TRIG;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(HCSR04_PORT, &GPIO_InitStruct);
	
	//Echo
	GPIO_InitStruct.GPIO_Pin = HCSR04_ECHO;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(HCSR04_PORT, &GPIO_InitStruct);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource12);
	
	Ex_NVIC_Config(GPIO_A,12,RTIR);

	EXTI_InitStruct.EXTI_Line = EXTI_Line12;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStruct);

	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
}

void Hc_Sr04_Start(void)
{	
	HC_SR04_OUT(1);
	delay_us(20);
	HC_SR04_OUT(0);
}

float HC_SR04_Get_Distance(void)
{
	uint32_t temp = 0;
	float Distance = 0;

	temp = (count_HcSr04*1000+TIM6->CNT)/2;
	//转换公式
	Distance = (temp* 346.675)/10000;
	
	return Distance;
}

void HCSR04_SetIsGetDistantFlag(void)
{
	isGetDistant = 1;
}

void HCSR04_ClearIsGetDistantFlag(void)
{
	isGetDistant = 0;
}

uint8_t HCSR04_IsGetDistantFlag(void)
{
	return isGetDistant;
}

void AutoDriver_SetIsAutoDriverFlag(void)
{
	isAutoDriver =1;
}

void AutoDriver_ClearAutoDriverFlag(void)
{
	isAutoDriver = 0;
}

uint8_t AutoDriver_IsAutoDriverFlag(void)
{
	return isAutoDriver;
}

//外部中断配置函数
// GPIO_x		: GPIO_A GPIO_B... 参考相应的.h文件中的参数定义
// BITx			: 具体所在的位 eg:BIT11       11
// TRIM			: TRIMÎ为FTIR表示下降沿触发     为RTIR表示上升沿触发
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 
{ 
	u8 EXTOFFSET=(BITx%4)*4;  
	RCC->APB2ENR|=1<<0;  						/使能AFIO时钟
	switch (BITx/4)
	{
	case 0:
		AFIO->EXTICR[BITx/4]&=~(0x000F<<EXTOFFSET);//清除原来的设置
		AFIO->EXTICR[BITx/4]|=GPIOx<<EXTOFFSET;	//EXTI.BITxÓ³Éäµ½GPIOx.BITx 
		break;
	
	case 0x01:
		AFIO->EXTICR[BITx/4] &=~(0x000F<<EXTOFFSET);//清除原来的设置
		AFIO->EXTICR[BITx/4] |=GPIOx<<EXTOFFSET;
		break;
	
	case 0x02:
		AFIO->EXTICR[BITx/4] &=~(0x000F<<EXTOFFSET);//清除原来的设置
		AFIO->EXTICR[BITx/4] |=GPIOx<<EXTOFFSET;
		break;
	
	case 0x03:
		AFIO->EXTICR[BITx/4] &=~(0x000F<<EXTOFFSET);//清除原来的设置
		AFIO->EXTICR[BITx/4] |=GPIOx<<EXTOFFSET;
		break;
	
	default:
		break;
	}
	
	//自动设置
	EXTI->IMR|=1<<BITx;					//开启line BITx上的中断(要禁止,反操作)
	if(TRIM&0x01)EXTI->FTSR|=1<<BITx;	//line BITx上事件下降沿触发
	if(TRIM&0x02)EXTI->RTSR|=1<<BITx;	//line BITx上时间上升沿触发
} 	

SysTick.c




#include "SysTick.h"


static u8  fac_us=0;//us延时倍乘数
static u16 fac_ms=0;//ms延时倍乘数
//初始化延时函数
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void SysTick_init(u8 SYSCLK)
{
	SysTick->CTRL&=0xfffffffa;//bit2清空,选择外部时钟  HCLK/8
	fac_us=SYSCLK/8;		    
	fac_ms=(u16)fac_us*1000;
}



//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           //清空计数器
	SysTick->CTRL=0x01 ;          //开始倒数 
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
	SysTick->CTRL=0x00;       //关闭计数器
	SysTick->VAL =0X00;       //清空计数器	  	    
}   



//延时为nus
//nus为要延时的us数.		    								   
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; //时间加载		 
	SysTick->VAL=0x00;        //清空计数器
	SysTick->CTRL=0x01 ;      //开始倒数	 
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
	SysTick->CTRL=0x00;       //关闭计数器
	SysTick->VAL =0X00;       //清空计数器
}


drv_time.c

#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "drv_time.h"

#define MOTOR_LEFT_PWM_PIN_IN1			GPIO_Pin_4
#define MOTOR_LEFT_DIR_PIN_IN2			GPIO_Pin_3
#define MOTOR_RIGHT_PWM_PIN_IN3			GPIO_Pin_5
#define MOTOR_RIGHT_DIR_PIN_IN4			GPIO_Pin_11

#define MOTOR_PWM_PORT					GPIOB
#define MOTOR_DIR_LEFT					GPIOB
#define MOTOR_DIR_RIGHT					GPIOC

void TIM3_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
		
	//开启定时器的外设时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	// 开启复用时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

	// GPIO配置(PWM通道引脚)
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin = MOTOR_LEFT_PWM_PIN_IN1 | MOTOR_RIGHT_PWM_PIN_IN3;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(MOTOR_PWM_PORT, &GPIO_InitStruct);
	// 方向控制引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = MOTOR_RIGHT_DIR_PIN_IN4;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(MOTOR_DIR_RIGHT, &GPIO_InitStruct);
	GPIO_InitStruct.GPIO_Pin = MOTOR_LEFT_DIR_PIN_IN2;
	GPIO_Init(MOTOR_DIR_LEFT, &GPIO_InitStruct);

	// 配置定时器的参数(预分频值,分频系数等)
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 1000;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 719;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);

	// 配置PWM输出
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0;
	TIM_OC1Init(TIM3, &TIM_OCInitStruct);
	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

	TIM_OCInitStruct.TIM_Pulse = 0;
	TIM_OC2Init(TIM3, &TIM_OCInitStruct);
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

	TIM_ARRPreloadConfig(TIM3, ENABLE);
	TIM_Cmd(TIM3, ENABLE);
}

void TIM6_Configuration(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE);
	TIM_TimeBaseStructure.TIM_Period = 1000;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
	TIM_ClearFlag(TIM6, TIM_FLAG_Update);

	TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
		
	TIM_Cmd(TIM6, DISABLE);	
}

void TIM6_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 
	
    NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;	  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void TIM_InitConfig(void)
{
	TIM6_Configuration();
	TIM6_NVIC_Configuration();
}

void TIM_SetSpeed(int left, int right)
{
	// left&rightµÄÖµÔÚ+100µ½-100·¶Î§ÄÚ
	if ((left > 100) || (left < -100))
		return ;
	if ((right > 100) || (right < -100))
		return ;
			
	if (left >= 0)
	{
		GPIO_SetBits(MOTOR_DIR_LEFT, MOTOR_LEFT_DIR_PIN_IN2);
	}
	else
	{
		GPIO_ResetBits(MOTOR_DIR_LEFT, MOTOR_LEFT_DIR_PIN_IN2);
		left = 100+left;
	}

	if (right >= 0)
	{
		GPIO_SetBits(MOTOR_DIR_RIGHT, MOTOR_RIGHT_DIR_PIN_IN4);
	}
	else
	{
		GPIO_ResetBits(MOTOR_DIR_RIGHT, MOTOR_RIGHT_DIR_PIN_IN4);
		right = 100+right;
	}
	
	TIM_SetCompare1(TIM3, left*10);
	TIM_SetCompare2(TIM3, right*10);
}

drv_serchLine.c

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "drv_time.h"

#define SERCHLINE_PERIPH_CLK_FUNC				RCC_APB2PeriphClockCmd
#define SERCHLINE_PERIPH_PORT					(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB)
#define SERCHLINE_PORT_CENTER					GPIOC
#define SERCHLINE_PORT							GPIOB

#define SERCHLINE_CENTER_PIN					GPIO_Pin_2
#define SERCHLINE_LEFT_PIN						GPIO_Pin_8
#define SERCHLINE_RIGHT_PIN						GPIO_Pin_12

// ³¯Ç°½ø·½Ïò¿´£¬D1ÔÚ×ó±ß D2ÔÚÖмä D3ÔÚÓÒ±ß
#define D1										GPIO_ReadInputDataBit(SERCHLINE_PORT, SERCHLINE_LEFT_PIN)
#define D2										GPIO_ReadInputDataBit(SERCHLINE_PORT_CENTER, SERCHLINE_CENTER_PIN)
#define D3										GPIO_ReadInputDataBit(SERCHLINE_PORT, SERCHLINE_RIGHT_PIN)

void SERCHLINE_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	SERCHLINE_PERIPH_CLK_FUNC(SERCHLINE_PERIPH_PORT, ENABLE);

	GPIO_InitStruct.GPIO_Pin = SERCHLINE_CENTER_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(SERCHLINE_PORT_CENTER, &GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin = SERCHLINE_LEFT_PIN | SERCHLINE_RIGHT_PIN;
	GPIO_Init(SERCHLINE_PORT, &GPIO_InitStruct);
}

void SERCHLINE_AutoRun(void)
{
	// ¸Ã²¿·ÖµÄ´úÂëÖ»ÊÇÌṩһ¸öʾÀýµÄ˼·£¬¾ßÌåµÄÐèÒª¸ù¾ÝÓ²¼þÉϹâµç´«¸ÐÆ÷µÄ²¼¾Ö
	// ÖØÐÂÓÅ»¯£¬´«¸ÐÆ÷µÄ²¼¾Ö·½Ê½²»Í¬£¬¶ÔÓ¦µÄ´úÂëµÄʵÏÖÉÏÐèÒª×öÏàÓ¦µÄ×îÓŵ÷Õû
	
	// С³µÔÚÑ°¼£ÏßÉÏ£¬Á½±ß²»Ö´ÐвîËÙ
	if ((1 == D1) && (0 == D2) && (1 == D3))
	{
		TIM_SetSpeed(70, 70);
	}
	// С³µÆ«Ïò×ó±ß£¬ÐèÒªÍùÓұߵ÷Õû
	else if ((1 == D1) && (1 == D2) && (0 == D3))
	{
		TIM_SetSpeed(100, 70);
	}
	// С³µÆ«ÏòÓұߣ¬ÐèÒªÍù×ó±ßµ÷Õû
	else if ((0 == D1) && (1 == D2) && (1 == D3))
	{
		TIM_SetSpeed(70, 100);
	}
	// Èç¹ûС³µÒѾ­ÍêÈ«ÍÑÀëÔ¤¶¨µÄ¹ì¼£Ïß»òÏÖÓеij¡µØÎÞ·¨Õý³£±æʶ³ö¹ì¼£Ïߣ¬Ôò×öÖƶ¯´¦Àí
	else if (((0 == D1) && (0 == D2) && (0 == D3)) || ((1 == D1) && (1 == D2) && (1 == D3)))
	{
		TIM_SetSpeed(0, 0);
	}
}

app:百度盘下载

提取码:fl7n

猜你喜欢

转载自blog.csdn.net/qq_20539533/article/details/102645395