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

📄 main.cpp

📁 射频芯片nRF905例程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    | VICIntSel_EINT0;//获取EINT0的IRQ级别

  VIC->VectCntls[1] = VICIntSel_Enable//使能IRQ中断
                    | VICIntSel_EINT2;//获取EINT2的IRQ级别

  VIC->VectCntls[2] = VICIntSel_Enable//使能IRQ中断
                    | VICIntSel_RTC;//获取RTC的IRQ级别

  VIC->VectCntls[3]   = VICIntSel_Enable//使能IRQ中断
                      | VICIntSel_UART0;//获取UART0的IRQ级别



  INTCON->EXT_INT = (1 << EINT0)    //清除INT0中断标志
                  | (1 << EINT1)	//清除INT1中断标志
                  | (1 << EINT2)	//清除INT2中断标志
                  | (1 << EINT3);	//清除INT3中断标志
}

void SystemObj::BeepInit(void)
{
  BEEPPORT->IODIR |= (1 << BEEP);		// 设置BEEP控制口为输出	
//  BEEPPORT->IOSET = (1 << BEEP);			// BEEP停止蜂鸣
  BEEPPORT->IOCLR = (1 << BEEP);			// BEEP停止蜂鸣
//while(1) {
//  WDPORT->IOPIN ^= (1 << WDI);		    // 设置WDI控制口为输出	
//}

}

//__inline
LcdObj::LcdObj(void)
{
  LcdPinSetup();
  LcdInit();
}


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


/* 设置MOSI 和SCK 及SS 为输出,其他为输入 */
  LCDPORT->IODIR |= (1 << LCDRST) | (1 << LCDCS) | (1 << LCDSCK) | (1 << LCDSID);
  LCDPORT->IOCLR  = (1 << LCDRST) | (1 << LCDCS);
  LCDPORT->IOSET = (1 << LCDSCK) | (1 << LCDSID);
  _delay_loop_(10);
  LCDPORT->IOSET = (1 << LCDRST);
  _delay_loop_(100);
}

//__inline
void LcdObj::LcdInit(void)
{
/*--------------------------------------------------- 
    LCD模块上电等待延时 
----------------------------------------------------*/ 
  LcdClearBuffer();
  LcdSendCommand(0x20);//发送4位控制命令 
//  LcdSendCommand(0x30);//发送8位控制命令//与8位4位无关!!! 
  LcdSendCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0 
  LcdSendCommand(0x04);//发送进入点命令 
  LcdSendCommand(0x0c);//发送开显示关光标命令 
  LcdSendCommand(0x01);//发送清除显示命令 
  LcdSendCommand(0x80);//发送设定DDRAM地址0x00命令 
//汉字0xfd出错测试	   
  LcdDisplay("褒饼昌除待谍洱俘");
  SetLcdDisplayPos(1, 0);//汉字定位到上行左端
  LcdDisplay("庚过糊积箭烬君魁");
  SetLcdDisplayPos(2, 0);//汉字定位到上行左端
  LcdDisplay("例笼慢谬凝琵讫驱");
  SetLcdDisplayPos(3, 0);//汉字定位到上行左端
  LcdDisplay("三升数她听妄锡淆");

}

//__inline
void LcdObj::LcdSend(char cData)
{
unsigned int i;
//  _delay_loop_(1);
  for (i = 0; i < 8; i ++) {
//    _delay_loop_(1);
    LCDPORT->IOCLR = (1 << LCDSCK);
//    _delay_loop_(1);
    if (cData & 0x80) {//MSB最高位为1时
      LCDPORT->IOSET = (1 << LCDSID);
	}
	else {
      LCDPORT->IOCLR = (1 << LCDSID);
	}
//    _delay_loop_(1);
	cData <<= 1;
    LCDPORT->IOSET = (1 << LCDSCK);
//    _delay_loop_(1);
  }	
/*
  SPI->SPI_SPDR = cData;                        //发送数据(相当于51的SBUF = DATA)
  while(!(SPI->SPI_SPSR & (1 << SPIF)));		// 等待SPIF置位,即等待数据发送完毕
*/
}



/*--------------------------------------------------------
    发送8位LCD控制命令
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendCommand(char cCommand)
{
/*--------------------------------------------------------
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
  LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
  LcdSend(0xf8);//发送LCD控制命令
  LcdSend(cCommand & 0xf0);//发送高4位LCD控制命令
  LcdSend(cCommand << 4);//发送低4位LCD控制命令
  LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
  if (cCommand == 0x01) _delay_loop_(160);//1.6mS
  else _delay_loop_(72);//st7920要求等待72uS
}

/*--------------------------------------------------------
    发送8位LCD显示数据
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendData(char cData)
{
/*--------------------------------------------------------
    发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
  LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
  LcdSend(0xfa);//发送LCD显示数据
  LcdSend(cData & 0xf0);//发送高4位LCD显示数据
  LcdSend(cData << 4);//发送低4位LCD显示数据
  LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
  _delay_loop_(72);//st7920要求等待延时72uS
}

//__inline
void LcdObj::SetLcdDisplayPos(unsigned char row, unsigned char col)
{
  row &= 0x03;//4行汉字
  col &= 0x0f;//每行8个汉字16个字符
  LcdRow = row;
  LcdCol = col;
  LcdRowWriteEnable[row] = 1;//允许此行刷新汉字显示
}

//__inline
void LcdObj::LcdClearBuffer(void)
{
unsigned char i, j;
  for (i = 0;i < 4;i ++) {
    for (j = 0;j < 16; j ++) {
      LcdBuffer[i][j] = ' ';
    }
    LcdRowWriteEnable[i] = 1;//允许此行刷新汉字显示
  }
  LcdRow = 0;
  LcdCol = 0;
}

//__inline
void LcdObj::LcdDisplayBuffer(void)
{
unsigned char i, j;
  for (i = 0; i < 4; i ++) {//4行汉字
    if (LcdRowWriteEnable[i]) {//允许此行刷新汉字显示
      LcdSendCommand(0x80 + (i & 1) * 16 + (i >> 1) * 8);//移动光标
      for (j = 0; j < 16; j ++) {//每行8个汉字16个字符
        LcdSendData(LcdBuffer[i][j]);//刷新显示字符
      }
	  LcdRowWriteEnable[i] = 0;//过后不允许此行刷新汉字显示
	}
  }
}

//__inline
void LcdObj::LcdDisplay(const char * string)
{
  while(*string) {
    LcdBuffer[LcdRow][LcdCol ++] = *string ++;
  }
}

void LcdObj::LcdDisplay(unsigned char hexstr[], unsigned int len)
{
unsigned char ch;
  for (int i = 0; i < len; i ++) {
    ch = *hexstr++;
	if (ch < 0xa0) {
      LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) + '0';
	}
	else {
      LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) - 10 + 'A';
	}
	if ((ch & 0x0f) < 0x0a) {
      LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) + '0';
	}
	else {
      LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) - 10 + 'A';
	}
  }
}

//__inline//(不敢加inline)
//__forceinline
void LcdObj::LcdDisplay(unsigned int Val, unsigned char size1, signed char size0)
{
char str[7], *ptr;
unsigned char i;
  ptr = str + 5;
  if (size0 > 0) {//有小数
    for (i = 0; i < 3; i ++) {
	  *ptr -- = (Val % 10) + '0';
	  Val /= 10;
    }
    ptr[size0 + 1] = 0;
    *ptr -- = '.';
  }
  else {
    *ptr -- = 0;
  }
  for (i = 0; i < size1; i ++) {
    if (i && (Val == 0)) {
	  if (size0 < 0) {
	    *ptr -- = '0';
	  }
	  else {
	    *ptr -- = ' ';
	  }
    }
	else *ptr -- = (Val % 10) + '0';
	Val /= 10;
  }
  LcdDisplay(ptr + 1);
}

//inline
UartObj::UartObj(void)
{
  UartInit();
}

//inline
void UartObj::UartInit(void)
{
unsigned int Fdiv;
  PINSEL->PIN_SEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //设置I/O连接到UART0
  U0->LCR = 0x83;						// DLAB=1,允许设置波特率
  Fdiv  = (Fpclk / 16) / UART_BPS;	// 设置波特率
  U0->DLM = Fdiv / 256;
  U0->DLL = Fdiv % 256;
  U0->LCR = 0x03;
  U0->FCR = 0xc7;                                   /* 初始化FIFO 接收14个字节就中断*/
  U0->IER = 0x07;//0x01;//0x07                                   /* 允许接收发送中断 */
  RxCount = TxCount = 0;
  RxdCount = TxdCount = 0;
  for (int i = 0; i < 256; i ++) {
    RxBuffer[i] = TxBuffer[i] = 0;
  }
  TxBusy = false;
// 
}


void UartObj::Exec(void)
{
static unsigned char cData = 0;
unsigned char ch;
  Status = U0->IIR & 0x0f;
  switch (Status) {
    case 0x06://接收线状态
	  switch (U0->LSR) {
	    case 0x63:
		  break;
	  }
	  break;
    case 0x04://接收数据可用
    case 0x0c://字符超时指示
	 do{
	  ch = U0->RBR;
	  if (ch == '$') {
	    cData = '$';
	    RxBuffer[RxCount ++] = ch;
	  }
	  else if(cData == '$'){
	    if (ch >= 0x20) {
	      RxBuffer[RxCount ++] = ch;
		}
	    else if (ch == 0x0d) {
	      RxBuffer[RxCount ++] = ch;
		}
		else if (ch == 0x0a) {
//          if (RxBuffer[(RxCount - 1) & 0x7f] == 0x0d) {
	        cData = 0;
	        RxBuffer[RxCount ++] = ch;
//isr_evt_set (DefBeep_1, Beep_Task);
            isr_evt_set (1, Uart_Task);
//	      }
		}
	  }
	}while(U0->LSR & (1 << RDR));
	  break;
	case 0x01://LPCARM保留中断,可用于软件模拟激活UART0中断
     if (!(VIC->SoftInt & (1 << VICIntSel_UART0))) {//硬件UART0中断
	   break;//正常的UART0中断退出
	 }
    case 0x02://THRE中断
  	  TxBusy = TxCount != TxdCount;//保证FIFO发送全部结束时,缓冲区空不拒绝发送
	  for (int i = 0; (i < 16) && (TxCount != TxdCount); i ++) {//1次写入FIFO最多16个字节
		ch = TxBuffer[TxdCount ++];//取出缓冲区1个字节数据
		if (ch >= 0x0a) {//防止非法字符漏入
	      U0->THR = ch;//将缓冲区1个字节数据写入FIFO
		}
	  }
	  break;
//    case 0x0f://保留中断
//	  break;
  }   
}
/*
    RTC->RTC_YEAR = 2006;
    RTC->RTC_MONTH = 3;
    RTC->RTC_DOM = 30;
    RTC->RTC_HOUR =8;
    RTC->RTC_MIN =53;
    RTC->RTC_SEC = 0;
    RTC->RTC_DOW = 4;
*/
void UartObj::LoadDataBuff(void)
{
unsigned char ch, cl;
unsigned int val;
  if (RxBuffer[RxdCount ++] == '$') {
	ch = RxBuffer[RxdCount ++];//取PC命令
    switch(ch) {
	  case 'C'://$CS81*CRC<CR>
	    ch = RxBuffer[RxdCount ++];//取PC命令
	    switch(ch) {
		  case 'S'://系统日期
		    if (RxBuffer[RxdCount + 2] == 0x0a) {
///              nRF.SetTxMode();//设置发送模式  
///			  os_dly_wait(1);
			  for (int i = 0; i < 32; i ++) {
			    nRF.nRFTxBuff[i] = nRF.nRFRxBuff[i];
			  }
			  for (int i = 0; i < 4; i ++) {
			    nRF.nRFTxBuff[i] = nRF.nRFRxBuff[i + 4];
			  }
			  for (int i = 0; i < 4; i ++) {
			    nRF.nRFTxBuff[i + 4] = nRF.nRFRxBuff[i];
			  }
	          ch = RxBuffer[RxdCount ++];
	          cl = RxBuffer[RxdCount ++];
			  val = ((ch - '0') << 4) + (cl - '0');
			  nRF.nRFTxBuff[9] = val;//无线命令号
			  nRF.nRFWriteBuffers();
//              nRF.StartTx();//开始发送//?????
///			  os_dly_wait(1);
              nRF.SetRxMode();//设置接收模式
//			  RxdCount ++;//放弃0x0d
			  RxdCount ++;//放弃0x0a
              os_evt_set (4888, Lcd_Task);//开关BEEP
              os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
			}
			break;
		}
	    break;
	  case 'D'://$DS2006-03-18*CRC<CR>
	    ch = RxBuffer[RxdCount ++];//取PC命令
	    switch(ch) {
		  case 'S'://系统日期
		    if (RxBuffer[RxdCount + 10] == 0x0a) {
RTC->RTC_CCR = 0; 
              val = 0; 
			  for (int i = 0; i < 4; i ++) {
	            ch = RxBuffer[RxdCount ++];
			    val = val * 10 + (ch - '0');
			  }
			  RTC->RTC_YEAR = val;
			  RxdCount ++;//放弃'-'
              val = 0; 
			  for (int i = 0; i < 2; i ++) {
	            ch = RxBuffer[RxdCount ++];
			    val = val * 10 + (ch - '0');
			  }
			  RTC->RTC_MONTH = val;
			  RxdCount ++;//放弃'-'
              val = 0; 
			  for (int i = 0; i < 2; i ++) {
	            ch = RxBuffer[RxdCount ++];
			    val = val * 10 + (ch - '0');
			  }
			  RTC->RTC_DOM = val;
/*
			  RxdCount ++;//放弃'-'
              val = 0; 
			  for (int i = 0; i < 1; i ++) {
                RxdCount &= 0x7f;
	            ch = RxBuffer[RxdCount ++];
			    val = val * 10 + (ch - '0');
			  }
*/
			  val = Rtc.GetDow(RTC->RTC_YEAR, RTC->RTC_MONTH, RTC->RTC_DOM);
			  RTC->RTC_DOW = val;
//			  RxdCount ++;//放弃0x0d
			  RxdCount ++;//放弃0x0a
RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC);				        // 启动RTC
              os_evt_set (2888, Lcd_Task);//开关BEEP
              os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
			}
			else {
              RxdCount = RxCount;//失败,取下次首指针
			}
		    break;
		}
	    break;
	  case 'T'://$TS00:01:08*CRC<CR>
	    ch = RxBuffer[RxdCount ++];//取PC命令
	    switch(ch) {
		  case 'S'://系统时间
		    if (RxBuffer[RxdCount + 8] == 0x0a) {
RTC->RTC_CCR = 0; 
	          ch = RxBuffer[RxdCount ++];
			  val = (ch - '0') * 10;
	          ch = RxBuffer[RxdCount ++];
			  val += ch - '0';
			  RTC->RTC_HOUR = val;
			  RxdCount ++;//放弃':'
	          ch = RxBuffer[RxdCount ++];
			  val = (ch - '0') * 10;
	          ch = RxBuffer[RxdCount ++];
			  val += ch - '0';
			  RTC->RTC_MIN = val;
			  RxdCount ++;//放弃':'
	          ch = RxBuffer[RxdCount ++];
			  val = (ch - '0') * 10;
	          ch = RxBuffer[RxdCount ++];
			  val += ch - '0';
			  RTC->RTC_SEC = val;
//			  RxdCount ++;//放弃0x0d
			  RxdCount ++;//放弃0x0a
RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC);				        // 启动RTC
              os_evt_set (1888, Lcd_Task);//开关BEEP
              os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
			}
			else {
              RxdCount = RxCount;//失败,取下次首指针
			}
		    break;
		}
	    break;
	} 
  }
  else {
    RxdCount = RxCount;//失败,取下次首指针
  }
}



//inline
void UartObj::putchar(unsigned char dat)
{
//  U0->THR = dat;
//  while ((U0->LSR & 0x40) == 0);		// 等待数据发送完毕
//以上未用FIFO

//以下采用FIFO...
  TxBuffer[TxCount ++] = dat;//写入发送缓冲区(并非FIFO!!!)
  if ((!TxBusy) && (dat == 0x0a)){//发送FIFO不忙并且以换行符为界
  	VIC->SoftInt = (1 << VICIntSel_UART0);//软件中断模拟激活UART0中断
  }
}

//inline
void UartObj::putstr(const char str[])
{
  while (*str) {
	putchar(*str);
	str++;
  }
}


//inline
void UartObj::puts(const char str[])
{
  while (*str) {
	putchar(*str);
	str++;
  }
  putchar(0x0d);
  putchar(0x0a);//回车换行
}

//inline
void UartObj::puthex(unsigned char val)
{
char str[3];
  BinToHex(val, str);
  putstr(str);//
}

//inline
void UartObj::puthex(unsigned short val)
{
char str[5];
  BinToHex(val, str);
  putstr(str);//

⌨️ 快捷键说明

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