在上一次用开发板做小车后 继续深入研究 把开发板换成了PCB 遥控器用两个模拟量摇杆,达到了玩小车的乐趣 , 又在原有的基础上增加了超声波数据回传,实现了数据收发,而且程序也有了很大的优化 ,速度变得更快了点,最重要的还是用了PCB ,买一些元器件就可以自己做电路,特别适合学生DIY,我也是用腐刻做板的,所以不用担心很复杂。直接附上图片吧。
制作出来的实物图如下:
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
nRF24L01无线发射检测:
1、将nRF24L01模块按照正确方向插到J11端子上;
2、MINI USB连接线给开发板通电下载程序,下载软件中内部IRC时钟选择11.0592MHZ;
3、下载程序后,开发板蓝色指示灯会不停闪烁,表示无线发送正常;
4、此时,如果有下发接收程序的开发板,则可以观察到有表示接收到的红色指示灯闪烁。
注:该实验需要配合接收实验进行。
nRF24L01无线接收实验:
1、将nRF24L01模块按照正确方向插到J11端子上;
2、MINI USB连接线给开发板通电下载程序,下载软件中内部IRC时钟选择11.0592MHZ;
3、下载程序后,开发板红色指示灯会常亮,表示没有接收到无线信号;
4、此时,如果有下发发送程序的开发板,则可以观察到该接收板上的红色指示灯闪烁。
注:该实验需要配合发送实验进行。
单片机源程序如下:
- /****************************************Copyright (c)****************************************************
- **
- **
- **
- **--------------File Info---------------------------------------------------------------------------------
- ** File name:
- ** Last modified Date:
- ** Last Version:
- ** Descriptions:
- **--------------------------------------------------------------------------------------------------------
- ** Created by: FiYu
- ** Created date: 2018-2-1
- ** Version: 1.0
- ** Descriptions: nRF24L01无线发射程序(硬件SPI)
- **--------------------------------------------------------------------------------------------------------
- ** Modified by: FiYu
- ** Modified date:
- ** Version:
- ** Descriptions:
- ** Rechecked by:
- **********************************************************************************************************/
- /****-----请阅读ReadMe.txt进行实验-----***********/
- #include "STC8.H"
- #include "oled.h"
- #include "intrins.h"
- #include "delay.h"
- #include "ADC.h"
- #include "NRF24L01.h"
- #include "timer.h"
- bit ZF,CJ=0;
- bit kaiqi=0;
- sbit Rled=P0^7;
- sbit Gled=P0^6;
- sbit Bled=P0^5;
- extern bit TIM,JS ;
- extern bit LEDK;
- extern uint8 RxPayload[6]; //无线接收缓存
- extern uint8 TxPayload[6]; //无线发送缓存
- extern uint8 S2;
- void moter(uint8 zf,uint8 SD) ; // 电机驱动函数
- void CSZX(uint16 y);
- void INT0_init(); //外部中断0的初始化配置
- void INT1_init();
- void led(bit x,bit y,bit z);
- void OLEDXS(void);
- void INT0_int (void) interrupt 0
- {
-
- delay_ms(150);
- if(P3^2==0)
- {
- kaiqi=~kaiqi;
- }
-
- }
- void INT1_int (void) interrupt 2
- {
- delay_ms(150);
- if(P3^3==0){CJ=~CJ;}
- }
- /***************************************************************************
- * 描 述 : 主函数
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************/
- int main()
- {
- uint16 n1=0;
- bit M1=1;
- TxPayload[0] = 0x5A;
- TxPayload[3] = 0xA5;
- OLED_Init() ;
- delay_ms(20);
- OLEDXS();
- Init_NRF24L01_MA(); //初始化
- Set_TxMode_MA(); //配置nRF24L01为发送模式
- delay_ms(20);
- INT0_init();
- INT1_init();
- Timer1Init();
- EA=1;
- ADC_config();
- while(1)
- {
- if(CJ==0&&kaiqi==0){led(1,1,1); led(0,1,1);Set_TxMode_MA(); //第0模式 发送停止不接受
- while(CJ==0&&kaiqi==0){
- ADC1(); //读取AD的值
- ADC2();
- if(kaiqi==0&&LEDK==1)
- {
- Rled=~Rled;
- TxPayload[0] = 0x5A;
- TxPayload[1] = 50;
- TxPayload[2] = 50;
- TxPayload[3] = 0xA5;
- TxPayload[4] = 0;
- NRF24L01_TxPacket_MA(TxPayload); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+1); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+2); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+3); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+4); //发送启动标志位
- LEDK=0;
- }
- }
- }
-
- if(kaiqi==0&&CJ==1){led(1,0,1); //第1模式 接收和发送停止信号
- while(CJ==1&&kaiqi==0){
- if(JS==1){Set_TxMode_MA();
- while(JS){ led(1,0,1);
- ADC1(); //读取AD的值
- ADC2();
- TxPayload[1] = 50;
- TxPayload[2] = 50;
- TxPayload[4] = 1;
-
- NRF24L01_TxPacket_MA(TxPayload); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+1); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+2); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+3); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+4); //发送启动标志位
- CSZX(70+20*TxPayload[1]/50); //使控制超声波的舵机转到中间位置
-
- if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED显示控制电机的PWM值 这里最大是80,可以修改到90以上,但不能是100,因为AD的波动值会直接超过一百
- else if(TxPayload[2]<52) moter(2,0); //防止AD波动造成误启动
- else moter(1,(TxPayload[2]-52)*80/45); //正转PWM值
- }
- }
- if(JS==0){ Set_RxMode_MA();
- while(!JS){
- if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK) //如果接收成功
- {
- if(RxPayload[0] == 0x04) //检验校验码
- {
- while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK)); //等待接收数据
- while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK)); //等待接收数据
- while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK)); //检验校验码
- }
-
- if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 ) //符合校验码的值 ,则中间的数据是正确的,不然乱码,错位的数据就不对
- {
- n1= RxPayload[1]*256+RxPayload[2];
- if(n1>=4000) LCD_P8x16Str(64, 6,"---.-");
- if(n1/1000==0) OLED_ShowChar(64,6,' ');
- else OLED_ShowChar(64,6,' '+16+n1/1000);
- OLED_ShowChar(72,6,' '+16+n1%1000/100);
- OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
- OLED_ShowChar(88,6,'.');
- OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
- RxPayload[0] = 0;
- RxPayload[1] = 0;
- RxPayload[2] = 0;
- RxPayload[3] = 0;
- }
- }
- }
- }
- }
- }
-
- if(kaiqi==1&&CJ==0){ led(1,1,1); led(1,1,0); //第二模式 只发送不接收
- Set_TxMode_MA();
- while(CJ==0&&kaiqi==1){
- ADC1(); //读取AD的值
- ADC2();
- TxPayload[4] =2;
- NRF24L01_TxPacket_MA(TxPayload); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+1); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+2); //发送数据
- NRF24L01_TxPacket_MA(TxPayload+3); //发送校验码
- NRF24L01_TxPacket_MA(TxPayload+4); //发送启动标志位
-
- CSZX(70+20*TxPayload[1]/50); //使控制超声波的舵机转到中间位置
- if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED显示控制电机的PWM值 这里最大是80,可以修改到90以上,但不能是100,因为AD的波动值会直接超过一百
- else if(TxPayload[2]<52) moter(2,0); //防止AD波动造成误启动
- else moter(1,(TxPayload[2]-52)*80/45); //正转PWM值
- }
- }
- if(kaiqi==1&&CJ==1){led(1,1,1);}
- //if(kaiqi==1&&CJ==1){led(1,1,1); //第3模式 接收和发送
- // while(CJ==1&&kaiqi==1){
- //
- // if(JS==1){Set_TxMode_MA();
- // while(JS){led(0,0,0);
- // TxPayload[4] = 3;
- // ADC1(); //读取AD的值
- // ADC2();
- // NRF24L01_TxPacket_MA(TxPayload); //发送校验码
- // NRF24L01_TxPacket_MA(TxPayload+1); //发送数据
- // NRF24L01_TxPacket_MA(TxPayload+2); //发送数据
- // NRF24L01_TxPacket_MA(TxPayload+3); //发送校验码
- // NRF24L01_TxPacket_MA(TxPayload+4); //发送启动标志位
- // CSZX(70+20*TxPayload[1]/50); //使控制超声波的舵机转到中间位置
- //
- // if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED显示控制电机的PWM值 这里最大是80,可以修改到90以上,但不能是100,因为AD的波动值会直接超过一百
- // else if(TxPayload[2]<52) moter(2,0); //防止AD波动造成误启动
- // else moter(1,(TxPayload[2]-52)*80/45); //正转PWM值
- // }
- //
- // if(JS==0){ Set_RxMode_MA(); led(1,1,1);
- // while(!JS){
- // if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK) //如果接收成功
- // {
- // if(RxPayload[0] == 0x04) //检验校验码
- // {
- // while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK)); //等待接收数据
- // while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK)); //等待接收数据
- // while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK)); //检验校验码
- // }
- //
- // if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 ) //符合校验码的值 ,则中间的数据是正确的,不然乱码,错位的数据就不对
- // {
- // n1= RxPayload[1]*256+RxPayload[2];
- // if(n1>=5500) LCD_P8x16Str(56, 6,"---.-");
- // if(n1/1000==0) OLED_ShowChar(64,6,' ');
- // else OLED_ShowChar(64,6,' '+16+n1/1000);
- // OLED_ShowChar(72,6,' '+16+n1%1000/100);
- // OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
- // OLED_ShowChar(88,6,'.');
- // OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
- // RxPayload[0] = 0;
- // RxPayload[1] = 0;
- // RxPayload[2] = 0;
- // RxPayload[3] = 0;
- // }
- // }
- // }
- // }
- // }
- // }
- // }
- }
- }
- void led(bit x,bit y,bit z)
- {
- Rled=x;
- Gled=y;
- Bled=z;
- }
- void OLEDXS(void)
- { uint8 i;
- LCD_P8x16Str(56, 2,"X:"); //2.4G模块用了SPI,所以OLED用IIC显示
- LCD_P8x16Str(0, 2,"Y:");
- for(i=0;i<8;i++) //遥控小车——发射
- {
- LCD_P16x16Ch(i*16,0,i);
- };
-
- for(i=8;i<11;i++)
- {
- LCD_P16x16Ch(i*16-16*8,4,i); //转向角 控制小车转向的舵机
- };
-
- LCD_P8x16Str(48, 4,":");
- LCD_P8x16Str(80, 4,"'C");
- LCD_P8x16Str(0, 6,"PWMY:");
- LCD_P8x16Str(104, 6,"CM");
- }
- void moter(uint8 zf,uint8 SD) // 电机驱动函数
- { uint8 sudu,i;
- sudu=SD;
- ZF=zf;
-
- OLED_ShowChar(40,6, ' '+16+sudu%100/10);
- OLED_ShowChar(48,6, ' '+16+sudu%100%10);
-
- if(zf<1)
- {
- for(i=13;i<15;i++) //反转
- {
- LCD_P16x16Ch(i*16-16*7,2,i);
- }
- }
- else if(zf<2) //正转
- {
- for(i=11;i<13;i++)
- {
- LCD_P16x16Ch(i*16-16*5,2,i);
- };
- }
- else {
- for(i=15;i<17;i++) //停转
- {
- LCD_P16x16Ch(i*16-16*9,2,i);
- }
- }
-
-
-
- }
- void CSZX(uint16 y) //超声波初值显示函数 ,没加可屏蔽
- {
- uint8 yy;
- yy=y;
-
- OLED_ShowChar(56,4,' '+16+yy/100);
- OLED_ShowChar(64,4,' '+16+yy%100/10);
- OLED_ShowChar(72,4,' '+16+yy%100%10);
-
- }
- void INT0_init() //外部中断0的初始化配置
- {
- IE0 = 0; //将INT0中断请求标志位清"0"
- EX0 = 1; //使能INT0中断允许位
- IT0 = 1; //选择INT0为上升沿或下降沿触发方式 1为下降沿,0为上升沿
- }
- void INT1_init()
- {
- //外部中断1的初始化配置
- IE1 = 0; //将INT1中断请求标志位清"0"
- EX1 = 1; //使能INT1中断允许位
- IT1 = 1; //选择INT1为下降沿触发方式 1为下降沿,0为上升沿
- }
复制代码
所有资料51hei提供下载:
PCB 图.zip
(55.86 KB, 下载次数: 77)
遥控小车PCB版.zip
(4.38 MB, 下载次数: 107)
|