目录
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--0地 1黑
?
in3 left_D ---D2--PC8-0地 1黑
?
//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