標題: 基于單片機的聲控小車 [打印本頁]
作者: 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://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |