粤嵌实训笔记一

2023/2/21(第一周周二)

1.使能时钟(中文手册p53)
函数
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
uint32_t RCC_AHB1Periph 外设名字
FunctionalState NewState (ENABLE使能时钟/DISABLE禁止时钟)
例子:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE)

2.初始化引脚
GPIO_Init()

 		void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
		GPIO_TypeDef*  GPIOx   (A-I引脚组)
		GPIO_InitTypeDef*   GPIO_InitStruct(结构体指针)
		GPIO_Pin :(GPIO_Pin_0)
		GPIO_Mode:(GPIO_Mode_IN/AF/OUT)
		GPIO_Speed:(GPIO_Speed_50MHz)(一般50MHz)
		GPIO_OType:(GPIO_OType_PP/OD)(pp推挽)
		GPIO_PuPd:(GPIO_PuPd_NOPULL/UP/DOWN)带上拉电阻输入,下拉电阻输入;

例子:初始化PF9,输出推挽

	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_OD;
	GPIO_Init(GPIOF,&GPIO_InitStruct);

3.操作引脚
3.1 输出
(置1)高电平 GPIO_SetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
低电平 GPIO_ResetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
反转电平 GPIO_ToggleBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
GPIOx :组号 x= A-I
GPIO_Pin_x :编号:x=0-15

例子:PF9输出高电平
GPIO_SetBits(GPIOF,GPIO_Pin_9);

3.2 获取引脚状态(读)

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
GPIOx :组号 x= A-I
GPIO_Pin_x :编号:x=0-15
uint8_t 返回值:0/1

例子:PA2引脚的状态

if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)== 1) 
{
	//高电平
}else
{
	//低电平
}

5.LED灯的实现(user/src/)
main.c
led.h

//(头文件格式)
	#ifndef __LED_H__
	#define __LED_H__
	/*宏定义、函数声明
	  宏定义
	  #define XX XX
	  #define XX XX
	  #define XX XX
	  函数声明
	  void  led_ctl(int LED_ID,int ON_OFF);
	  void led_init();
	*/
	#endif 
  (头文件引用)
(搜索路径不同)
(自己写的要用双引号)
	#include <>  (只标准头文件路径)(usr/include)
	#include ""  (先从当前工程路径,后标准头文件)
	(官方库在工程下,所以用“ ”)

led.c

#include "led.h"

	//灯的初始化
	void led_init()
	{
		//1使能时钟
		
		//2初始化引脚
		
		//3默认全熄灭
		

	
	}
	 /*
	       控制第几个灯,和状态
	 	   点亮灯二 led_ctl(LED_1,ON)
	
		   LED_ID:灯的编号
		   			#define led1 1
		   			#define led2 2
		   ON_OFF:状态
		   			#define  ON 1
		   			#define OFF 0
	*/
	void  led_ctl(int LED_ID,int ON_OFF)
	{
		
		
	
	}

编写代码: IS
编译用 Keil

20230222(第一周周三)小车组装

通电-反接==前后走
电势差==转速 3.5v/5v

驱动(小车上的块)

	-A-1:--------引脚(输出)
	-A-2:--------引脚(输出)

(电源) -VCC
-GND

	-B-1:
	-B-2:

正:
1
0
vcc
gnd
1
0
可以用
D0 PC6
D2 PC8
D4 PC11
D6 PE5

==========
D1 PC7
D3 PC9
D5 PB6
D7 PE6

==========

使用:输出推挽

红外模块:T发射 D接收

原理: 有障碍 -》 收到反射==》 out = =》输出0

任务:按照黑色胶带轨迹行驶(代码思路如下)

bool left_D = GPIO_ReadInputDataBit(GPIO?, GPIO_Pin_?);//左传感器

bool right_D = GPIO_ReadInputDataBit(GPIO?, GPIO_Pin_?);//右传感器



if(  == 0 )//out 
{
	//有反射

}else
{
	//无反射
}

20230223循迹(第一周周三)

bool left_D = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8);//左传感器out
bool right_D = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);//右传感器out

地面白色:有反射 out=0
遇见黑色:接收不到 out=1

左0右1–右转
左1右0–左转
左1右1–停止
左0右0–前进

接线:
vcc
gnd
in1  right_D ---D0-PC6--01黑
?
in3  left_D  ---D2--PC8-01黑
?

//D0 PC6
//D2 PC8

20230223避障(第一周周四)

根据空气对于红外光线有一定的削弱作用
当前方有障碍物时,红外接收管就能够收到红外光线
当前方没有障碍物时,红外接收管就不能收到红外光线

5)避障代码实现

	//自动避障 
	void auto_drive()
	{
		unsigned char l,r;
		while(1)
		{
			l = GPIO_ReadInputDataBit( , );
			r = 
			
			if( l == 1 && r == 1 )	//两边都没有障碍物
			{
				//前进
			}
			else if()	//左边有障碍物,右边没有
			{}
			else if()	//右边有障碍物,左边没有
			{}
			else if() 	//两边都有障碍物
			{
				//180°调头
			}
		}
	}

3、利用脉冲宽度调制技术 控制 转速

	//PWM调速 左转 
	void PWM_move_left()
	{
		unsigned char i = 2;
		
		set_left_a(0);
		set_right_a(1);
		
		while(i--)
		{
			set_left_b(1);
			set_right_b(0);
			delay_ms(70);	//转动
			
			set_left_b(0);
			set_right_b(1);
			delay_ms(30);	//停止,但是由于惯性会继续转动的
		}
	}

20230224蓝牙模块(第一周周五)

3)串口协议

	串口发送和接收数据都是以 帧Frame 为单位  
	
		1 帧Frame =  1个StartBit起始位 + 5~9DataBits数据位 + 
					0/1个校验位  + 0.5~2个StopBots停止位 
					
			起始位:一个周期的低电平
			数据位:5~9bits的数据位,具体是多少,需要双方协商,通常是8bits 
			校验位:
				0bit : 没有校验位
				1bit :有一个校验位   “赖子位”
			
					奇校验 Odd 
						要保证传输1的个数为奇数个 
						D0 D1 D2 D3  D4 D5 D6 D7      X 
						1  1  0  1   0  0  1  0       1
					
					偶校验 Even 
					
					纠错能力太有限了,只能检测出一个bit位有误,还不能纠错 
			停止位: 
				0.5个周期的高电平 
				1个周期的高电平
				1.5个周期的高电平
				2个周期的高电平

蓝牙控制

usart.c   /  usart.h   

	//串口1的初始化 USART1 
	void usart1_init()
	{
		//1)GPIO引脚的初始化 
		//2)串口的初始化
		//3)串口中断的配置
		//4)开启串口
	}
	
	
	unsigned char cmd = 0;	//保存接收的指令数据
		
	//串口1的中断处理函数 
	void USART1_IRQHandler(void)
	{
		//判断接收标志是否产生
		if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
		{
			cmd = USART_ReceiveData( USART1 );	//获取数据 
			
			//清除标志
			USART_ClearITPendingBit( USART1, USART_IT_RXNE );
		}
	}		
			
		
	//蓝牙控制 
	void bt_ctl()
	{
		while(1)
		{
			if( cmd == 1 )	//前进 
			{
			}
			else if(  )
			{
			}
			else if()
			{}
			...
		}
	}

代码

lcd.c

#include "led.h"
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"


//led灯的GPIO引脚初始化 
void led_init()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//1.使能GPIO引脚的时钟 
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF, ENABLE );
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOE, ENABLE );
	
	//2.初始化GPIO
	
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;	//9、10号引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;			//输出功能
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;		//50MHz输出速率
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;			//输出推挽
	//GPIO_InitStruct.GPIO_PuPd = 
	GPIO_Init( GPIOF, &GPIO_InitStruct );

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;	//13、14号引脚
	GPIO_Init( GPIOE, &GPIO_InitStruct );
	
	//3.设置灯默认的状态 全部熄灭 
	GPIO_SetBits( GPIOF , GPIO_Pin_9 );
	GPIO_SetBits( GPIOF , GPIO_Pin_10 );
	
	GPIO_SetBits( GPIOE , GPIO_Pin_13 );
	GPIO_SetBits( GPIOE , GPIO_Pin_14 );
	
}


/*
	led_ctl:led灯的控制函数 
		参数: 
			LED_ID:灯的编号 
					#define led1 1 
					#define led2 2 
					...
			ON_OFF:灯的状态 
					亮  #define ON  0 
					灭  #define OFF 1
*/
void led_ctl( int LED_ID, int ON_OFF )
{
	if( LED_ID == led1 ) 	//灯1  -- PF9
	{
		if( ON_OFF == ON )	//点亮 
		{
			GPIO_ResetBits( GPIOF, GPIO_Pin_9 );  //清0
		}
		else	//熄灭
		{
			GPIO_SetBits( GPIOF, GPIO_Pin_9 );	//置1
		}
	}
	else if( LED_ID == led2 ) 	//灯2  -- PF10
	{
		if( ON_OFF == ON )	//点亮 
		{
			GPIO_ResetBits( GPIOF, GPIO_Pin_10 );  //清0
		}
		else	//熄灭
		{
			GPIO_SetBits( GPIOF, GPIO_Pin_10 );	//置1
		}
	}
	else if( LED_ID == led3 ) 	//灯3  -- PE13
	{
		if( ON_OFF == ON )	//点亮 
		{
			GPIO_ResetBits( GPIOE, GPIO_Pin_13 );  //清0
		}
		else	//熄灭
		{
			GPIO_SetBits( GPIOE, GPIO_Pin_13 );	//置1
		}
	}
	else if( LED_ID == led4 ) 	//灯4  -- PE14
	{
		if( ON_OFF == ON )	//点亮 
		{
			GPIO_ResetBits( GPIOE, GPIO_Pin_14 );  //清0
		}
		else	//熄灭
		{
			GPIO_SetBits( GPIOE, GPIO_Pin_14 );	//置1
		}
	}
}




//流水灯
void water_led()
{
	int i;
	while(1)
	{
		for(i=1; i<=4; i++)
		{
			led_ctl( i , ON);
			delay_ms(300);	//延时300ms
			led_ctl( i , OFF);
		}
		
	}
}



lcd.h


#ifndef __LED_H__
#define __LED_H__



//一般包含 宏定义、函数声明等 

//灯的编号
#define led1 1 
#define led2 2
#define led3 3
#define led4 4

//灯的状态
#define ON  0 
#define OFF 1



void led_init();
void led_ctl( int LED_ID, int ON_OFF );
void water_led();



#endif



key.h


#ifndef __KEY_H__
#define __KEY_H__
#define KEY1 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
#define KEY3 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define KEY4 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)
void key_init();
void key_ctl_led();



#endif





key.c


#include "key.h"
#include "led.h"
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
//key按键的初始化 
void key_init()
{
	GPIO_InitTypeDef GPIO_InitStruct;

	//1.使能时钟 
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOE, ENABLE );
	
	//2.初始化GPIO引脚,带上拉的输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;	//输入功能
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;	//带上拉的输入
	GPIO_Init( GPIOA, &GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
	GPIO_Init( GPIOE, &GPIO_InitStruct);
}

/*通过4个按键 分别控制4盏灯  
	按下key1, 灯1亮,松开 灯1熄灭
	按下key2, 灯2亮,松开 灯2熄灭
	...
*/
void key_ctl_led()
{
	while(1)
	{
		//if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0 )  //判断按键1 是否按下
		if( KEY1 == 0 )
		{
			led_ctl( led1, ON );
		}
		else	
		{ 
			led_ctl( led1, OFF );
		}

		if( KEY2  == 0 )	//判断按键2 
		{
			led_ctl( led2, ON );
		}
		else	
		{ 
			led_ctl( led2, OFF );
		}

		if( KEY3  == 0 )	//判断按键3 
		{
			led_ctl( led3, ON );
		}
		else	
		{ 
			led_ctl( led3, OFF );
		}

		if( KEY4  == 0 )	//判断按键4 
		{
			led_ctl( led4, ON );
		}
		else	
		{ 
			led_ctl( led4, OFF );
		}
		
	}
}


delay.h


#ifndef __DELAY_H__
#define __DELAY_H__


void delay_us(int n);
void delay_ms(int n);


#endif


delay.c


#include "delay.h"
#include <stdint.h>
#include "stm32f4xx.h"

#define rSysTickCtrl  	*((volatile unsigned long*)0xE000E010)
#define rSysTickVal  	*((volatile unsigned long*)0xE000E018)
#define rSysTickReload 	*((volatile unsigned long*)0xE000E014)

//等待的时间
static uint32_t wait_time = 0;

void delay_us(int n)
{
	//1. 配置SysTick定时器
	// disable Sytick
	rSysTickCtrl &= ~(1 << 0);

	//enable INT, select processor clock
	rSysTickCtrl |= (1 << 1) | (1 << 2);

	rSysTickVal = 0;

	rSysTickReload = SystemCoreClock/1000000 - 1;


	NVIC_SetPriority(SysTick_IRQn, 1);


	// 2. 把n 赋值给wait_time
	wait_time = n;
	rSysTickCtrl |= 1 << 0; //enable systick


	//3.
	while (wait_time > 0);


	// 4. disable systick
	rSysTickCtrl &= ~(1 << 0);

}


void delay_ms(int n)
{
	//1. 配置SysTick定时器
	// disable Sytick
	rSysTickCtrl &= ~(1 << 0);

	//enable INT, select processor clock
	rSysTickCtrl |= (1 << 1) | (1 << 2);

	rSysTickVal = 0;

	rSysTickReload = SystemCoreClock/1000 - 1;


	NVIC_SetPriority(SysTick_IRQn, 1);


	// 2. 把n 赋值给wait_time
	wait_time = n;
	rSysTickCtrl |= 1 << 0; //enable systick


	//3.
	while (wait_time > 0);


	// 4. disable systick
	rSysTickCtrl &= ~(1 << 0);

}

unsigned int systick_cnt = 0; //用来作为系统滴答计数,每次滴答自动+1,可以用作超时时间等待

//SysTick中断处理函数
void SysTick_Handler(void)
{
	if (wait_time > 0)
	{
		wait_time --;
	}
	systick_cnt++;
}




beep.h

#ifndef __BEEP_H__
#define __BEEP_H__
void beep_init();
void beep_ctl( int ON_OFF );

#endif



beep.c


#include "beep.h"
#include "led.h"
#include "stm32f4xx.h"


//beep蜂鸣器的GPIO引脚初始化
void beep_init()
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	//1.使能时钟
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF , ENABLE );

	//2.初始化GPIO
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_Init( GPIOF , &GPIO_InitStruct );

	//3.设置默认状态,不响
	GPIO_ResetBits( GPIOF, GPIO_Pin_8 );
}

//beep蜂鸣器的控制
void beep_ctl( int ON_OFF )
{
	if( ON_OFF == ON )	//响
	{
		GPIO_SetBits( GPIOF , GPIO_Pin_8 );
	}
	else 	//不响
	{
		GPIO_ResetBits( GPIOF, GPIO_Pin_8 );
	}
}



main.c

#include "stm32f4xx.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "delay.h"
#include "motor.h"
#include "track.h"
#include "usart.h"

int main()
{

	//初始化led灯 
	//led_init();
	//beep_init();//初始化蜂鸣器
	//key_init();//初始化按键
	
	motor_init();//初始化电机
	usart1_init();//初始化串口
	
	while(1)
	{
			move_left();
	    delay_ms(1000);
			move_front();
			
	    move_right();
	    delay_ms(1000);
			move_back();
			
			bt_ctl();
		
		//auto_drive();避障
		
		//led_ctl( led2 , ON );     //点亮灯2 
		
		//beep_ctl(OFF );   //蜂鸣器
		
		//led_ctl( 4 , 0 );//点亮灯2
		
		//key_led();  //按键开灯
		
		//water_led();  //流水灯
		
		//auto_track(); //循迹
		
		/*	move_front();//前后左右测试
			delay_ms(2000);
		  move_back();
	    delay_ms(2000);
			
			move_left();
	    delay_ms(1000);
			move_front();
			
	    move_right();
	    delay_ms(1000);
			move_back();
			
	    move_stop();
			delay_ms(2000);*/
		
	}


	return 0;
}




motor.c

#include "motor.h"
#include "led.h"
#include "delay.h"
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"

		

//电机的初始化 
 void motor_init()
  {
  	
   RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOC , ENABLE );
 	 RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE );
 	 RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOE , ENABLE );
  
 	 //2.初始化GPIO
	 GPIO_InitTypeDef  GPIO_InitStruct;

 	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_9;
 	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
 	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
 	 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
 	 GPIO_Init( GPIOC , &GPIO_InitStruct );
  
 	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
 	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
 	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
 	 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
 	 GPIO_Init( GPIOB , &GPIO_InitStruct );
  
 	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
 	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
 	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
 	 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
 	 GPIO_Init( GPIOE , &GPIO_InitStruct );


 	 //3.设置默认的状态 
	 GPIO_SetBits(GPIOB, GPIO_Pin_6);
	 GPIO_SetBits(GPIOC, GPIO_Pin_7);
	 GPIO_SetBits(GPIOC, GPIO_Pin_9);
	 GPIO_SetBits(GPIOE, GPIO_Pin_6);

	  /***引脚的使用
		  D1 PC7
		  D3 PC9
		  D5 PB6
		  D7 PE6
	  ***/
 
  }


//左轮 a极
void set_left_a( int n )
{
	if(n == 1)
	{
		GPIO_SetBits(GPIOC , GPIO_Pin_7);
	}
	else 
	{
		GPIO_ResetBits(GPIOC , GPIO_Pin_7);
	}
}
			
//左轮 b极
void set_left_b( int n )
{
	if(n == 1)
	{
		GPIO_SetBits(GPIOC , GPIO_Pin_9);
	}
	else 
	{
		GPIO_ResetBits(GPIOC , GPIO_Pin_9);
	}

}

//右轮 a极
void set_right_a( int n )
{
	if(n == 1)
	{
		GPIO_SetBits(GPIOB , GPIO_Pin_6);
	}
	else 
	{
		GPIO_ResetBits(GPIOB , GPIO_Pin_6);
	}

}

//右轮 b极
void set_right_b( int n )
{
	if(n == 1)
	{
		GPIO_SetBits(GPIOE , GPIO_Pin_6);
	}
	else 
	{
		GPIO_ResetBits(GPIOE , GPIO_Pin_6);
	}

}
			
			

//前进
void move_front()
{
	//左轮 
	set_left_a(1);
	set_left_b(0);
	
	//右轮 
	set_right_a(1);
	set_right_b(0);
}

/*(转弯:
	(1)一个转,另一个不转
	(2)一个正转,另一个反转

验收: 
前进、后退、左转、右转、停止 
*/

void move_back()
{
    //左轮 
	set_left_a(0);
	set_left_b(1);
	
	//右轮 
	set_right_a(0);
	set_right_b(1);

}

void move_left()
{
	//左轮 
	set_left_a(0);
	set_left_b(0);
	
	//右轮 
	set_right_a(1);
	set_right_b(0);

}

void move_right()
{
	//左轮 
	set_left_a(1);
	set_left_b(0);
	
	//右轮 
	set_right_a(0);
	set_right_b(0);

}

void move_stop()
{
	//左轮 
	set_left_a(0);
	set_left_b(0);
	
	//右轮 
	set_right_a(0);
	set_right_b(0);

}



//PWM调速 左转
void pwm_move_left()
{

    unsigned char i = 2;
	
	set_left_a(0);
	set_right_a(1);
	
	while(i--)
	{
		set_left_b(1);
		set_right_b(0);
		delay_ms(50);	//转动
		
		set_left_b(0);
		set_right_b(1);
		delay_ms(50);	//停止,但是由于惯性会继续转动的
	}
}


//PWM调速 右转
void pwm_move_right()
{
	unsigned char i = 2;
	
	set_left_a(1);
	set_right_a(0);
	
	while(i--)
	{
		set_left_b(0);
		set_right_b(1);
		delay_ms(50);	//转动
		
		set_left_b(1);
		set_right_b(0);
		delay_ms(50);	//停止,但是由于惯性会继续转动的
	}
}


//PWM调速 前进
void pwm_move_front()
{

    unsigned char i = 2;
	
	set_left_a(1);
	set_right_a(1);
	
	while(i--)
	{
		set_left_b(0);
		set_right_b(0);
		delay_ms(50);	//转动
		
		set_left_b(1);
		set_right_b(1);
		delay_ms(50);	//停止,但是由于惯性会继续转动的
	}
}

		

motor.h


#ifndef __MOTOR_H__
#define __MOTOR_H__



//一般包含 宏定义、函数声明等 


#define ON  0 
#define OFF 1



void motor_init();
void set_left_a( int n );
void set_left_b( int n );
void set_right_a( int n );
void set_right_b( int n);
void move_front();
void move_back();
void move_left();

void move_right();

void move_stop();

void pwm_move_front();
void pwm_move_left();
void pwm_move_right();

#endif

track.c

#include "track.h"
#include "motor.h"
#include "delay.h"

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"

		

//led灯的初始化 
void track_init()
{
	//1.使能GPIO引脚的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);	
	
	//2.初始化GPIO
	GPIO_InitTypeDef  GPIO_InitStruct;	
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
		
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;//输入功能
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//50MHz输出
	//GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;	
		
	GPIO_Init( GPIOC, &GPIO_InitStruct );//初始化

	
	
}

void auto_track()
{
	unsigned char l,r;
	while(1)
	{
		r = GPIO_ReadInputDataBit(GPIOC ,GPIO_Pin_8 );
		l = GPIO_ReadInputDataBit(GPIOC ,GPIO_Pin_6 );
		
		if( l == 0 && r == 0 )	//两边都没有压线
		{
			      pwm_move_front();//前进
		}
		else if(l == 1 && r == 0)	//左边压线,右边没有
		{
            pwm_move_left();
		}
		else if(l == 0 && r == 1)	//右边压线,左边没有
		{
            pwm_move_right();
		}
		else if(l == 1 && r == 1) 	//两边都压线
		{
            move_stop();
		}
	}

}



void auto_drive()
{
	unsigned char l,r;
	while(1)
	{
		r = GPIO_ReadInputDataBit(GPIOC ,GPIO_Pin_8 );
		l = GPIO_ReadInputDataBit(GPIOC ,GPIO_Pin_6 );
		
		if( l == 1 && r == 1 )	//两边都没有障碍
		{
			      pwm_move_front();//前进
		}
		else if(l == 1 && r == 0)	//左边有,右边没有
		{
			      move_back();
			      delay_ms(300);
            move_left();
			      delay_ms(700);
		}
		else if(l == 0 && r == 1)	//右边有,左边没有
		{
			      move_back();
			      delay_ms(300);
            move_right();
			      delay_ms(700);
		}
		else if(l == 0 && r == 0) 	//两边都有障碍
		{
			      move_back();
			      delay_ms(300);
            move_right();
			      delay_ms(1300);
		}
	}

}

track.h

#ifndef __TRACK_H__
#define __TRACK_H__

//一般包含 宏定义、函数声明等 

#define ON  0 
#define OFF 1

void track_init();
void auto_track();
void auto_drive();

#endif

usart.c

#include "stdio.h"
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "motor.h"
#include "usart.h"
#include "delay.h"
//初始化
//GPIO_Mode_AF	复用功能


void usart1_init()
{
	
	
		//1.使能GPIO引脚的时钟 
		RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );
		
		
		//初始化GPIO
		//A9发送   输出推挽      GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;		
		//A10接收   输入悬空 GPIO_PuPd_NOPULL 	
		
		GPIO_InitTypeDef GPIO_InitStruct;							
		
		GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;	//9、10号引脚
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF  ;			//复用功能
		GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;		//50MHz输出速率
		GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;		
		GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;	//A10接收   输入悬空

		GPIO_Init( GPIOA, &GPIO_InitStruct );

		//串口复用
		GPIO_PinAFConfig(GPIOA,  GPIO_PinSource9, GPIO_AF_USART1);//APB2
		GPIO_PinAFConfig(GPIOA,  GPIO_PinSource10, GPIO_AF_USART1);
		

		//2,使能串口时钟
		RCC_AHB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
		//初始化
		USART_InitTypeDef USART_InitStruct;//定义结构体
		USART_InitStruct.USART_BaudRate = 9600;
		USART_InitStruct.USART_WordLength = USART_WordLength_8b;
		USART_InitStruct.USART_StopBits = USART_StopBits_1;
		USART_InitStruct.USART_Parity = USART_Parity_No;//无校验
		USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//同时收r发t
		USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不需要
		USART_Init(USART1, &USART_InitStruct);

	 
	
		//NVIC中断控制
		NVIC_InitTypeDef NVIC_InitStruct;
		NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//串口一中断
		NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//是否上报
		NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级 0(最高优先级)-15
		NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//子优先级
		NVIC_Init(& NVIC_InitStruct);
		
		//3(c) 中断优先级分组
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
		

	//3,串口中断配置
	 
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

 
	//4,开启串口
    USART_Cmd(USART1, ENABLE);
    
						
										

}

 


unsigned char cmd = 0;	//保存接收的指令数据
			
//串口1的中断处理函数 
void USART1_IRQHandler(void)
{
	//判断接收标志是否产生
	if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
	{
		cmd = USART_ReceiveData( USART1 );	//获取数据 
		printf("%c",cmd); //把收到的数据发送回电脑	
		USART_ClearITPendingBit( USART1, USART_IT_RXNE );//清除标志
	}
}		
		



	
//蓝牙控制 
void bt_ctl()
{
	while(1)
	{
		if( cmd == '1' )	//前进 
		{
		  move_front();
			delay_ms(3000);
		}
		else if(  cmd == '2')//左转
		{
			move_left();			
			delay_ms(3000);

		}
		else if( cmd == '3')//右转
		{
			move_right();			
			delay_ms(3000);

		}
		else if( cmd == '4')//后退
		{
			move_back();			
			delay_ms(3000);

		}
		
	}
}
		

		

usart.h

#ifndef __USART_H__
#define __USART_H__
void usart1_init();
void bt_ctl();
#endif


  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值