📄 main.cpp
字号:
/*----------------------------------------------------------------------------
* 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 + -