基于合泰单片机无线鼠标智能小车控制.docx
《基于合泰单片机无线鼠标智能小车控制.docx》由会员分享,可在线阅读,更多相关《基于合泰单片机无线鼠标智能小车控制.docx(17页珍藏版)》请在冰豆网上搜索。
基于合泰单片机无线鼠标智能小车控制
#include"HT66FU70A.h"
#defineucharunsignedchar
#defineuintunsignedint
#defineled_pc2//led
//*********************************************NRF24L01端口宏定义*************************************
//#defineMOSI_pa3//MOSI
//#defineSCK_pa4//SCK
//#defineCE_pa5//CE
//#defineCSN_pa6//CSN
//#defineMISO_pa1//MISO输入
//#defineIRQ_pa7//IRQ输入
//*********************************************NRF24L01*************************************
#defineTX_ADR_WIDTH5//5字节宽度的发射地址
#defineRX_ADR_WIDTH5//5字节宽度的接收地址
#defineTX_PLOAD_WIDTH1//数据通道有效数据宽度
#defineRX_PLOAD_WIDTH1//数据通道有效数据宽度
ucharTX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//发送地址
ucharRX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址
uchargs[10]={0x00,0x01,0x80,0x01,0x00,0x02,0x80,0x02,0x00,0x03};//低字节高字节占空比数组1,83.3,66.7,50,33.3
//***************************************NRF24L01相关命令的宏定义*******************************************************
#defineREAD_REG0x00//读寄存器命令
#defineWRITE_REG0x20//写寄存器命令
#defineRD_RX_PLOAD0x61//读取接收数据命令
#defineWR_TX_PLOAD0xA0//写待发数据指令
#defineFLUSH_TX0xE1//冲洗发送FIFO指令
#defineFLUSH_RX0xE2//冲洗接收FIFO指令
#defineREUSE_TX_PL0xE3//定义重复装载数据命令
#defineNOP0xFF//?
?
//*************************************SPI(nRF24L01)相关地址的宏定义****************************************************
#defineCONFIG0x00
#defineEN_AA0x01
#defineEN_RXADDR0x02
#defineSETUP_AW0x03
#defineSETUP_RETR0x04
#defineRF_CH0x05
#defineRF_SETUP0x06
#defineSTATUS0x07
#defineOBSERVE_TX0x08
#defineCD0x09
#defineRX_ADDR_P00x0A
#defineRX_ADDR_P10x0B
#defineRX_ADDR_P20x0C
#defineRX_ADDR_P30x0D
#defineRX_ADDR_P40x0E
#defineRX_ADDR_P50x0F
#defineTX_ADDR0x10
#defineRX_PW_P00x11
#defineRX_PW_P10x12
#defineRX_PW_P20x13
#defineRX_PW_P30x14
#defineRX_PW_P40x15
#defineRX_PW_P50x16
#defineFIFO_STATUS0x17
//uucharTxBuf[2]={};
ucharRxBuf[1];
//**************************************
ucharsta;
ucharm=3;
unsignedcharIN1,IN2,IN3,IN4;//对应芯片如向前1000
voidpwn_1();
voidcar_qian();
voidcar_hou();
voidcar_zuo();
voidcar_you();
voidcar_stop();
voidtime_init();
voidCAR_Q();
voidCAR_H();
/************延迟函数ms************************/
voiddelay200ms(unsignedintx)
{
unsignedinti;
for(i=0;i{
GCC_DELAY(200000);
}
}
/**********小车控制函数***********************/
voidcar_qian()
{
_pcs2=0b00100000;//STM0C5pwm
_pcc5=0;
_pcpu5=1;
_pcs3=0b00000000;//STM0C60
_pcc6=0;
_pc6=0;
}
voidcar_hou()
{
_pcs2=0b00000000;//STM0C50
_pcc5=1;
_pcpu5=0;
_pcs3=0b00000001;//STM0C6pwm
_pcc6=0;
_pcpu6=1;
}
voidcar_zuo()
{
_pds0=0b00000001;//STM3D0pwm
_pdc0=0;
_pdpu=1;
_pds1=0b00000000;//STM3D30
_pdc3=0;
_pd3=0;
}
voidcar_you()
{
_pds0=0b00000000;//STM3D00
_pdc0=1;
_pdpu0=0;
_pds1=0b00010000;//STMD3pwm
_pdc3=0;
_pdpu3=1;
}
voidcar_stop()
{
_pcs2=0x00;
_pcs3=0x00;
_pds0=0x00;
_pds1=0x00;
_pcc6=0;
_pc6=0;
_pcc5=1;
_pcpu5=0;
_pdc0=1;
_pdpu0=0;
_pdc3=0;
_pd3=0;
}
voidcar_clear()//清楚上次位移端口影响
{
_pcs2=0x00;
_pcs3=0x00;
_pds0=0x00;
_pds1=0x00;
GCC_DELAY(20);
}
//******pwm占空比********
voidpwm_gs()
{
if(m>5){m=5;}
if(m<1){m=1;}
switch(m)
{
case1:
{_tm0al=0x00;_tm0ah=0x01;_tm3al=0x00;_tm3ah=0x01;break;}
case2:
{_tm0al=0x80;_tm0ah=0x01;_tm3al=0x80;_tm3ah=0x01;break;}
case3:
{_tm0al=0x00;_tm0ah=0x02;_tm3al=0x00;_tm3ah=0x02;break;}
case4:
{_tm0al=0x80;_tm0ah=0x02;_tm3al=0x80;_tm3ah=0x02;break;}
case5:
{_tm0al=0x00;_tm0ah=0x03;_tm3al=0x00;_tm3ah=0x03;break;}
}
GCC_DELAY(10);
time_init();
}
voidMcu_init()
{
_pas1=0x00;
_pac3=0;
_pas2=0x00;
_pac4=0;
_pas2=0x00;
_pac5=0;
_pas3=0x00;
_pac6=0;//pa3-6配置为输出io口无线模块配置
_pas0=0x00;
_pac1=1;
_papu1=1;
_pas3=0x00;
_pac7=1;
_papu7=1;
_pcs1=0x00;
_pcc2=0;
}
//写一个字节到nrf24l01,同时从nrf24l01读出一个字节
//*************************************************************************************
ucharSPI_RW(uchardata)
{
uchari,temp=0;
for(i=0;i<8;i++)//output8-bit
{
if((data&0x80)==0x80)
{
_pa3=1;//output'uuchar',MSBtoMOSI
}
else
{
_pa3=0;
}
data=(data<<1);//shiftnextbitintoMSB..
temp<<=1;
_pa4=1;//SetSCKhigh..
if(_pa1==1)temp++;//capturecurrentMISObitxiugaipa1
_pa4=0;//..thensetSCKlowagain
}
return(temp);//returnreaduuchar
}
//从reg寄存器读一个字节
//*************************************************************************************
ucharSPI_Read(ucharreg)
{
ucharreg_val;
_pa6=0;//CSNlow,initializeSPIcommunication...
SPI_RW(reg);//Selectregistertoreadfrom..
reg_val=SPI_RW(0);//..thenreadregistervalue
_pa6=1;//CSNhigh,terminateSPIcommunication
return(reg_val);//returnregistervalue
}
//写数据到reg寄存器
//*************************************************************************************
ucharSPI_RW_Reg(ucharreg,ucharvalue)
{
ucharstatus1;
_pa6=0;//CSNlow,initSPItransaction
status1=SPI_RW(reg);//selectregister
SPI_RW(value);//..andwritevaluetoit..
_pa6=1;//CSNhighagain
return(status1);//returnnRF24L01statusuuchar
}
//用于读数据
//*************************************************************************************
ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)
{
ucharstatus2,uuchar_ctr;
_pa6=0;//SetCSNlow,initSPItranaction
status2=SPI_RW(reg);//Selectregistertowritetoandreadstatusuuchar
for(uuchar_ctr=0;uuchar_ctr{
pBuf[uuchar_ctr]=SPI_RW(0);
}
_pa6=1;
return(status2);//returnnRF24L01statusuuchar
}
//用于写数据
//*************************************************************************************
ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)
{
ucharstatus1,uuchar_ctr;
_pa6=0;//SPI使能
status1=SPI_RW(reg);
for(uuchar_ctr=0;uuchar_ctr{
SPI_RW(*pBuf++);
}
_pa6=1;//关闭SPI
return(status1);
}
voidSetRX_Mode(void)
{
_pa5=0;
SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);//IRQ收发完成中断响应,16位CRC,主接收
_pa5=1;
GCC_DELAY(2000);//注意不能太小
}
ucharnRF24L01_RxPacket(uchar*rx_buf)
{
ucharrevale=0;
sta=SPI_Read(STATUS);//读取状态寄存其来判断数据接收状况
if(sta&0x40)//判断是否接收到数据
{
_pa5=0;//SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);//readreceivepayloadfromRX_FIFObuffer
revale=1;//读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);//接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
returnrevale;
}
//发送tx-buf中数据
/*************************************************************************************
voidnRF24L01_TxPacket(uuchar*tx_buf)
{
CE=0;
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);
CE=1;
delay_us(100);
}
*************************************************************************************/
voidinit_NRF24L01(void)
{
GCC_DELAY(250);
_pa5=0;//chipenable
_pa6=1;//Spidisable
_pa4=0;//Spiclocklineinithigh
SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写本地地址
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写接收端地址
SPI_RW_Reg(WRITE_REG+EN_AA,0x01);//频道0自动ACK应答允许
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG+RF_CH,0);//设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);//设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG+CONFIG,0x0E);//IRQ收发完成中断响应,16位CRC,主接收
}
voidtime_init(void)
{
//保持对应的I/O口的原来功能
_phs0=0;
_tm0c0=0x00;//增强型TM(查找TM1C0寄存器),4分频
//_tm0dl=0x00;
//_tm0dh=0x00;
_tm0c0=0b10010110;//7.784M停止不分频关闭100512P高三位本来应该8m实验测得7.784M
_tm0c1=0b10101000;//工作模式输出模式高有效同相向上计数(p匹配双pwm输出模式)
//_tm0c2=0b10101000;//工作模式输出模式高有效同相边沿对齐
//_tm0al=0x80;//a
//_tm0ah=0x02;//a
_tm0c0&=~(1<<7);//运行定时器
_tm0c0|=(1<<3);//计数器On
/*_tm0c0|=(1<<3);//计数器On*/
_tm3c0=0x00;//增强型TM(查找TM3C0寄存器)
//_tm3dl=0x00;
//_tm3dh=0x00;
_tm3c0=0b10010110;//7.784M停止不分频关闭100512P高三位本来应该8m实验测得7.784M
_tm3c1=0b10101000;//工作模式输出模式高有效同相向上计数(p匹配双pwm输出模式)
//_tm3al=0x80;//a
//_tm3ah=0x02;//a
_tm3c0&=~(1<<7);//运行定时器
_tm3c0|=(1<<3);//计数器On
/*计数值的上限是3FFH,这里取计数初值为356H,即每隔
(3FFH-356H)=169x1/(fsys/4)的时间触发一次中断*/
_mf0e=1;//允许多功能中断0,多功能中断包括TM中断(INTC1寄存器bit1位)
_emi=1;//开总中断
}
voidmain()
{
ucharnum,zuo,you,qian,hou;
num=0;zuo=0;you=0;qian=0;hou=0;
Mcu_init();
init_NRF24L01();
SetRX_Mode();
//设置看门狗除能(使能应为:
0b01010011)
_wdtc=0b10101011;
_tm0al=0x00;//a
_tm0ah=0x02;//a
_tm3al=0x00;//a
_tm3ah=0x02;//a
time_init();//定时器初始化
_emi=1;//开总中断
while
(1)
{
SetRX_Mode();
nRF24L01_RxPacket(RxBuf);
GCC_DELAY(10000);
if(nRF24L01_RxPacket(RxBuf))
{
num++;
if(RxBuf[0]==0x0a){zuo++;}
elseif(RxBuf[0]==0x0b){you++;}
elseif(RxBuf[0]==0x0c){qian++;}
elseif(RxBuf[0]==0x0d){hou++;}
elseif(RxBuf[0]==0x0e){m++;pwm_gs();}
elseif(RxBuf[0]==0x0f){m--;pwm_gs();}
if(num>=20)
{
num=0;
if(zuo>=11){zuo=0;car_zuo();delay200ms(10);car_clear();car_stop();}
if(you>=11){you=0;car_you();delay200ms(10);car_clear();car_stop();}
if(qian>=11){qian=0;car_qian();delay200ms(10);car_clear();car_stop();}
if(hou>=11){hou=0;car_hou();delay200ms(10);car_clear();car_stop();}
}
}
else
{
led=0;
}
}
}