⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tx433.c

📁 nrf9e5带超时无线收发:从串口接收数据(靠超时判断而不是字节判断)
💻 C
字号:
/*******************************************
双机无线收发:
        将从串口接收到的字符发送出去。
串口接收靠超时判断,超过20ms就认为完成接收一个数据包,
开始无线发送。

P06闪烁表明超时判断完成,即一个数据包接收完毕;
P04闪烁表明无线发送数据成功。

修改:增加"串口接收数目超过缓冲区则重新计数"
******************************************/

#include <Nordic\reg9e5.h>

#define    HFREQ    0                               // 0=433MHz, 1=868/915MHz
#define    POWER    3                               // 0=min power...3 = max power
#define    UART_BUFFER_SIZE    10                   //串口接收缓冲区大小为 10 bytes,最大为31

unsigned char  UART_BUFFER[UART_BUFFER_SIZE+1];     //串口接收数据缓冲区
unsigned char  countt=0;                            //待发送数据个数

unsigned int  Tnum=400;                             //设定超时时间
bit    Overtime_Flag;                               //超时标志位


//延时函数
void Delay400us(volatile unsigned char n)
{
    unsigned char i;
    while(n--)
        for(i=0;i<35;i++)
            ;
}

//超时计时定时器T0初始化
void Time0_Init(void)
{
    TMOD &= 0xF0;          //定时器/计数器T0选为定时器模式,工作方式2,以TR0启动定时器
    TMOD |= 0x02;
    CKCON |= 0x08;         // T0M=1 (/4 timer clock)
    TH0=0x38;              //16MHz下定时时间为50us
    TL0=0x38;
    ET0=1;                 //允许定时器T0中断          
    TR0=1;                 //启动定时器T0
    Overtime_Flag=0;       //清超时标志
}

//定时器T0中断服务子程序
void Timer0_ISR (void) interrupt 1
{
     //TF0=0;                //响应中断后自动清0
     Tnum--;                 //计时20ms(中断次数计数)
     if(Tnum==0)             //超时20ms到?
      {
       TR0=0;               //关闭定时器T0
       Overtime_Flag=1;     //超时标志置1
       P06=~P06;              
      }
}

//串口接收中断函数 
void serial_ISR (void) interrupt 4
{
    if(RI)
      {
          unsigned char ch;          
          RI = 0;
          ch = SBUF;
          //TR0=1;
          if(Overtime_Flag==0)                //未超时就接收
           	 {								  //*********下面为修改***************
				if(countt==UART_BUFFER_SIZE)  //串口接收数目超过缓冲区则重新计数,缓冲区内数据会混乱
                        countt=0;
			    countt++;
                UART_BUFFER[0]=countt;
                UART_BUFFER[countt]=ch;
             }  
      }
    if(TI) 
      {
          //TI=0;
          return;
      }
}

//SPI读写
unsigned char SpiReadWrite(unsigned char b)
{
    EXIF &= ~0x20;                  // Clear SPI interrupt
    SPI_DATA = b;                   // Move byte to send to SPI data register
    while((EXIF & 0x20) == 0x00)    // Wait until SPI hs finished transmitting
           ;
    return SPI_DATA;
}

//无线发送
void Transmitter(unsigned char *str,unsigned char strlen)
{
    unsigned char j=0;
    TRX_CE=0;                   //待机模式
    //Delay400us(10);
    RACSN = 0;                  
    SpiReadWrite(WTP);          //将发送数据写入SPI寄存器
    for(j=0;j<strlen;j++)
      {
       SpiReadWrite(*(str + j)); 
      }
 
    RACSN = 1;
    TXEN = 1;
    TRX_CE = 1;              //使能发送
    Delay400us(2);
    TRX_CE = 0;              //发送完毕
    P04=~P04;
//    countt=0;
}

//初始化
void Init(void)
{
    unsigned char tmp,cklf,tmpa,tmpb;
    
    TH1 = 0xE6;                      // 9600@16MHz (when T1M=1 and SMOD=1)
    CKCON |= 0x10;                  // T1M=1 (/4 timer clock)
    PCON = 0x80;                    // SMOD=1 (double baud rate)
    SCON = 0x50;                    // Serial mode1, enable receiver
    TMOD = 0x20;                    // Timer1 8bit auto reload 
    TR1 = 1;                        // Start timer1  
//    P0_ALT |= 0x06;
//    P0_DIR |= 0x02;                 // P0.1 (RxD) is input
    tmpa= P0_ALT | 0x06;                 // Select alternate functions on pins P0.1 and P0.2
    P0_ALT = tmpa & 0x06;
    tmpb = P0_DIR | 0x02;                 // P0.1 (RxD) is input
    P0_DIR =tmpb & 0x02;

    SPICLK = 0;                     // Max SPI clock
    SPI_CTRL = 0x02;                // Connect internal SPI controller to Radio

    // Configure Radio:
    RACSN = 0;
    SpiReadWrite(WRC | 0x03);       // Write to RF config address 3 (RX payload)
    SpiReadWrite(0x01);             // One byte RX payload
    SpiReadWrite(0x01);             // One byte TX payload
    RACSN = 1;

    RACSN = 0;
    SpiReadWrite(RRC | 0x01);       // Read RF config address 1
    tmp = SpiReadWrite(0) & 0xf1;   //  PA_PWR[1:0]=00(输出电源-10dBm) HFREQ_PLL=0(433MHz)  Clear the power and frequency setting bits
    RACSN = 1;

    RACSN = 0;
    SpiReadWrite(WRC | 0x01);      // Write RF config address 1
    SpiReadWrite(tmp | (POWER <<2) | (HFREQ << 1));   // Change power defined by POWER and to 433 or 868/915MHz defined by HFREQ above:
    RACSN = 1;


    // Switch to 16MHz clock:
    RACSN = 0;
    SpiReadWrite(RRC | 0x09);
    cklf = SpiReadWrite(0) | 0x1c;
    RACSN = 1;
    RACSN = 0;
    SpiReadWrite(WRC | 0x09);
    SpiReadWrite(cklf);
    RACSN = 1;

    RACSN = 0;
    SpiReadWrite(WTA);             //写本发送器配套的接收器地址,与rx433里的配置一样才可通信
    SpiReadWrite(0x18);
    SpiReadWrite(0x32);
    SpiReadWrite(0x40);
    SpiReadWrite(0xAF);
    RACSN = 1;

    RACSN = 0;
    SpiReadWrite(WRC | 0x04);       //设置本发送器发送的数据宽度,与tx433里的配置一样才可通信
    SpiReadWrite(0x20);             //发送数据宽度为32个字节
    RACSN = 1;
}

void main(void)
{
    Init();
    Time0_Init();  //T0初始化
    EA=1;
    ES=1;
    //PT0=1;       //定时器T0为高优先级
   
    while(1)
     {
        if(Overtime_Flag)        //超时,将读到的数无线发送
        {
			ES=0;            
			//UART_BUFFER[0]=countt;
            if(countt != 0)     //缓冲区有接收到数据,开始发送
			       Transmitter(UART_BUFFER,(UART_BUFFER[0]+1));
            countt=0;  
            Overtime_Flag=0;    //复位超时标志 
			Tnum=400;
			TL0=0x38;           //重置超时计数器
			TR0=1;              //启动超时定时器
			ES=1;
        }         
    }  

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -