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

📄 main.cpp

📁 USB中文数据说明
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------
 *      R T L   K e r n e l   E x a m p l e
 *----------------------------------------------------------------------------
 *      Name:    main.cpp
 *--------------------------------------------------------------------------*/
#include <RTL.h>                     /* ARTX kernel functions & defines     */

#include "main.h"
#include "class.h"
#include <string.h>
#include <stdio.h>


OS_TID Main_Task, Key_Task, Lcd_Task, Beep_Task, Led_Task, Uart_Task;

void MainTask (void) __task;
void KeyTask (void) __task;
void LcdTask (void) __task;
void BeepTask (void) __task;
void LedTask (void) __task;
void UartTask (void) __task;



extern "C"
void UserIRQ_Handler (void) {//干扰出错
unsigned long temp;
  temp = VIC->IRQStatus;
  if (temp & (1 << VICIntSel_EINT0)) {
    INTCON->EXT_INT = (1 << EINT0);	//清除INT0中断标志
  }
  if (temp & (1 << VICIntSel_EINT1)) {
    INTCON->EXT_INT = (1 << EINT1);	//清除INT1中断标志
  }
  if (temp & (1 << VICIntSel_EINT2)) {
    INTCON->EXT_INT = (1 << EINT2);	//清除INT2中断标志
  }
  if (temp & (1 << VICIntSel_EINT3)) {
    INTCON->EXT_INT = (1 << EINT3);	//清除INT3中断标志
  }
  else {//其他干扰源
//再次填入干扰处理代码
    temp |= VIC->FIQStatus;//将两种中断干扰合并处理
	for (int i = 0;i < 32; i ++) {
	  if (temp & (1 << i)) {
	    switch (i) {
	      case VICIntSel_Watchdog://看门狗中断异常处理
               __nop();
		       break;
	      case VICIntSel_Time0://定时器0中断异常处理
               T0->TIMER_IR = (1 << MR0) | (1 << MR1) | (1 << MR2) | (1 << MR3) //清除匹配通道X中断标志
			                | (1 << CR0) | (1 << CR1) | (1 << CR2) | (1 << CR3);//清除捕获通道X事件中断标志
		       break;
	      case VICIntSel_Time1://定时器1中断异常处理
               T1->TIMER_IR = (1 << MR0) | (1 << MR1) | (1 << MR2) | (1 << MR3) //清除匹配通道X中断标志
			                | (1 << CR0) | (1 << CR1) | (1 << CR2) | (1 << CR3);//清除捕获通道X事件中断标志
		       break;
	      case VICIntSel_UART0://UART0中断异常处理
               __nop();
		       break;
	      case VICIntSel_UART1://UART1中断异常处理
               __nop();
		       break;
	      case VICIntSel_PWM0://PWM0中断异常处理
               __nop();
		       break;
	      case VICIntSel_I2C0://I2C0中断异常处理
               __nop();
		       break;
	      case VICIntSel_SPI0://SPI0中断异常处理
               __nop();
		       break;
	      case VICIntSel_SPI1://SPI1/SSP中断异常处理
               __nop();
		       break;
	      case VICIntSel_PLL://PLL中断异常处理
               __nop();
		       break;
	      case VICIntSel_RTC://RTC中断异常处理
               RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF);//清除RTC增量和报警中断标志
		       break;
	      case VICIntSel_EINT0://EINT0中断异常处理
               INTCON->EXT_INT = (1 << EINT0);	//清除INT0中断标志
		       break;
	      case VICIntSel_EINT1://EINT1中断异常处理
               INTCON->EXT_INT = (1 << EINT1);	//清除INT1中断标志
		       break;
	      case VICIntSel_EINT2://EINT2中断异常处理
               INTCON->EXT_INT = (1 << EINT2);	//清除INT2中断标志
		       break;
	      case VICIntSel_EINT3://EINT3中断异常处理
               INTCON->EXT_INT = (1 << EINT3);	//清除INT3中断标志
		       break;
	      case VICIntSel_ADC0://ADC0中断异常处理
               __nop();
		       break;
	      case VICIntSel_I2C1://I2C1中断异常处理
               __nop();
		       break;
	      case VICIntSel_BOD://BOD中断异常处理
               __nop();
		       break;
	      case VICIntSel_ADC1://ADC1中断异常处理
               __nop();
		       break;
		  
	    }
	  }
	}
  }
  for (int i = 0;i <= 15; i ++) {//VIC->VectAddrs只能在特权模式下修改
    VIC->VectAddrs[i] = i;//刷新向量地址寄存器VICVectAddr0~VICVectAddr15
  }
  VIC->SoftIntClr = 0xffffffff;//也应该清除安全些!!!
  VIC->VectAddr = 0;
}


extern "C" void IRQ_Eint3 (void) __irq
{
  INTCON->EXT_INT = (1 << EINT3);	//清除INT0中断标志
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}

extern "C" void IRQ_Eint0 (void) __irq
{
  INTCON->EXT_INT = (1 << EINT0);	//清除INT0中断标志
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}

extern "C" void IRQ_Timer0 (void) __irq
{
  T0->TIMER_IR = 0x01;				/* 清除中断标志									*/
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}

extern "C" void IRQ_I2C0 (void) __irq
{
  Twi.Exec();
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}

extern "C" void IRQ_UART0 (void) __irq
{
  Uart.Exec();
  VIC->VectAddr = 0x00;		/* 通知VIC中断处理结束							*/
}


void SystemObj::VicIntSetup(void)
{
  INTCON->EXT_POLAR       &= ~((1 << EXTPOLAR0)  //INT0为低电平有效
				          |	  (1 << EXTPOLAR3));//INT3为低电平有效
//  INTCON->EXT_MODE        &= ~ (1 << EXTMODE0);   //设置INT0为电平触发
  INTCON->EXT_MODE        |=   (1 << EXTMODE0);   //设置INT0为边沿触发
  INTCON->EXT_MODE        |=   (1 << EXTMODE3);   //设置INT3为边沿触发
//  LEDPORT->IODIR |= (1 << LED1); 

  VIC->VectCntls[0]   = VICIntSel_Enable//使能IRQ中断
                      | VICIntSel_EINT0;//获取EINT0的IRQ级别


//  VIC->VectAddrs[0]   = (long) IRQ_Eint0;//取INT0中断服务地址

//////////////////////////////////////////////////////////////////////////////////////////////////
  VIC->VectCntls[1]   = VICIntSel_Enable//使能IRQ中断 
	                  | VICIntSel_Time0;			

//  VIC->VectAddrs[1]   = (uint32)IRQ_Timer0;
//  VIC->IntEnable   |= (1 << VICIntSel_Time0);
//  VIC->IntEnable   |= (1 << VICIntSel_EINT3); //使能EINT3中断

  INTCON->EXT_INT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3);	//清除INT中断标志

/* VIC初始化 */
  VIC->VectCntls[2]   = VICIntSel_Enable//使能IRQ中断 
                      | VICIntSel_RTC;

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

  VIC->VectCntls[4]   = VICIntSel_Enable//使能IRQ中断
                      | VICIntSel_I2C0;//获取I2C0的IRQ级别

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


//  VIC->VectAddrs[2] = (int)RTC_Int;	// 设置中断服务程序地址
//  VIC->IntEnable |= (1 << VICIntSel_RTC);		// 使能RTC中断



//  VIC->IntSelect   = (1 << VICIntSel_RTC);	  // Enable a Vic Channel as FIQ
}


void SystemObj::Timer0Init(void)
{
	/* 定时器0初始化 */
	T0->TIMER_TC   = 0;			/* 定时器设置为0										*/
	T0->TIMER_PR   = 0;			/* 时钟不分频											*/
    T0->TIMER_MCR  = 0x03;		/* 设置T0MR0匹配后复位T0TC,并产生中断标志				*/
	T0->TIMER_MR0  = Fpclk / 2;	/* 0.5秒钟定时											*/
	T0->TIMER_TCR  = 0x01;		/* 启动定时器											*/
}


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

void SystemObj::WdtInit(void)
{
  WDPORT->IODIR |= (1 << WDI);		    // 设置WDI控制口为输出	
//  WDPORT->IOPIN ^= (1 << WDI);
}

void SystemObj::LedInit(void) {
  LEDPORT->IODIR |= (1 << LED1) |	// 设置LED1为输出	
               (1 << LED2)	|	// 设置LED2为输出  
               (1 << LED3)	|	// 设置LED3为输出  
               (1 << LED4)	|	// 设置LED4为输出  
               (1 << LED5)	|	// 设置LED5为输出  
               (1 << LED6)	|	// 设置LED6为输出  
               (1 << LED7)	|	// 设置LED7为输出  
               (1 << LED8);  	// 设置LED8为输出  
  LEDPORT->IOSET  = (1 << LED1) |	// 关闭LED1
	           (1 << LED2) |	// 关闭LED2
	           (1 << LED3) |	// 关闭LED3
	           (1 << LED4) |	// 关闭LED4
	           (1 << LED5) |	// 关闭LED5
	           (1 << LED6) |	// 关闭LED6
	           (1 << LED7) |	// 关闭LED7
	           (1 << LED8);  	// 关闭LED8
}



extern "C" void RTC_Int(void) __irq
{
//volatile unsigned int temp;
//  temp = RTC->RTC_ILR;
//  if ( temp == (1 << RTCCIF)) {
//    RTC->RTC_ILR = (1 << RTCCIF);	// 清除RTC增量中断标志
    Rtc_.Sec = RTC->RTC_SEC;
    Rtc_.Min = RTC->RTC_MIN;
    Rtc_.Hour = RTC->RTC_HOUR;
    Rtc_.Year = RTC->RTC_YEAR;
    Rtc_.Month = RTC->RTC_MONTH;
    Rtc_.Dom = RTC->RTC_DOM;
    Rtc_.Dow = RTC->RTC_DOW;
//  }
//  else {
//    RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF);	// 清除RTC增量和报警中断标志
//  }
  isr_evt_set (2, Lcd_Task);//
  RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF);	// 清除RTC增量和报警中断标志
  VIC->VectAddr = 0;		// 向量中断结束
}




/*-----------------------------------------------------------------
  MainTask任务
1.建立其他任务,并分配任务级别.
2.负责清除看门狗的任务.
-----------------------------------------------------------------*/
void MainTask (void) __task {
  Main_Task = os_tsk_self ();
//  os_tsk_prio_self(200);
  Key_Task = os_tsk_create (KeyTask, 1);//创建KeyTask任务及级别
  Lcd_Task = os_tsk_create (LcdTask, 5);//创建LcdTask任务及级别
  Led_Task = os_tsk_create (LedTask, 8);//创建LedTask任务及级别
  Beep_Task = os_tsk_create (BeepTask, 10);//创建BeepTask任务及级别
  Uart_Task = os_tsk_create (UartTask, 100);//创建UartTask任务及级别
  if (SystemRamTest	!= 0x55aa55aa) {
    os_evt_set (DefBeep_Start, Beep_Task);//开关BEEP
	SystemRamTest = 0x55aa55aa;
  }
  else {
    os_evt_set (DefBeep_Begin, Beep_Task);//开关BEEP
  }
  os_dly_wait (100);//延时1000mS
  Lcd_.LcdInit();
  os_evt_set (1, Lcd_Task);//开关BEEP
  VIC->IntEnable  |= (1 << VICIntSel_EINT0) //使能EINT0中断
				   | (1 << VICIntSel_EINT3);//使能EINT3中断
  VIC->IntEnable  |= (1 << VICIntSel_RTC);		// 使能RTC中断
  VIC->IntEnable  |= (1 << VICIntSel_Time0);
  VIC->IntEnable  |= (1 << VICIntSel_I2C0);
  VIC->IntEnable  |= (1 << VICIntSel_UART0);
  for(int i = 0; i < 16;i ++) {
    Twi.TxBuffer[i] = i;
  }
  Twi.TWByteWrite(0, 16);
  Twi.TWByteRead(0, 16);
//Twi.WorkExec();
  os_itv_set(5);//每50个节拍醒来一次
  for (;;) {
    os_itv_wait();//
	WDPORT->IOPIN ^= (1 << WDI);
  }
}

/*-----------------------------------------------------------------
  KeyTask任务
1.每个节拍醒来一次,执行键盘扫描任务
2.负责设置键盘标志的任务.
-----------------------------------------------------------------*/

void KeyTask (void) __task {
  os_itv_set(1);//每个节拍醒来一次
  for (;;) {
    os_itv_wait();//
//	Key.Exec();//键扫描及运行
  }
}

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(result == OS_R_EVT) {
	  num = os_evt_get();
	  switch(num) {
	    case 1://只刷新
          Lcd_.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 2://显示时间
//		  os_evt_set (1, Led_Task);//开关BEEP
          Lcd_.SetLcdDisplayPos(0, 0);//汉字定位到上行左端
		  sprintf(str, "今天: %04d-%02d-%02d", Rtc_.Year, Rtc_.Month, Rtc_.Dom);
          Lcd_.LcdDisplay(str);

          Lcd_.SetLcdDisplayPos(1, 0);//汉字定位到上行左端
		  sprintf(str, "时间%02d:%02d:%02d%4s", Rtc_.Hour, Rtc_.Min, Rtc_.Sec, DowTab[Rtc_.Dow & 7]);
          Lcd_.LcdDisplay(str);
          Lcd_.LcdDisplayBuffer();//刷新LCD显示缓冲区
		  break;
		case 8888:
          Lcd_.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
		  sprintf(str, "Uart.Status=%02X  ", Uart.Status);
          Lcd_.LcdDisplay(str);
		  break;
		case 1888:
          Lcd_.SetLcdDisplayPos(3, 0);//汉字定位到上行左端
          Lcd_.LcdDisplay("改写时间成功!!");
		  break;
		case 2888:
          Lcd_.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
          Lcd_.LcdDisplay("改写日期成功!!");
		  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) {
	  num = os_evt_get();
	  while (num){
	    if (num & 1) OpenBeep();//BEEP	蜂鸣
	    else CloseBeep();		// BEEP停止蜂鸣
		num >>= 1;
        os_dly_wait (25);//延时100mS
	  }
	  CloseBeep();		// BEEP停止蜂鸣
	}
  }
}

void LedTask (void) __task {
unsigned int i = 0, k = 0, dir = 0;
  os_itv_set(20);//每20个节拍醒来一次
  for (;;) {
    os_itv_wait();//
	Led_.LedDisplay((i ++) % 10);
	if (i >= 10) {
	  i = 0;
	}
	if (i & 1)	{
      LEDPORT->IOSET  = (1 << LED1) |	// 关闭LED1
	               (1 << LED2) |	// 关闭LED2
	               (1 << LED3) |	// 关闭LED3
	               (1 << LED4) |	// 关闭LED4
	               (1 << LED5) |	// 关闭LED5
	               (1 << LED6) |	// 关闭LED6
	               (1 << LED7) |	// 关闭LED7
	               (1 << LED8);  	// 关闭LED8
      k &= 0x07;
	  if (dir) {
	    LEDPORT->IOCLR  = (1 << LED1) << k;
	  }
	  else {
	    LEDPORT->IOCLR  = (1 << LED8) >> k;
	  }
      k ++;
	  if (k >= 8) {
  	    dir = ~dir;
	  }
	}
  }
}

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


void _delay_loop_(unsigned int);
void _delay_loop_(unsigned int val)
{
unsigned int i;
  for(i = 0; i < (val * 60); i ++);
}


⌨️ 快捷键说明

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