嵌入式 > 技术百科 > 详情

基于MSP430单片机驱动NRF24L01无线模块发送C语言程序

发布时间:2020-10-16 发布时间:
|
MCU:MSP430F16X系列,RF无线模块:NRF24L01,液晶显示:ST7920串行控制128*64液晶,发送数据是把4X4矩阵键盘对应的键值发送出去。IRQ是采用中断查询法,具体的可以参考下面代码:
//p4口为液晶屏

//p1口中断

//nRF24L01无线通信

//p5.0  csn    

//p5.1  mosi

//p5.3  sck

//p5.2  miso

//p1.2  irq

//p5.7  ce

//ST7920串行控制128*64液晶

//rst  p4.3   复位

//rs   p4.0   片选

//rw   p4.1    数据

//E    p4.2    时钟

#include 

#include 

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

#define LCD_CLK_1   (P4OUT |=  BIT2)

#define LCD_CLK_0   (P4OUT &=~ BIT2)


#define LCD_D_1   (P4OUT |=  BIT1)

#define LCD_D_0   (P4OUT &=~ BIT1)


#define LCD_RST_1  (P4OUT |=  BIT3)

#define LCD_RST_0  (P4OUT &=~ BIT3)


#define LCD_CS_1 (P4OUT |= BIT0)

#define LCD_CS_0 (P4OUT &= ~BIT0)


#define TMP121_CS_1 (P5OUT |= BIT7)

#define TMP121_CS_0 (P5OUT &= ~BIT7)


#define TMP121_CLK_1 (P5OUT |= BIT3)

#define TMP121_CLK_0 (P5OUT &= ~BIT3)


#define send_1 (P2OUT |= BIT0)

#define send_0 (P2OUT &= ~BIT0)

#define CPU_F ((double)1000000) // MCLK=1MHZ主频

#define Delayus_us(x) __Delayus_cycles((long)(CPU_F*(double)x/1000000.0))

#define Delayus_ms(x) __Delayus_cycles((long)(CPU_F*(double)x/1000.0))

#define Delayus_s(x) __Delayus_cycles((long)(CPU_F*(double)x/1.0))

uint  alldata[32],keyflg;

uchar char11[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

uchar busy='A',hang,lie,flash_flag,bostart;

uchar key0=0,key1='T',key2,boflg,flg,key2flg=0,tab1=1,newsflag1,newsflag2;

uchar key11,key12;

uint LCDL;

uchar tu[32][32]={0x00};

uint Rdata[8]={0},botu[98]={0x0000};


uchar Tx_Payload[32]={4,1,9};

uchar Tx_Address[5]={100,101,102,103,104};

void Delayus(ulong ilinshi)

{ ulong ii;

 for(ii=0;ii<=ilinshi;ii++)

 {

  key0=key0;

 }

}


#define nRF24L01_CE_1   (P5OUT|= BIT7)

#define nRF24L01_CE_0   (P5OUT&=~BIT7)

#define nRF24L01_CSN_1  (P5OUT|= BIT0)

#define nRF24L01_CSN_0  (P5OUT&=~BIT0)

#define nRF24L01_SCK_1  (P5OUT|= BIT3)

#define nRF24L01_SCK_0  (P5OUT&=~BIT3)

#define nRF24L01_MOSI_1 (P5OUT|= BIT1)

#define nRF24L01_MOSI_0 (P5OUT&=~BIT1)


//SPI Commands

#define nRF24L01_R_REGISTER    0x00

#define nRF24L01_W_REGISTER    0x20

#define nRF24L01_R_RX_PAYLOAD  0x61

#define nRF24L01_W_TX_PAYLOAD  0xA0

#define nRF24L01_FLUSH_TX      0xE1

#define nRF24L01_FLUSH_RX      0xE2

#define nRF24L01_REUSE_TX_PL   0xE3

#define nRF24L01_NOP           0xFF


//NRF24L01寄存器地址

#define nRF24L01_CONFIG        0x00

#define nRF24L01_EN_AA         0x01

#define nRF24L01_EN_RXADDR     0x02

#define nRF24L01_SETUP_AW      0x03

#define nRF24L01_SETUP_RETR    0x04

#define nRF24L01_RF_CH         0x05

#define nRF24L01_RF_SETUP      0x06

#define nRF24L01_STATUS        0x07

#define nRF24L01_OBSERVE_TX    0x08

#define nRF24L01_CD            0x09

#define nRF24L01_RX_ADDR_P0    0x0A

#define nRF24L01_RX_ADDR_P1    0x0B

#define nRF24L01_RX_ADDR_P2    0x0C

#define nRF24L01_RX_ADDR_P3    0x0D

#define nRF24L01_RX_ADDR_P4    0x0E

#define nRF24L01_RX_ADDR_P5    0x0F

#define nRF24L01_TX_ADDR       0x10

#define nRF24L01_RX_PW_P0      0x11

#define nRF24L01_RX_PW_P1      0x12

#define nRF24L01_RX_PW_P2      0x13

#define nRF24L01_RX_PW_P3      0x14

#define nRF24L01_RX_PW_P4      0x15

#define nRF24L01_RX_PW_P5      0x16

#define nRF24L01_FIFO_STATUS   0x17



void IO_Init(void)   //初始化端口

{

 P2SEL = 0;

 P3SEL = 0;

 P4SEL = 0;

 P4DIR|=0x0f;              //P4.0,1,2,3=OUT

 P4OUT|=0x0f;

 P2DIR=0xfd;              //P2.1=in    qita=OUT

 P3DIR&=0xf7;              //p3.3=in

}

void Init_Port1(void)   //P1.0、P1.1为中断,下降沿触发

{  

   P1SEL=0;                         //设置为普通I/O口功能

   P1DIR=0;                         //设置为输入方向

   P1IE=0;

   P1IES=0;                          

   P1IE|=BIT2;                           //打开中断允许

   P1IES|=BIT2;                          //下降沿触发

   P1IFG=0;                              //P1IES的切换可能使P1IFG置位,需清除

}



/*******************************************************************************/

//无线通信

void Init_nRF24L01_IO()

{

 nRF24L01_CE_0;

 nRF24L01_CSN_1;

 nRF24L01_SCK_0;

 nRF24L01_MOSI_0;

}

//NRF24L01的SPI写时序

void nRF24L01SpiWrite(unsigned char byte)

{

unsigned char i;

nRF24L01_SCK_0;

Delayus(1);

for (i=0;i<8;i++) // Setup byte circulation bits

{

if ((byte&BIT7)==BIT7) // Put DATA_BUF.7 on data line

nRF24L01_MOSI_1; //MOSI=1;

else

nRF24L01_MOSI_0; //MOSI=0;

nRF24L01_SCK_1; // Set clock line high

Delayus(2);

byte=byte<<1;

nRF24L01_SCK_0; // Set clock line low

Delayus(2);

}

Delayus(1);

}


//NRF24L01的SPI读时序

unsigned char nRF24L01SpiRead(void)

{

unsigned char i;

unsigned char temp=0;

nRF24L01_SCK_0;

Delayus(2);

for (i=0;i<8;i++) // Setup byte circulation bits

{

nRF24L01_SCK_1; // Set clock line high

Delayus(2);

temp=temp<<1; // Right shift DATA_BUF

if ((P5IN&BIT2==BIT2))

{temp|=1;} // Read data

nRF24L01_SCK_0; // Set clock line low

Delayus(2);

}

Delayus(2);

return temp;

}


//

void nRF24L01_Flush_TX_FIFO(void)//Clear TX FIFO

{

nRF24L01_CSN_1;

nRF24L01_CSN_0;

nRF24L01SpiWrite(nRF24L01_FLUSH_TX);

nRF24L01_CSN_1;

}



//

void nRF24L01_Flush_RX_FIFO(void)//Clear RX FIFO

{

nRF24L01_CSN_1;

nRF24L01_CSN_0;

nRF24L01SpiWrite(nRF24L01_FLUSH_RX);

nRF24L01_CSN_1;

}


//

void nRF24L01SpiWriteReg(unsigned char SpiCommand,unsigned char Content)

{

nRF24L01_CSN_1;

nRF24L01_CSN_0;

nRF24L01SpiWrite(SpiCommand);

nRF24L01SpiWrite(Content);

nRF24L01_CSN_1;

}


//

void nRF24L01_Set_Rx_Address(unsigned char RX_Address_Pipex,unsigned char *Address,unsigned char Length)//Local

//Address

{

unsigned char i=0;

nRF24L01_CSN_1;

nRF24L01_CSN_0;

nRF24L01SpiWrite(RX_Address_Pipex);

for(i=0;i>12;

hexdisp(f1);

f1=(f2&0x0f00)>>8;

hexdisp(f1);

f1=(f2&0xf0)>>4;

hexdisp(f1);

f1=f2&0x0f;

hexdisp(f1);

}

void liney(uchar x,uchar y,uchar l)  //在(x,y)向下开始显示长度为l(<=16)的竖线

{

 uchar l1,i;

 uint x1=0x00,x2=0x00,ix=x/16;

 l1=x-ix*16;

 if (l1<8)

 {

   x1=0x80>>l1;

 }

 else

 {

  x2=0x80>>(l1-8);

 }

 for (i=0;i>(l1+l2);

 x1=x1<>l1;

 x2=0xff<>(l2+l1-8);

 x2=x2<>l1;

 x2=0xff;

 }

else

 {

 l2=l1-8;

 x1=0x00;

 x2=0xff>>l2;

 }

 if(l+l1<=24)

 {

  l2=24-l-l1;

  x3=0xff<0;k--)

 {

   c^=a&0x0001;   //奇偶校验

   a=a>>1;

 }

 buffer=buffer|c;

 return buffer;

}
[page]
/******************************************************************/

//收发

void send_bit1()

{

 send_1;

 Delayus(500);

 send_0;

 Delayus(500);

}


void send_bit0()

{

 send_0;

 Delayus(1000);

}


void send_data()

{

  int k;

  ulong buffer2;

  buffer2=convert();

//     send_bit1();

//  Delayus(500);  

//  send_bit1();

 

 

  for(k=16;k>0;k--)//发送数据位

   {

     if(buffer2&0x01==0x01)

       send_bit1();

    else

       send_bit0();

       buffer2=buffer2>>1;

    }

}


void send_adrs(uint z)

{ int k;

 uint buffer1=z;

 for(k=16;k>0;k--)//发送地址位

   {

     if(buffer1&0x01==0x01)

       send_bit1();

    else

       send_bit0();

       buffer1=buffer1>>1;

    }

}


uint recieve_adrs()

{

 int k,a;

 uint buffer1=0x0000,b=0x0000;

 Delayus(250);

 for(k=32;k>0;k--)

   {

   alldata[k]=P2IN&0x02;

   Delayus(1000);

  }

for(k=32;k>16;k--)

   {

   a=alldata[k];

   a=a>>1;

   b=b|a;

   b=b<<15;

   buffer1=buffer1>>1;

   buffer1=buffer1|b;

  }

 return buffer1;

}

 



ulong recieve_data()

{

 int k,a;

 ulong buffer2=0x0000,b=0x0000;

for(k=16;k>0;k--)

   {

   a=alldata[k];

   a=a>>1;

   b=b|a;

   b=b<<15;

   buffer2=buffer2>>1;

   buffer2=buffer2|b;

  }

 return buffer2;

}


/*************************************************************************/

//显示数据

void print_tmp()

{

 ulong TEMP=0;

 int TEMPFLG=0;

 char TEMP1,TEMP2,TEMP3,TEMP4;

 TEMP = recieve_data()&0xfff8;

if(TEMP>0x8000)

{

  TEMP=TEMP>>3;

  TEMP=TEMP<<3;

  TEMP=0xffff-TEMP+1;

  TEMPFLG=1;

}

TEMP = TEMP*10;

TEMP = TEMP/128;

//    if( TEMP>35)

   //P1OUT &= ~BIT1;

//    Delayus_ms(700);

  TEMP1=char11[TEMP/1000];

  TEMP2=char11[TEMP%1000/100];

  TEMP3=char11[TEMP%100/10];

  TEMP4=char11[TEMP%10];

  if(TEMP1=='0')

  { if(TEMP2=='0')

    {

      if(TEMPFLG==1)

      writechar(0x90,'-');

      writechar(0x91,TEMP3);

      writechar(0x92,'.');

      writechar(0x93,TEMP4);

     }

    else

    {

     if(TEMPFLG==1)

     writechar(0x90,'-');

     writechar(0x91,TEMP2);

     writechar(0x92,TEMP3);

     writechar(0x93,'.');

      writechar(0x94,TEMP4);

    }

  }

  else

   

  {

    if(TEMPFLG==1)

   writechar(0x90,'-');

   writechar(0x91,TEMP1);

   writechar(0x92,TEMP2);

   writechar(0x93,TEMP3);

   writechar(0x94,'.');

   writechar(0x95,TEMP4);

  }

}

 


void print_light()

{

 ulong lgt;

 lgt=recieve_data()&0x0004;

 lgt=lgt>>2;

if(lgt)

   writechinese(0x98,"暗");

else

   writechinese(0x98,"亮");

}

void print_data()

{

 uchar num;

 num=char11[Tx_Payload[0]];

 writechar(0x90,num);

 num=char11[Tx_Payload[1]];

 writechar(0x91,num);

 num=char11[Tx_Payload[2]];

 writechar(0x92,num);

}


/********************************************************************************/

//键盘

void key_Init()

{

 P5SEL = 0;

 P6SEL = 0;

 P6DIR|=0xff;              //P6=OUT

 P5DIR=0x8b;              //P5.2、4、5、6=in,P5.0、1、3、7=out


}


void key_read()

{

 //第一排扫描

 P6OUT=0x18;

 Delayus(100);

 key0=P5IN&0x70 ;

  if (key0==0x30)

 {

   key11='1';

   if(keyflg==0)

   {

     CLEAR();

     writechinese(0x80,"单独探测节点");

     writechinese(0x90,"1-选择1#节点");

     writechinese(0x88,"2-选择2#节点");

     writechinese(0x98,"g-返回主菜单");

     keyflg=1;

   }

   else if(keyflg==1)

   {

     CLEAR();

     writechinese(0x80,"寻检1#节点");

     writechinese(0x90,"d-确认,g-返回");

     keyflg=2;

   }

   

   Delayus(30000);

 }

 

  if (key0==0x40)

 {

   key11='2';

   if(keyflg==0)

   {

     CLEAR();

     writechinese(0x80,"轮寻模式");

     writechinese(0x90,"d-确认,g-返回");

     keyflg=4;

   }

   if(keyflg==1)

   {

     CLEAR();

     writechinese(0x80,"寻检2#节点");

     writechinese(0x90,"d-确认,g-返回");

     keyflg=3;

   }

     

 Delayus(30000);

 }

  if (key0==0x50)

 {

 key11='3';

 Delayus(30000);

  }

  if (key0==0x60)

 {

 Delayus(30000);

  key11='4';

 }


//第二排扫描

 P6OUT=0x20;

 Delayus(100);

 key0=P5IN&0x70 ;

  if (key0==0x30)

 {

   key11='5';

   CLEAR();

   nRF24L01_TX_MODE();

   nRF24L01_Set_Rx_Address(nRF24L01_W_REGISTER+nRF24L01_RX_ADDR_P0,Tx_Address,5);

   writechinese(0x80,"正在发送");

   nRF24L01_Flush_TX_FIFO();

   nRF24L01_Set_Tx_Address(nRF24L01_W_REGISTER+nRF24L01_TX_ADDR,Tx_Address,5);// 指定接收方的地址

   nRF24L01_Write_Tx_Payload(Tx_Payload,3);//把1 字节数据放入FIFO

   nRF24L01_Transmit_Data();//启动发送,发送完成后进入Standby-I 模式

   print_data();

   

   

Delayus(30000);

   }


 

  if (key0==0x40)

 {

 key11='6';

Delayus(30000);

   }

  if (key0==0x50)

 {

 key11='7';

Delayus(30000);

   }

  if (key0==0x60)

 {

 key11='8';

 Delayus(30000);

  }


//第三排扫描

 P6OUT=0x28;

 Delayus(100);

 key0=P5IN&0x70 ;

  if (key0==0x30)

 {

 key11='9';

 Delayus(30000);

  }

 

  if (key0==0x40)

 {

 key11='A';

Delayus(30000);

   }

  if (key0==0x50)

 {

 key11='B';

 Delayus(30000);

  }

  if (key0==0x60)

 {

 key11='C';

Delayus(30000);

   }


  //第四排扫描

 P6OUT=0x30;

 Delayus(100);

 key0=P5IN&0x70 ;

  if (key0==0x30)

 {

 key11='D';

  if(keyflg==2)

 {

   CLEAR();

   writechinese(0x80,"发送1#节点请求");

   send_bit1();

   send_adrs(0x0001);

   _EINT();

   //发送1号节点请求

   

 }

 if(keyflg==3)

 {

   CLEAR();

   writechinese(0x80,"发送2#节点请求");

   send_bit1();

   send_adrs(0x0002);

   _EINT();

   //发送2号节点请求

 }

 if(keyflg==4)

 {

   CLEAR();

   writechinese(0x80,"发送1#节点请求");

   send_bit1();

   send_adrs(0x0001);

   keyflg=2;

 

   Delayus(20000);

   writechinese(0x80,"发送2#节点请求");

   send_bit1();

   send_adrs(0x0002);

   keyflg=3;

   _EINT();

 }

 Delayus(30000);

  }

 

  if (key0==0x40)

 {

 key11='E';

 Delayus(30000);

 }

  if (key0==0x50)

 {

 key11='F';

 Delayus(30000);

   }

  if (key0==0x60)

 {

 key11='G';

 CLEAR();

 writechinese(0x80,"江南大学");

 writechinese(0x90,"通信与控制工程");

 writechinese(0x88,"无线监测模拟装置");

 Delayus(100000);

 CLEAR();

 writechinese(0x80,"选择接受模式");

 writechinese(0x90,"1-单独探测节点");

 writechinese(0x88,"2-轮巡模式");

 keyflg=0;

 Delayus(30000);

 Init_nRF24L01_IO();

 }


}



void print1(ulong x)

{

ulong cvt0,cvt1;  

 int k,i;

 char data[10];

 cvt0=x;

   for(k=4,i=0;k>0;k--,i++)

   {

     cvt1=cvt0&0x000f;

     data[i]=char11[cvt1%16];

     cvt0=cvt0>>4;

   }

   

   writechar(0x90,data[3]);

   writechar(0x91,data[2]);

   writechar(0x92,data[1]);

   writechar(0x93,data[0]);

}



void main(void)

{

 WDTCTL=WDTPW+WDTHOLD;

  _DINT();

  Init_Port1();

  IO_Init();

  LCD_Init();

  CLEAR();

 

 key11='M';

// LCDL='安';

 //汉字显示示例

writechinese(0x80,"江南大学");

writechinese(0x90,"通信与控制工程");

writechinese(0x88,"无线监测模拟装置");

Delayus(100000);

CLEAR();

writechinese(0x80,"选择接受模式");

writechinese(0x90,"1-单独探测节点");

writechinese(0x88,"2-轮巡模式");

keyflg=0;

 bostart=0x00;

 boflg=0x00;

 key_Init();

 Init_nRF24L01_IO();

_EINT();

do

{

key11='w' ;

key_read();

}while(1);


}

#pragma vector=PORT1_VECTOR

__interrupt void P1_ISR(void)

{


 _DINT();

 P1IFG=0;

   P1IE=0;

   P1IES=0;

  Delayus(500);

  writechinese(0x88,"发送成功");

           

  IO_Init();

  Init_Port1();

  _EINT();

}
 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
用于MAX7456随屏显示器SPI