制作简单的小车运动控制程序,使用遥控器给小车发指令,遥控器和接收器都使用STM32。
遥控器端发不同的指令,小车接收器端解析指令再控制步进电机不同的运转。基于NRF24L01,作如下具体事项。
遥控器端main程序:
#include "sys.h"
#include "misc.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "24l01.h"
//#include "timer.h"
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
int main(void)
{
u8 key;
u8 tmp_buf[33];
u8 t;
SystemInit(); //系统时钟等初始化
delay_init(72); //初始化延时
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化波特率为9600,停止位1
LED_Init(); //初始化LED灯
KEY_Init(); //按键初始化
NRF24L01_Init(); //初始化NRF24L01
while(NRF24L01_Check())//检测不到24L01
{
delay_ms(1000);
LED0=!LED0; //D2闪烁
}
TX_Mode();//发送模式
for(t=0;t<6;t++)
{
tmp_buf[t]='0';
}
while(1)
{
key=KEY_Scan(0);
switch(key)
{
case KEY_FORWARD:
for(t=0;t<6;t++)
{
tmp_buf[t]='1';
}
NRF24L01_TxPacket(tmp_buf);
LED1=!LED1; //D3闪烁
//LCD_ShowString(100,210,239,32,16,"forward ");
break;
case KEY_BACKWARD:
for(t=0;t<6;t++)
{
tmp_buf[t]='2';
}
NRF24L01_TxPacket(tmp_buf);
LED1=!LED1; //D3闪烁
//LCD_ShowString(100,210,239,32,16,"backward ");
break;
case KEY_LEFT:
for(t=0;t<6;t++)
{
tmp_buf[t]='3';
}
NRF24L01_TxPacket(tmp_buf);
LED1=!LED1; //D3闪烁
//LCD_ShowString(100,210,239,32,16,"turn left");
break;
case KEY_RIGHT:
for(t=0;t<6;t++)
{
tmp_buf[t]='4';
}
NRF24L01_TxPacket(tmp_buf);
LED1=!LED1; //D3闪烁
//LCD_ShowString(100,210,239,32,16,"turn right");
break;
case KEY_STOP:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '1';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
//LCD_ShowString(100,210,239,32,16,"Stop ");
break;
case KEY_VACUUMPUMP:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '2';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
//LCD_ShowString(100,210,239,32,16,"Vacuumonoff");
break;
case KEY_FASTVEL:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '4';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
// LCD_ShowString(100,210,239,32,16,"fastVel ");
break;
case KEY_FAST:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '5';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
//LCD_ShowString(100,210,239,32,16,"slowVel ");
break;
case KEY_MIDDVEL:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '6';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
// LCD_ShowString(100,210,239,32,16,"steermotor1");
break;
case KEY_SLOW:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '7';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
//LCD_ShowString(100,210,239,32,16,"steermotor2");
break;
case KEY_SLOWVEL:
tmp_buf[0] = '1';
tmp_buf[1] = '1';
tmp_buf[2] = '1';
tmp_buf[3] = '0';
tmp_buf[4] = '1';
tmp_buf[5] = '8';
LED1=!LED1; //D3闪烁
NRF24L01_TxPacket(tmp_buf);
//LCD_ShowString(100,210,239,32,16,"spare1 ");
break;
}
delay_ms(5);
}
}
小车接收端main程序:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "spi.h"
#include "key.h"
#include "24l01.h"
#include "misc.h"
#include"stdio.h"
#include
#include "stm32f4xx_adc.h"
#include "Motorcontrol.h"
#include "steermotor.h"
#include "beep.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
int Vacuum=0; //关闭
int motorbrake=0;//抱闸关闭
extern int motion;//电机停止
int index=0;//按钮索引
int main(void)
{
u8 key, mode;
u16 t = 0;
u8 tmp_buf[33];
int decode;
//系统时钟初始化SystemInit()使原频率15750000HZ变成26880000HZ
SystemInit(); //系统时钟等初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //LCD初始化
KEY_Init(); //按键初始化
NRF24L01_Init(); //初始化NRF24L01
Adc_Init(); //初始化ADC
//BEEP_Init(); //初始化蜂鸣器端口
Initialization();//步进电机控制初始化
POINT_COLOR = RED;//设置字体为红色
LCD_ShowString(30, 50, 200, 16, 16, "Explorer STM32F4");
LCD_ShowString(30, 70, 200, 16, 16, "NRF24L01 ");
LCD_ShowString(30, 90, 200, 16, 16, "SIASUN Co.,Ltd");
LCD_ShowString(30, 110, 200, 16, 16, "2016/8");
while (NRF24L01_Check())
{
LCD_ShowString(30, 130, 200, 16, 16, "NRF24L01 Error");
delay_ms(200);
LCD_Fill(30, 130, 239, 130 + 16, WHITE);
delay_ms(200);
}
LCD_ShowString(30, 130, 200, 16, 16, "NRF24L01 OK");
while (1)
{
key = KEY0_PRES;
// key = KEY_Scan(0);
if (key == KEY0_PRES)
{
mode = 0;
break;
}
else if (key == KEY1_PRES)
{
mode = 1;
break;
}
t++;
if (t == 100)LCD_ShowString(10, 150, 230, 16, 16, "KEY0:RX_Mode KEY1:TX_Mode"); //闪烁显示提示信息
if (t == 200)
{
LCD_Fill(10, 150, 230, 150 + 16, WHITE);
t = 0;
}
delay_ms(5);
}
LCD_Fill(10, 150, 240, 166, WHITE);//清空上面的显示
POINT_COLOR = BLUE;//设置字体为蓝色
decode = 0;
if (mode == 0)//RX模式
{
LCD_ShowString(30, 150, 200, 16, 16, "NRF24L01 RX_Mode");
LCD_ShowString(30, 170, 200, 16, 16, "Received DATA:");
NRF24L01_RX_Mode();
while (1)
{
if (NRF24L01_RxPacket(tmp_buf) == 0)//一旦接收到信息,则显示出来.
{
tmp_buf[32] = 0;//加入字符串结束符
LCD_ShowString(0, 190, lcddev.width - 1, 32, 16, tmp_buf);
decode = atoi(tmp_buf);
switch (decode)
{
case 111111:
if(index!=1)
{
LCD_ShowString(100, 210, 239, 32, 16, "forward ");
LED1 = !LED1;
Brakeon();//电机抱闸打开
forward();
motion=1;//电机运动
index=1;
}
break;
case 222222:
if(index!=2)
{
LCD_ShowString(100, 210, 239, 32, 16, "backward ");
LED1 = !LED1;
Brakeon();//电机抱闸打开
backward();
motion=1;//电机运动
index=2;
}
break;
case 333333:
if(index!=3)
{
LCD_ShowString(100, 210, 239, 32, 16, "turn left");
LED1 = !LED1;
Brakeon();//电机抱闸打开
turnleft();
motion=1;//电机运动
index=3;
}
break;
case 444444:
if(index!=4)
{
LCD_ShowString(100, 210, 239, 32, 16, "turn right");
LED1 = !LED1;
Brakeon();//电机抱闸打开
turnright();
motion=1;//电机运动
index=4;
}
break;
case 111011:
if(index!=5)
{
LCD_ShowString(100, 210, 239, 32, 16, "Stop ");
LED1 = !LED1;
stop();
delay_ms(25);
Brakeoff();
motion=0;//电机运动
index=5;
}
break;
case 111012:
LCD_ShowString(100, 210, 239, 32, 16, "Vacuumonoff");
LED1 = !LED1;
Vacuumpump = !Vacuumpump;
if( Vacuum==0)
{
Vacuum=1;//打开
}
else
{
Vacuum=0;//关闭
}
index=6;
break;
case 111013:
LCD_ShowString(100, 210, 239, 32, 16, "motorbrake ");
LED1 = !LED1;
index=7;
break;
case 111014:
if(index!=8)
{
LCD_ShowString(100, 210, 239, 32, 16, "fastVel ");
LED1 = !LED1;
fastVel();
index=8;
}
break;
case 111015:
LCD_ShowString(100, 210, 239, 32, 16, "fast ");
LED1 = !LED1;
fast();
index=9;
break;
case 111016:
if(index!=10)
{
LCD_ShowString(100, 210, 239, 32, 16, "midVel ");
LED1 = !LED1;
middVel();
index=10;
}
break;
case 111017:
LCD_ShowString(100, 210, 239, 32, 16, "slow ");
LED1 = !LED1;
slow();
index=11;
break;
case 111018:
if(index!=12)
{
LCD_ShowString(100, 210, 239, 32, 16, "slowVel ");
LED1 = !LED1;
slowVel();
index=12;
}
break;
case 111019:
if(index!=13)
{
LCD_ShowString(100, 210, 239, 32, 16, "auto ");
LED1 = !LED1;
if( motorbrake==1)
{
forward();
delay_ms(500);
turnleft();
delay_ms(500);
forward();
delay_ms(500);
backward();
delay_ms(500);
turnright();
delay_ms(500);
backward();
delay_ms(500);
stop();
}
index=13;
}
break;
}
}
else
{
delay_us(5);
t++;
if (t == 10000)//大约1s钟改变一次状态
{
t = 0;
LED1 = !LED1;
}
}
}
}
else//TX模式
{
LCD_Fill(10, 150, 240, 166, WHITE);//清空上面的显示
POINT_COLOR = BLUE;//设置字体为蓝色
LCD_ShowString(60, 150, 200, 16, 16, "NRF24L01 TX_Mode");
LCD_ShowString(60, 170, 200, 16, 16, "please select key");
NRF24L01_TX_Mode();
for (t = 0; t<6; t++)
{
tmp_buf[t] = '0';
}
while (1)
{
key = KEY_Scan(0);
switch (key)
{
case WKUP_PRES:
for (t = 0; t<6; t++)
{
tmp_buf[t] = '1';
}
NRF24L01_TxPacket(tmp_buf);
LCD_ShowString(60, 190, 239, 32, 16, "Sended DATA:");
LCD_ShowString(0, 210, 239, 32, 16, tmp_buf);
LCD_ShowString(100, 210, 239, 32, 16, "forward ");
break;
case KEY1_PRES:
for (t = 0; t<6; t++)
{
tmp_buf[t] = '2';
}
NRF24L01_TxPacket(tmp_buf);
LCD_ShowString(60, 190, 239, 32, 16, "Sended DATA:");
LCD_ShowString(0, 210, 239, 32, 16, tmp_buf);
LCD_ShowString(100, 210, 239, 32, 16, "backward ");
break;
case KEY2_PRES:
for (t = 0; t<6; t++)
{
tmp_buf[t] = '3';
}
NRF24L01_TxPacket(tmp_buf);
LCD_ShowString(60, 190, 239, 32, 16, "Sended DATA:");
LCD_ShowString(0, 210, 239, 32, 16, tmp_buf);
LCD_ShowString(100, 210, 239, 32, 16, "turn left");
break;
case KEY0_PRES:
for (t = 0; t<6; t++)
{
tmp_buf[t] = '4';
}
NRF24L01_TxPacket(tmp_buf);
LCD_ShowString(60, 190, 239, 32, 16, "Sended DATA:");
LCD_ShowString(0, 210, 239, 32, 16, tmp_buf);
LCD_ShowString(100, 210, 239, 32, 16, "turn right");
break;
}
delay_ms(5);
}
}
}