接收部分:
/*接收部分的硬件电路即为上图中的自制的avr开发板,采用1602显示*/
1)yj1602.h文件
#define uchar unsigned char #define uint unsigned int #include #define RS 4 #define RW 5 #define EN 6 #define PORT_CTL PORTA #define DDR_CTL DDRA #define DATA_PORT PORTC #define DATA_DDR DDRC #define DATA_PIN PINC uchar table[11]={"0123456789 "}; void s_ms(uint ms) { for(;ms>1;ms--); }
//查忙 void busy(void) { uchar temp; s_ms(500); PORT_CTL&=~(1< s_ms(500); PORT_CTL|=(1< s_ms(500); while(temp) { PORT_CTL|=(1< s_ms(500); DATA_DDR=0x00; //A口变输入 DATA_PORT =0xff; //上拉使能 s_ms(500); temp =DATA_PIN&0x80; //读取A口 s_ms(500); DATA_DDR=0xff; DATA_PORT =0xff; //A口变输出 s_ms(500); PORT_CTL&=~(1< s_ms(500); } }
//写指令 void writecom(uchar com) { busy(); s_ms(500); PORT_CTL&=~(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); PORT_CTL|=(1< s_ms(500); DATA_PORT = com; //输出指令 s_ms(500); PORT_CTL&=~(1< s_ms(500); }
//1602初始化 void LcdInit(void) { DATA_DDR=0xff; DATA_PORT=0xff; DDR_CTL|= ((1< PORT_CTL|= ((1<
writecom(0x38); s_ms(1000); writecom(0x01); s_ms(10000); s_ms(1000); s_ms(1000); s_ms(1000); s_ms(1000); s_ms(1000); s_ms(1000); writecom(0x02); s_ms(1000); writecom(0x06); s_ms(1000); writecom(0x0c); s_ms(1000); writecom(0x38); s_ms(1000); }
//写数据 void writedata(uchar data) { busy(); s_ms(500); PORT_CTL|=(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); PORT_CTL|=(1< s_ms(500); DATA_PORT= data; //输出数据 s_ms(500); PORT_CTL&=~(1< s_ms(500); }
//读数据 uchar readdata(void) { uchar temp; busy(); s_ms(500); PORT_CTL|=(1< s_ms(500); PORT_CTL|=(1< s_ms(500); PORT_CTL|=(1< s_ms(500); DATA_DDR=0x00; //A端口变输入 s_ms(500); temp = DATA_PIN; //读A端口 s_ms(500); DATA_DDR=0xff; //A端口变输出 s_ms(500); PORT_CTL&=~(1< s_ms(500); return temp; }
//================================================= // 描述: 写LCD内部CGRAM函数 // 入口: ‘num’要写的数据个数 // ‘pbuffer’要写的数据的首地址 // 出口: 无 //================================================ void WriteCGRAM(uint num, const uint *pBuffer) { uint i,t; writecom(0x40); PORT_CTL|=(1< PORT_CTL&=~(1< for(i=num;i!=0;i--) { t = *pBuffer; PORT_CTL|=(1< DATA_PORT = t; PORT_CTL&=~(1< pBuffer++; } }
//================================================= //描述:写菜单函数,本程序使用的LCD规格为 16 * 2 //入口:菜单数组首地址 //出口:无 //================================================= void WriteMenu(const uchar *pBuffer) { uchar i,t; writecom(0x80); //数据地址 PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50); for(i=0;i<16;i++) { t = *pBuffer; DATA_PORT = t; PORT_CTL|=(1< s_ms(50); PORT_CTL&=~(1< pBuffer++; } writecom(0xC0);
PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50); for(i=0;i<16;i++) { t = *pBuffer; DATA_PORT = t; PORT_CTL|=(1< s_ms(50); PORT_CTL&=~(1< pBuffer++; } } //==================================================== // 描述:在任意位置写数字函数 // 入口:’row‘表示要写数字所在的行地址,只能为1或2 // ’col‘表示要写数字所在的列地址,只能为0--15 // ‘num’表示要写的数字,只能为0--9 // 出口:无 //=================================================== void WriteNum(uchar row,uchar col,uchar num) { if (row == 1) row = 0x80 + col; else row = 0xC0 + col; writecom(row);
PORT_CTL|=(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); DATA_PORT = num; s_ms(500); PORT_CTL|=(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); } //================================================================ // 描述:在任意位置写任意多个字符 // 入口:’row‘要写的字符所在的行,只能为1或2; // ‘col’要写的字符所在的列,只能为0---15 // ‘num’要写字符的个数 // ‘pbuffer’要写字符的首地址 //================================================================== void WriteChar(uchar row,uchar col,uint num,uchar *pBuffer) { uchar i,t; if (row == 1) row = 0x80 + col; else row = 0xC0 + col; writecom(row);
PORT_CTL|=(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); for(i=num;i!=0;i--) { t = *pBuffer; s_ms(500); DATA_PORT = t; s_ms(500); PORT_CTL|=(1< s_ms(500); PORT_CTL&=~(1< s_ms(500); pBuffer++; } } uchar wz[]={""}; uchar gd[]={"Good Luck!"}; uchar dd1[]={"NRF 905 DEMO"}; uchar dd2[]={"the key is: "};
2)main.c文件:
//ICC-AVR application builder : 2010-5-20 // Target : M16 // Crystal: 8.0000Mhz #include #include #include "yj1602.h" #define uint unsigned int #define uchar unsigned char ///////////////////////////模式控制定义///////////////////////////////// //#define nrf905_TX_EN PB0 //输出1 #define Low_nrf905_TX_EN PORTB &= ~(1 << PB0) #define Hign_nrf905_TX_EN PORTB |= (1 << PB0) //#define nrf905_TRX_CE PD4 //输出1 #define Hign_nrf905_TRX_CE PORTD |= (1 << PD4) #define Low_nrf905_TRX_CE PORTD &= ~(1 << PD4) //#define nrf905_PWR PB1 //输出1 #define Hign_nrf905_PWR PORTB |= (1 << PB1) #define Low_nrf905_PWR PORTB &= ~(1 << PB1) //--------------------------------SPI口定义------------------------------------- //#define nrf905_MISO PB6 //输入0 //#define nrf905_MOSI PB5 //输出1 //#define nrf905_SCK PB7 //输出1 #define Low_nrf905_SCK PORTB &= ~(1 << PB7) //------------------------------------------------------------------------------ //#define nrf905_CSN PB4 //输出1 #define Hign_nrf905_CSN PORTB |= (1 << PB4) #define Low_nrf905_CSN PORTB &= ~(1 << PB4) //-------------------------------状态输出口------------------------------------- //#define nrf905_CD PD3 //输入0 #define Hign_nrf905_CD PORTD |= (1 << PD3) #define Low_nrf905_CD PORTD &= ~(1 << PD3) #define Read_nrf905_CD PINB & (1 << PD3) //#define nrf905_AM PB3 //输入0 #define Hign_nrf905_AM PORTB |= (1 << PB3) #define Low_nrf905_AM PORTB &= ~(1 << PB3) #define Read_nrf905_AM PINB & (1 << PB3) //#define nrf905_DR PB2 //输入0 #define Hign_nrf905_DR PORTB |= (1 << PB2) #define Low_nrf905_DR PORTB &= ~(1 << PB2) #define Read_nrf905_DR PINB & (1 << PB2)
//----------------------------------905-SPI指令--------------------------------- #define WC 0x00 #define RRC 0x10 #define WTP 0x20 #define RTP 0x21 #define WTA 0x22 #define RTA 0x23 #define RRP 0x24 //---------------------------------发送数据缓冲区------------------------------- uchar TxRxBuf[4]; //----------------------------------接收地址------------------------------------ uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc }; uchar tf;
//------------------------------------------------------------------------------ //----------------------------------寄存器配置---------------------------------- uchar RFConf[11]= { 0x00, //配置命令// 0x4c, //CH_NO,配置频段在430MHZ 0x0C, //输出功率为10db,不重发,节电为正常模式 0x44, //地址宽度设置,为4字节 0x04,0x04, //接收发送有效数据长度为4字节 0xCC,0xCC,0xCC,0xCC, //接收地址 0x58, //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振 }; //----------------------------------函数申明------------------------------------ void Delay(uint x); void Spi_initial(); uchar SpiReadSpiWrite(uchar DATA); void system_Init(void); void Config905(void); void TxPacket(uchar TxBUF[4]); void SetTxMode(void); void TX(void); void StartUART(void); void R_S_Byte(uchar R_Byte); //----------------------------------100us延时子程序----------------------------- void Delay(uint x) { uint i; while(x--) for(i=0;i<80;i++); } //----------------------------------SPI初始化----------------------------------- void Spi_initial() { //SPCR=0x50; //SPSR=0x00; SPCR = (1<} //---------------------------------SPI读写程序---------------------------------- uchar SpiReadSpiWrite(unsigned char cData)//r { SPDR = cData; while(!(SPSR & (1< {}; // 等待SPI发送完毕 return SPDR; } //---------------------------------系统状态初始化------------------------------- void system_Init(void) {
Hign_nrf905_CSN; // Spi disable Low_nrf905_SCK; // Spi clock line init low Low_nrf905_DR; // Init DR for input Low_nrf905_AM; // Init AM for input Low_nrf905_CD; // Init nrf905_CDfor input Hign_nrf905_PWR; // nRF905 power on Low_nrf905_TRX_CE; // Set nRF905 in standby mode Low_nrf905_TX_EN ; // set radio in Rx mode } //--------------------------------NRF905寄存器初始化函数------------------------ void Config905(void) { uchar i; Low_nrf905_CSN; Delay(1); // Spi enable for write a spi command //SpiWrite(WC); // Write config command写放配置命令 for (i=0;i<11;i++) // Write configration words 写放配置字 { SpiReadSpiWrite(RFConf[i]); } Hign_nrf905_CSN; // Disable Spi } //--------------------------------NRF905待发数据打包---------------------------- void TxPacket(uchar TxBUF[4]) { uchar i; Low_nrf905_CSN; // 使能Spi,允许对nrf905进行读写操作 Delay(1); SpiReadSpiWrite(WTP); // 写数据前先写写数据命令 for (i=0;i<4;i++) { SpiReadSpiWrite(TxBUF[i]); // 待发送的32字节数据 } Hign_nrf905_CSN; Delay(1); // 关闭Spi,不允许对nrf905进行读写操作 Low_nrf905_CSN; // 使能Spi SpiReadSpiWrite(WTA); // 写地址前首先先写地址命令 for (i=0;i<4;i++) // 写 4 bytes 地址 { SpiReadSpiWrite(TxAddress[i]); } Hign_nrf905_CSN; // 关闭Spi Hign_nrf905_TRX_CE; // Set TRX_CE high,start Tx data transmission Delay(1); // 等待DR变高 Low_nrf905_TRX_CE; // 设置TRX_CE=0 } //-------------------------------发送模式激发----------------------------------- void SetTxMode(void) { Low_nrf905_TRX_CE; // Hign_nrf905_TX_EN; //发送使能 Delay(2); // delay for mode change(>=650us)根据晶振不同要改变 } //------------------------------设置接收模式激发-------------------------------- void SetRxMode(void) { Low_nrf905_TX_EN; Hign_nrf905_TRX_CE; Delay(1000); // delay for mode change(>=650us) } //-----------------------------------读接收数据包------------------------------- void RxPacket(void) //读数据 { uchar i; Low_nrf905_TRX_CE; Low_nrf905_CSN; // 使能SPI Delay(1); SpiReadSpiWrite(RRP); // 写入数据接收缓冲区数据命令 for (i = 0 ;i < 4 ;i++) { TxRxBuf[i]=SpiReadSpiWrite(0); // 读取数据接收缓冲区数据 } Hign_nrf905_CSN; Delay(2); Hign_nrf905_TRX_CE; }
void RX_YJ1602(void) { SetRxMode(); //设置NRF905接收模式 RxPacket(); //读取接收数据缓冲区 Delay(10); dd2[11]=table[TxRxBuf[0]]; dd2[12]=table[TxRxBuf[1]]; dd2[13]=table[TxRxBuf[2]]; dd2[14]=table[TxRxBuf[3]]; WriteChar(2,1,15,dd2); } void port_init_905() { DDRD&=~(1<<3); //将905设置为接收状态 DDRD|=(1<<4); DDRB=0xB3; //将905设置为接收状态 } //------------------------------主函数------------------------------------------ void main(void) { uint i,j,temp[32]; port_init_905(); LcdInit(); Spi_initial(); system_Init(); Config905(); WriteChar(1,1,12,dd1); while(1) { RX_YJ1602(); } }
|