找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2405|回复: 0
打印 上一主题 下一主题
收起左侧

基于单片机的声控小车

[复制链接]
跳转到指定楼层
楼主
ID:312454 发表于 2018-4-20 15:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include "nrf_rx.h"
#define uint unsigned int
#define uchar unsigned char
sbit ot1=P2^0;   //定义 ot1,ot2控制左轮;ot2,ot3控制右轮   ena为左轮pwm输出,enb为右轮pwm输出
sbit ot2=P2^1;
sbit ot3=P2^2;
sbit ot4=P2^3;
sbit ena=P1^3;
sbit enb=P1^4;
uint num1,k,b,t;         //pwm波标记
uint a,tm;
uint flag;
uchar ts;
extern uchar RX_Buffer[8];
void delayms(uint x)     //程序延时
{
   uint i,j;
   for(i=x;i>0;i--)
   for(j=110;j>0;j--);
}
void pwm0()                  //计时器中断
{
   TMOD=0x01;
   TH0=(65536-5000)/256;
   TL0=(65536-5000)%256;
   TH1=(65536-1000)/256;
   TL1=(65536-1000)%256;
   EA=1;
   ET0=1;
   ET1=1;     
}
void zhixing_h()         //高速直行转弯
{
   ot1=0;
   ot2=1;
   ot3=0;
   ot4=1;
   ena=1;
   enb=1;
   k=1;  
}
void zuozhuan_h()
{
   ot1=0;
   ot2=0;
   ot3=0;
   ot4=1;
   ena=1;
   enb=1;
   if(b==1)
   {  
   delayms(400);
   ot1=0;
   ot2=0;
   ot3=0;
   ot4=0;
   }
   else
   {
      TR1=1;
      tm=200;
   }
   a=0;
}
void youzhuan_h()
{
   ot1=0;
   ot2=1;
   ot3=0;
   ot4=0;
   ena=1;
   enb=1;
   if(b==1)
   {
   delayms(400);
   ot1=0;
   ot2=0;
   ot3=0;
   ot4=0;
   }
   else
   {
      TR1=1;
      tm=200;
   }
}
void diaotou()
{
   ot1=0;
   ot2=1;
   ot3=1;
   ot4=0;
ena=1;
   enb=1;
   if(b==1)
   {
      delayms(800);
      ot1=0;
      ot2=0;
      ot3=0;
      ot4=0;
   }
   else
   {     
       tm=600;
      TR1=1;
   }
}
void daoche_h()
{
   ot1=1;
   ot2=0;
   ot3=1;
   ot4=0;
   ena=1;
   enb=1;
   k=1;
}
void  stop()
{
   ot1=0;
   ot2=0;
   ot3=0;
   ot4=0;
   ena=0;
   enb=0;
}  
void direct()               //判断得到数据 快速直行转弯或慢速直行转弯
{  
   char c;  
   b=a/10;                    //提取a的第一位
   c=a%10;                 //提取a的第二位
   if(b==0)
   {
   ts=1;                 //调速标记
   }
   else
   {
      ts=0;
   }
    switch(c)                                 
   {  
   //a为一个2位数第一位1表示高速0表示低速,第二位代表所需要状态
      case 1:zhixing_h(); break;
      case 3:zuozhuan_h(); break;
      case 4:youzhuan_h(); break;
      case 6:diaotou(); break;
      case 2:daoche_h(); break;
      case 5:stop();break;
   }     
}
/*void bizhang()
{
   uint t=15;
   trige=1;
   while(t--);
   trige=0;
   while(!reback) ;
   TR1=1;
   while(reback)
   {
   if(TL1>10)      //17cm
   {
   t=0;
   TL1=0;
   break;
   }
   else
   {
      t=0;
      TL1=0;
      stop();
      break;
   }
   }  
}*/
/*
void main(void)
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
_delay_us(1000);
nRF24L01_Init();
while(1)
{
  nRF24L01_Set_RX_Mode();    //设置为接收模式
  _delay_ms(100);
  if(nRF24L01_RX_Data())     //判断是都接收到数据
  {
   LED=0;//如果有数据收到灯亮
   P0=RX_Buffer[0];
  }
  else//否则灯熄
   LED=1;
}
}
*/
    void main()
{
   P0=0xff;
   P1=0xff;
    P2=0xff;
    P3=0xff;
   EA=1;
    EX0=1;
    IT0=1;
   _delay_us(1000);
   nRF24L01_Init();
    nRF24L01_Set_RX_Mode();    //设置为接收模式
   while(1)
   {
       pwm0();  
       direct();
      a=0;
      while(a==0)
      {
           if(ts==1)         //ts等于1时需要调速  转弯调速时flag大于250转弯结束
         {  
      //if(k==1)              //此时计时器1空闲 小车处于运动状态
      //{
      //   bizhang();
      //}
         TR0=1;
         ena=1;
         enb=1;
            while(num1>2)
         {  
            ena=0;
            enb=0;
         }
         if(flag>tm)
         {
            ot1=0;
            ot2=0;
            ot3=0;
            ot4=0;
            ena=0;
            enb=0;
            flag=0;
            TR1=0;
        }     
      }
   }           
    }
}
void int0() interrupt 0   using 0
{
  char i;
  P2=0x50;
  for(i=0;i<3;i++)
  {
     nRF24L01_Set_RX_Mode();   //设置为接收模式
     _delay_ms(100);
     if(nRF24L01_RX_Data())     //判断是都接收到数据
     {
      LED=0;//如果有数据收到灯亮
      a=RX_Buffer[0];
      P0=RX_Buffer[0];
     }
     else//否则灯熄
     {
       LED=1;
     }
  }  
}
  
void time0() interrupt 1 using 1
{
   num1++;
   TH0=(65536-5000)/256;
   TL0=(65536-5000)%256;
   if(num1>20)
   {
   num1=0;
   }
   }
void time1() interrupt 3  using 2
{
   t++;
   if(t==400)
   {
   flag++;
   t=0;
   }
   TH1=(65536-100)/256;
   TL1=(65536-100)%256;
}
附录B:
#include <reg52.h>
#include <intrins.h>
#include "nrf_rx.h"
#define TX_ADDR_WITDH 5  //发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5   //接收地址宽度设置为5个字节
#define TX_DATA_WITDH 8   //发送数据宽度为8字节
#define RX_DATA_WITDH 8   //接收数据宽度为8字节
uchar  sta;    // 状态变量
#define RX_DR  (sta & 0x40)  // 接收成功中断标志
#define TX_DS  (sta & 0x20)  // 发射成功中断标志
#define MAX_RT (sta & 0x10)  // 重发溢出中断标志
uchar code TX_Addr[]={0x34,0x34,0x10,0x10,0x01};      //发送地址
uchar RX_Buffer[RX_DATA_WITDH];              //接收数据缓存
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
  for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
  for (i=0;i<120;i++);
}
void nRF24L01_Init(void)
{
_delay_us(2000);
CE=0;
CSN=1;
SCK=0;
// IRQ=1;
}
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
  if(byte&0x80)
   MOSI=1;
  else
   MOSI=0;
  byte<<=1;
  SCK=1;
  if(MISO)
   byte|=0x01;
  SCK=0;
}
return byte;
}
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return status;
}
uchar SPI_R_byte(uchar reg)
{
uchar status;
CSN=0;
SPI_RW(reg);
status=SPI_RW(0);
CSN=1;
return status;
}
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
  Dat_Buffer=SPI_RW(0);
}
CSN=1;
return reg_value;
}
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
  SPI_RW(TX_Dat_Buffer);
}
CSN=1;
return reg_value;
}
/**************************************************
函数:nRF24L01_Set_RX_Mode()
描述:
    这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void nRF24L01_Set_RX_Mode(void)
{
CE=0;//待机
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);   //写寄存器指令+发送节点地址+地址宽度
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);
//为了接收设备应答信号,接收通道0地址与发送地址相同
SPI_W_Reg(W_REGISTER+EN_AA,0x01);//auot ack           
//使能接收通道0自动应答
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);                 
//接收通道0接收使能
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0f);                 
//延时250+86us 自动重发15次
SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);            //设置接收数据宽度
SPI_W_Reg(W_REGISTER+RF_CH,0);                       
//设置信道
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);                  
// 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_W_Reg(W_REGISTER+CONFIG,0x0f);                    
// CRC使能,16位CRC校验,上电,接收模式
CE=1;
_delay_ms(5);
}
uchar nRF24L01_RX_Data(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);
if(RX_DR)   //如果接收成功
{
  CE=0;
  SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);  
//将数据读入接收缓存
  SPI_W_Reg(W_REGISTER+STATUS,0xff);   //清除状态标志
  CSN=0;
  SPI_RW(FLUSH_RX);     // 清除RX FIFO寄存器
  CSN=1;
  return 1;
}
else
  return 0;
}
/*
void main(void)
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
_delay_us(1000);
nRF24L01_Init();
while(1)
{
  nRF24L01_Set_RX_Mode();    //设置为接收模式
  _delay_ms(100);
  if(nRF24L01_RX_Data())     //判断是都接收到数据
  {
   LED=0;//如果有数据收到灯亮
   P0=RX_Buffer[0];
  }
  else//否则灯熄
   LED=1;
}
}
*/

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表