标题: 基于单片机的声控小车 [打印本页]
作者: 870855866 时间: 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;
}
}
*/
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |