基于STM32和PS2的遥控无线小车

欢迎大家关注博主的公众号 大海电子,在大海电子公众号里会和大家分享我的一些看法和知识。

不定期的会发布一些有趣的硬件作品及电路分析、软件源码分享。

基于STM32和PS2的遥控无线小车_第1张图片

需要以下源码工程请扫码关注大海电子,回复“基于STM32F103C8T6的PS2遥控小车源码及接线”,建议直接复制双引号里面的内容。(免费)

一、所需材料

整个工程文件:(淘宝购买)

https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.4c651deb7q5Hra&id=582278394068

 

1、小车底盘

 2WD(2驱):

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.12.fff43961B3dZVc&id=567079436225

4WD(4驱):

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.fff43961dgCABI&id=567173416961

2、STM32F103C8T6核心板

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.fff43961vbraDx&id=567200541464

3、PS2遥控器

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.15.fff43961KPX3S0&id=577723467175

4、L298N电机驱动模块

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.fff43961Oz8Sab&id=567173392291

5、18650电池

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.12.fff43961RsCgQd&id=577486077956

(5号充电电池)

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.12.fff43961dqhPEU&id=577324372710

6、18650电池座

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.437c3961h9AdcC&id=568450483270

(5号电池座,底盘自带)

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.fff43961dqhPEU&id=567280122150

7、杜邦线若干

https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-17409464480.9.fff43961ozUBpi&id=567071877141

二、硬件连接

基于STM32和PS2的遥控无线小车_第2张图片

 

三、程序源码

Main.c

#include "led.h"

#include "delay.h"

#include "sys.h"

#include "usart.h"  

#include "pstwo.h"

 

/*********************************************************

功能:通过PS2控制小车运动

作者:大海电子

时间:180531

硬件平台:STM32F103C8T6

时钟:8Mhz

 

硬件引脚分配:

//手柄接口

DI=PB12;

DO=PB13 ;

CS=PB14;

CLK=PB15;

 

//L298N 电机驱动控制引脚

IN1=PA0;    //左侧电机正  

IN2=PA1; //左侧电机负  

IN3=PA2;    //右侧电机正    

IN4=PA3; //右侧电机负

 

**********************************************************/  

#define go {IN1=1;IN2=0;IN3=0;IN4=1;}

#define back {IN1=0;IN2=1;IN3=1;IN4=0;}

#define stop {IN1=1;IN2=1;IN3=1;IN4=1;}

#define turnleft {IN1=1;IN2=1;IN3=0;IN4=1;}

#define turnright {IN1=1;IN2=0;IN3=1;IN4=1;}

 

 

 int main(void)

 {  

 u8 key=0;

delay_init();       //延时函数初始化   

NVIC_Configuration();  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(9600);   //串口初始化为9600

  LED_Init();      //LED端口初始化

PS2_Init();  

     

 

while(1)

{

 

key=PS2_DataKey();

 

 switch(key)

 {

 case 5:go;break;

 case 7:back;break;

 case 8:turnleft;break;

 case 6:turnright;break;

 

 default:stop;break;  

 }

if(key!=0)                   //有按键按下

     {

printf("%d  is  pressed  \r\n",key);

     }

// printf(" %5d %5d %5d %5d\r\n",PS2_AnologData(PSS_LX),PS2_AnologData(PSS_LY),

//                               PS2_AnologData(PSS_RX),PS2_AnologData(PSS_RY) );

       delay_ms(50);

}  

 }

 

 

pstwo.c

#include "pstwo.h"

#include "usart.h"

 

u16 Handkey;

u8 Comd[2]={0x01,0x42}; //开始命令。请求数据

u8 Data[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //数据存储数组

u16 MASK[]={

    PSB_SELECT,

    PSB_L3,

    PSB_R3 ,

    PSB_START,

    PSB_PAD_UP,

    PSB_PAD_RIGHT,

    PSB_PAD_DOWN,

    PSB_PAD_LEFT,

    PSB_L2,

    PSB_R2,

    PSB_L1,

    PSB_R1 ,

    PSB_GREEN,

    PSB_RED,

    PSB_BLUE,

    PSB_PINK

}; //按键值与按键明

 

//手柄接口初始化    输入  DI->PB12

//                  输出  DO->PB13    CS->PB14  CLK->PB15

void PS2_Init(void)

{

    //输入  DI->PB12

RCC->APB2ENR|=1<<3;     //使能PORTB时钟

GPIOB->CRH&=0XFFF0FFFF;//PB12设置成输入 默认下拉  

GPIOB->CRH|=0X00080000;   

 

    //  DO->PB13    CS->PB14  CLK->PB15

RCC->APB2ENR|=1<<3;    //使能PORTB时钟           

GPIOB->CRH&=0X000FFFFF;

GPIOB->CRH|=0X33300000;//PB13、PB14、PB15 推挽输出        

}

 

//向手柄发送命令

void PS2_Cmd(u8 CMD)

{

volatile u16 ref=0x01;

Data[1] = 0;

for(ref=0x01;ref<0x0100;ref<<=1)

{

if(ref&CMD)

{

DO_H;                   //输出以为控制位

}

else DO_L;

 

CLK_H;                        //时钟拉高

delay_us(50);

CLK_L;

delay_us(50);

CLK_H;

if(DI)

Data[1] = ref|Data[1];

}

}

//判断是否为红灯模式

//返回值;0,红灯模式

//   其他,其他模式

u8 PS2_RedLight(void)

{

CS_L;

PS2_Cmd(Comd[0]);  //开始命令

PS2_Cmd(Comd[1]);  //请求数据

CS_H;

if( Data[1] == 0X73)   return 0 ;

else return 1;

 

}

//读取手柄数据

void PS2_ReadData(void)

{

volatile u8 byte=0;

volatile u16 ref=0x01;

 

CS_L;

 

PS2_Cmd(Comd[0]);  //开始命令

PS2_Cmd(Comd[1]);  //请求数据

 

for(byte=2;byte<9;byte++)          //开始接受数据

{

for(ref=0x01;ref<0x100;ref<<=1)

{

CLK_H;

CLK_L;

delay_us(50);

CLK_H;

      if(DI)

      Data[byte] = ref|Data[byte];

}

        delay_us(50);

}

CS_H;

}

 

//对读出来的PS2的数据进行处理      只处理了按键部分         默认数据是红灯模式  只有一个按键按下时

//按下为0, 未按下为1

u8 PS2_DataKey()

{

u8 index;

 

PS2_ClearData();

PS2_ReadData();

 

Handkey=(Data[4]<<8)|Data[3];     //这是16个按键  按下为0, 未按下为1

for(index=0;index<16;index++)

{     

if((Handkey&(1<<(MASK[index]-1)))==0)

return index+1;

}

return 0;          //没有任何按键按下

}

 

//得到一个摇杆的模拟量  范围0~256

u8 PS2_AnologData(u8 button)

{

return Data[button];

}

 

//清除数据缓冲区

void PS2_ClearData()

{

u8 a;

for(a=0;a<9;a++)

Data[a]=0x00;

}

 

四、调试

  1. 若转动反向反了则说明电机正负或者左右反了,调整线和程序均可以解决。
  2. 建议使用18650锂电池供电,5号电池电压过低了些,若使用4驱方式,需要增加升压板,并且5号电池耗电很快。
  3. 上面的源码并非全部源码,简单的头文件等,LED及IO初始化等都为写入,如果需要完整的打开链接通过旺旺与我索要。

 

 

 

 

你可能感兴趣的:(硬件,嵌入式)