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

📄 main.cpp

📁 射频芯片nRF905例程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

//inline
void UartObj::puthex(signed short val)
{
char str[9];
  BinToHex(val, str);
  putstr(str);//
}

//static
const unsigned char BintHexTab[16] = {
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};

//inline
void UartObj::BinToHex(unsigned char val, char str[])
{
  str[0] = BintHexTab[val >> 4];
  str[1] = BintHexTab[val & 0x0f];
  str[2] = 0;
}

//inline
void UartObj::BinToHex(unsigned short val, char str[])
{
  str[0] = BintHexTab[val >> 12];
  str[1] = BintHexTab[(val >> 8) & 0x0f];
  str[2] = BintHexTab[(val >> 4) & 0x0f];
  str[3] = BintHexTab[val & 0x0f];
  str[4] = 0;
}


//inline
void UartObj::BinToHex(signed short val, char str[])
{
  str[0] = BintHexTab[val >> 28];
  str[1] = BintHexTab[(val >> 24) & 0x0f];
  str[2] = BintHexTab[(val >> 20) & 0x0f];
  str[3] = BintHexTab[(val >> 16) & 0x0f];
  str[4] = BintHexTab[(val >> 12) & 0x0f];
  str[5] = BintHexTab[(val >> 8) & 0x0f];
  str[6] = BintHexTab[(val >> 4) & 0x0f];
  str[7] = BintHexTab[val & 0x0f];
  str[8] = 0;
}




RtcObj::RtcObj(void){
  RtcInit();//rtc初始化 
}

void RtcObj::RtcInit(void){
  POWER->P_CONP |= (1 << PCRTC);
  RTC->RTC_CCR = 0; 
  RTC->RTC_CIIR = (1 << IMSEC);				    // 设置秒值的增量产生一次中断
  RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF);	// 清除RTC增量和报警中断标志
  RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC);				        // 启动RTC
  if (SystemRamTest != SystemRamTestVal) {//RAM真正掉电后才清除时钟!!!
  }
}


/*----------------------------------------------------------------------------------------
                                0000年~9999年星期算法
-----------------------------------------------------------------------------------------*/
unsigned int RtcObj::GetDow(unsigned int y, unsigned int m, unsigned int d)
{
unsigned int w, c;
  if (m <= 2){
    m |= 4;//1月2月同5月六月表
    y--;
  }
  c = y / 100;
  c &= 0x03;//百年%4
  y %= 100;
  w = ((c | (c << 2)) + (y + (y >> 2)) + (13 * m + 8)/ 5 + d) % 7;//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7
  return w;//返回星期
}

/*----------------------------------------------------------------------------------------
                                0000年~9999年月最大天数算法
-----------------------------------------------------------------------------------------*/
unsigned int RtcObj::GetDom(unsigned int y, unsigned int m)
{
unsigned int dn;
  dn = GetDow(y, m + 1, 1) - GetDow(y, m, 1);//m+1=13表示明年的1月
  if (dn >= 0x80) dn += 7;
  return dn + 28;//返回当月的最大天数
}

nRFObj::nRFObj(void)
{
  SpiInit();
  nRFInit();
}

void nRFObj::nRFInit(void)
{
  PINSEL->PIN_SEL0 |= (P0_15_EINT2 << P0_15_PINSEL); //设置I/O连接到EINT2
  nRFPORT->IODIR |= (__1 << nRF_CS) | (__1 << PWR_UP) | (__1 << TX_EN) | (__1 << TRX_CE);
  nRFPORT->IOSET  = (__1 << nRF_CS) | //关闭SPI
                    (__1 << PWR_UP);  //nRF905上电
  nRFPORT->IOCLR  = (__1 << TRX_CE) | //设置nRF905为待机方式
                    (__1 << TX_EN);   //设置接收方式

  INTCON->EXT_POLAR |= (1 << EXTPOLAR2); //INT2为高电平有效

  INTCON->EXT_MODE |= (1 << EXTMODE2); //设置INT2为边沿触发
  WritenRFConfig(0);
  SetRxMode();//设置接收模式
}

void nRFObj::SpiInit(void)
{
  POWER->P_CONP |= (1 << PCSPI0);
  PINSEL->PIN_SEL0 |= ((P0_4_SCK0 << P0_4_PINSEL) | (P0_5_MISO0 << P0_5_PINSEL) | (P0_6_MOSI0 << P0_6_PINSEL));
  SPI->SPI_SPCCR = 0x52;		        // 设置SPI时钟分频
  SPI->SPI_SPCR  = (0x08 << 8) | 
            (0 << CPHA) |				// CPHA = 0, 数据在SCK 的第一个时钟沿采样
  		    (0 << CPOL) |				// CPOL = 0, SCK 为低有效
 		    (1 << MSTR) |				// MSTR = 1, SPI 处于主模式
 		    (0 << LSBF) |				// LSBF = 0, SPI 数据传输MSB (位7)在先
 		    (0 << SPIE);				// SPIE = 0, SPI 中断被禁止
}

unsigned char nRFObj::SpiReadWrite(unsigned char cData)
{
  SPI->SPI_SPDR = cData;                        //发送数据(相当于51的SBUF = DATA)
  while(!(SPI->SPI_SPSR & (1 << SPIF)));		// 等待SPIF置位,即等待数据发送完毕
  cData = SPI->SPI_SPDR;
  return cData;  
}

unsigned char nRFObj::ReadStatus(void)
{
unsigned char val;
  nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
  val = SpiReadWrite(RC);//读状态
  nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
  return val;//返回nRF905状态字
}

void nRFObj::SetTxMode(void)//设置发送模式
{
  __nop();///
  __nop();///
  __nop();///
  nRFPORT->IOSET  = (__1 << TX_EN);
///  __nop();///???5*11.0592M需要以下几个__nop()
  _delay_loop_(1);
/*
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
*/
  nRFPORT->IOCLR  = (__1 << TRX_CE);//设置nRF905为待机方式
///  _delay_loop_(10);
//650uS
  __nop();///
  __nop();///
  __nop();///
}

void nRFObj::SetRxMode(void)//设置接收模式
{
  __nop();
  __nop();
  __nop();
  nRFPORT->IOCLR  = (__1 << TX_EN);
  __nop();
///  _delay_loop_(1);
  nRFPORT->IOSET  = (__1 << TRX_CE);
///  _delay_loop_(10);
//650uS
  __nop();
  __nop();
  __nop();
}

void nRFObj::StartTx(void)
{
  __nop();
  __nop();
  __nop();
///  _delay_loop_(1);
  nRFPORT->IOSET  = (__1 << TRX_CE);
///  _delay_loop_(10);
  __nop();
  __nop();
  __nop();
/*
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
  __nop();
*/
  nRFPORT->IOCLR  = (__1 << TRX_CE);
///  _delay_loop_(1);
  __nop();
  __nop();
  __nop();
}


void nRFObj::WritenRFConfig(unsigned int nRFAddr)//配置nRF905
{
  nRFPORT->IOCLR  = (__1 << TRX_CE);//设置nRF905为待机方式
  __nop();
  nRFPORT->IOCLR |= (__1 << nRF_CS);
  SpiReadWrite(WC);				// Write config command
  SpiReadWrite(CH_NO_BYTE);                       //中心频率低8位
  SpiReadWrite(PA_PWR_10dBm | HFREQ_PLL_433MHz); //发射+10dBm,发射频率433MHz,中心频率第9位=0
  SpiReadWrite(TX_AFW_4BYTE | RX_AFW_4BYTE);     //接收地址宽度4字节,发送地址宽度4字节
  SpiReadWrite(RX_PW_32BYTE);                    //接收数据宽度32字节
  SpiReadWrite(TX_PW_32BYTE);                    //发送数据宽度32字节
  SpiReadWrite((nRFAddr >> 24) & 0xff);                       //接收有效地址第1字节
  SpiReadWrite((nRFAddr >> 16) & 0xff);                       //接收有效地址第2字节
  SpiReadWrite((nRFAddr >> 8) & 0xff);                       //接收有效地址第3字节
  SpiReadWrite(nRFAddr & 0xff);                       //接收有效地址第4字节
  SpiReadWrite(CRC16_EN | XOF_16MHz);            //CRC16模式使能,晶体振荡器频率16MHz
  nRFPORT->IOSET |= (__1 << nRF_CS);
  if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
    nRFPORT->IOCLR  = (__1 << TRX_CE);
  }
  else {
    nRFPORT->IOSET  = (__1 << TRX_CE);
  }
}

void nRFObj::nRFReadBuffers(void)//收发无线读写模块
{
  SetRxMode();//设置接收模式
  if (!(nRFPORT->IOSET & (__1 << TX_EN))) {//在接收状态
    if ((nRFPORT->IOPIN & (1 << nRF_CD)) || (nRFPORT->IOPIN & (1 << nRF_AM))) {//正确收到数据
      nRFPORT->IOCLR  = (__1 << TRX_CE);//设置nRF905为待机方式
      __nop();
///      _delay_loop_(1);
      nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
      SpiReadWrite(RRP);
	  for (int i = 0; i < 32; i ++) {
	    nRFRxBuff[i] = SpiReadWrite(0xff);
	  }
      nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
	  nRFRxCount = 32;//接收到32个字节的数据
///      _delay_loop_(1);
      if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
        nRFPORT->IOCLR  = (__1 << TRX_CE);
      }
      else {
        nRFPORT->IOSET  = (__1 << TRX_CE);
      }
	  os_evt_set (3888, Lcd_Task);
    }
  }
}

void nRFObj::nRFWriteBuffers(void)//收发无线读写模块
{
  nRF.SetTxMode();//设置发送模式  
  if (nRFPORT->IOSET & (__1 << TX_EN)) {//在发送状态
    if (!((nRFPORT->IOPIN & (1 << nRF_CD)) || (nRFPORT->IOPIN & (1 << nRF_AM)))) {
      nRFPORT->IOCLR  = (__1 << TRX_CE);//设置nRF905为待机方式
      __nop();
///      _delay_loop_(1);
      nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
      SpiReadWrite(WTA);//写发送地址
	  for (int i = 0; i < 4; i ++) {
	    SpiReadWrite( nRFTxBuff[i]);
	  }
      nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
	  __nop();
///      _delay_loop_(1);
      nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
      SpiReadWrite(WTP);// Write payload command
	  for (int i = 0; i < 32; i ++) {
	    SpiReadWrite( nRFTxBuff[i]);
	  }
      nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
///      _delay_loop_(1);
	  nRFTxCount = 32;//接收到32个字节的数据
      if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
        nRFPORT->IOCLR  = (__1 << TRX_CE);
      }
      else {
        nRFPORT->IOSET  = (__1 << TRX_CE);
      }
    }
  }
}

void MainTask (void) __task {
//  Uart.puts("12345678");
//  tmr1 = os_tmr_create (10, 1);
  Main_Task = os_tsk_self ();
  os_tsk_prio_self(3);
  Key_Task = os_tsk_create (KeyTask, 10);//创建KeyTask任务及级别
  Beep_Task = os_tsk_create (BeepTask, 100);//10创建BeepTask任务及级别
  Rtc_Task = os_tsk_create (RtcTask, 100);//创建RtcTask任务及级别
  Uart_Task = os_tsk_create (UartTask, 100);//10创建UartTask任务及级别
  Gps_Task = os_tsk_create (GpsTask, 10);//创建GpsTask任务及级别
  Nrf_Task = os_tsk_create (NrfTask, 10);//10创建NrfTask任务及级别
  Lcd_Task = os_tsk_create (LcdTask, 100);//创建LcdTask任务及级别
  if (::SystemRamTest != SystemRamTestVal) {
//    os_evt_set (DefBeep_Start, Beep_Task);//开关BEEP
os_evt_set (DefBeep_3, Beep_Task);//蜂鸣器发1声
	::SystemRamTest = SystemRamTestVal;
  }
  else {
os_evt_set (DefBeep_2, Beep_Task);//蜂鸣器发2声
//    os_evt_set (DefBeep_Begin, Beep_Task);//开关BEEP
  }
  os_evt_set (1, Lcd_Task);//LCD
//VIC->SoftInt = (1 << VICIntSel_UART0);
  VIC->IntEnable  = (1 << VICIntSel_EINT0) | //使能EINT0中断
                    (1 << VICIntSel_EINT2) | //使能EINT2中断
                    (1 << VICIntSel_RTC)   | //使能RTC中断
                    (1 << VICIntSel_UART0);//使能UART0中断
  for (;;) {
    if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
 	else WDPORT->IOSET = (1 << WDI);
	os_tsk_pass();
//	os_tsk_delete_self();
  }
}

void KeyTask (void) __task {
//unsigned char KeyVal;
  os_itv_set(10);//每个节拍醒来一次
  for (;;) {
    os_itv_wait();//
    if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
 	else WDPORT->IOSET = (1 << WDI);
//	for (int i = 0; i < 10; i ++) {
//	  Key.Exec();//键扫描及运行
//	}
//    os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
  }
}

void LcdTask (void) __task {
OS_RESULT result;
OS_RESULT num;
char str[32];
static const char DowTab[8][5] = {
  "周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"
};
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待LcdTask任务事件发生
    if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
 	else WDPORT->IOSET = (1 << WDI);
	if(result == OS_R_EVT) {
	  num = os_evt_get();
	  switch(num) {
	    case 1://只刷新
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 2://显示时间
//		  os_evt_set (1, Led_Task);//
          Lcd.SetLcdDisplayPos(0, 0);//汉字定位到上行左端
		  sprintf(str, "今天: %04d-%02d-%02d", Rtc.Year, Rtc.Month, Rtc.Dom);
          Lcd.LcdDisplay(str);
Uart.puts(str);			 
          Lcd.SetLcdDisplayPos(1, 0);//汉字定位到上行左端
		  sprintf(str, "时间%02d:%02d:%02d%4s", Rtc.Hour, Rtc.Min, Rtc.Sec, DowTab[Rtc.Dow & 7]);
          Lcd.LcdDisplay(str);
Uart.puts(str);			 
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 8888:
          Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
		  sprintf(str, "Uart.Status=%02X  ", Uart.Status);
          Lcd.LcdDisplay(str);
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 1888:
          Lcd.SetLcdDisplayPos(3, 0);//汉字定位到上行左端
          Lcd.LcdDisplay("改写时间成功!!");
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 2888:
          Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
          Lcd.LcdDisplay("改写日期成功!!");
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 3888://显示无线数据
          Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
          Lcd.LcdDisplay(&nRF.nRFRxBuff[0], 8);
          Lcd.SetLcdDisplayPos(3, 0);//汉字定位到上行左端
          Lcd.LcdDisplay(&nRF.nRFRxBuff[8], 8);
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 4888:
          Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
          Lcd.LcdDisplay("无线数据发送成功");
          Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
Uart.puts("无线数据发送成功");			 
		  break;
	  }
	}
  }
}

void BeepTask (void) __task {
OS_RESULT result;
OS_RESULT num;
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待BeepTask任务事件发生
	if(result == OS_R_EVT) {
//      if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
// 	  else WDPORT->IOSET = (1 << WDI);
Uart.puts("BeepTask任务事件开始");
	  num = os_evt_get();
	  while (num > 0){
Uart.puts("BeepTask任务事件发生");
	    if (num & 1) {
	      BEEPPORT->IOCLR = (1 << BEEP);			// BEEP	蜂鸣
		}
	    else BEEPPORT->IOSET = (1 << BEEP);			// BEEP停止蜂鸣
		num >>= 1;
        os_dly_wait (25);//延时100mS
	  }
	  BEEPPORT->IOSET = (1 << BEEP);			// BEEP停止蜂鸣
Uart.puts("BeepTask任务事件结束");
	}
  }
}

void RtcTask (void) __task {
OS_RESULT result;
//OS_RESULT num;
//unsigned int val;
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待RtcTask任务事件发生
    if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
 	else WDPORT->IOSET = (1 << WDI);
	if(result == OS_R_EVT) {
//	  num = os_evt_get();
	}
  }
}

void UartTask (void) __task {
OS_RESULT result;
OS_RESULT num;
//unsigned int val;
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待UartTask任务事件发生
	if(result == OS_R_EVT) {
	  num = os_evt_get();
	  switch(num) {
	    case 1://
		  Uart.LoadDataBuff();
		  break;
	  }
	}
  }
}

void GpsTask (void) __task {
OS_RESULT result;
//OS_RESULT num;
//unsigned int val;
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待GpsTask任务事件发生
	if(result == OS_R_EVT) {
//	  num = os_evt_get();
	}
  }
}

void NrfTask (void) __task {
OS_RESULT result;
OS_RESULT num;
char str[32];
  for (;;) {
    result = os_evt_wait_or(0xffff, 0xffff);//等待NrfTask任务事件发生
	if(result == OS_R_EVT) {
	  num = os_evt_get();
	  switch(num) {
	    case 250://
          sprintf(str, "无线接收事件处理");
          Uart.puts(str);
		  nRF.nRFReadBuffers();
          os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
		  break;
	  }
	}
  }
}


int main (void) {
  INTCON->EXT_INT = (1 << EINT0)    //清除INT0中断标志
                  | (1 << EINT1)	//清除INT1中断标志
                  | (1 << EINT2)	//清除INT2中断标志
                  | (1 << EINT3);	//清除INT3中断标志
  Enable_IRQ();//开中断
  os_sys_init (MainTask);//启动ARTX,此函数并不返回main()
}

⌨️ 快捷键说明

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