📄 main.cpp
字号:
/*--------------------------------------------------------------------------
ARM菜鸟HotPower 2006.5.31与西安大雁塔菜地
http://blog.21ic.com/blog.asp?name=hotpower
HotPower@126.com
--------------------------------------------------------------------------*/
#include <RTL.h> /* ARTX kernel functions & defines */
#include "main.h"
#include "class.h"
#include <string.h>
#include <stdio.h>
__noinit__ volatile unsigned int SystemRamTest;//RAM不初始化
#define SystemRamTestVal 0x55aa55aa
#pragma arm
extern "C" void __swi(8) Enable_IRQ(void);
extern "C" void __SWI_8 (void) {
int tmp;
__asm
{
MRS tmp, SPSR
BIC tmp, tmp, #0x80
MSR SPSR_c, tmp
}
}
#pragma arm
extern "C" void __swi(9) Disable_IRQ(void);
extern "C" void __SWI_9 (void) {
int tmp;
__asm
{
MRS tmp, SPSR
ORR tmp, tmp, #0x80
MSR SPSR_c, tmp
}
}
extern "C" void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
void _delay_loop_(unsigned int);
void _delay_loop_(unsigned int val)
{
unsigned int i;
for(i = 0; i < (val * 60); i ++);
}
OS_TID Main_Task, Key_Task, Lcd_Task, Beep_Task;
OS_TID Rtc_Task, Uart_Task, Gps_Task, Nrf_Task;
//OS_ID tmr1;
void MainTask (void) __task;
void KeyTask (void) __task;
void LcdTask (void) __task;
void BeepTask (void) __task;
void RtcTask (void) __task;
void UartTask (void) __task;
void GpsTask (void) __task;
void NrfTask (void) __task;
extern "C"
void IRQ_Eint0 (void) __irq{//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0,按下P0.16
if (VIC->IRQStatus & (1 << VICIntSel_EINT0)) {
// isr_evt_set (1, Beep_Task);//开关BEEP
// os_evt_set (1, Beep_Task);//开关BEEP
}
else {
// UserIRQ_Handler();//干扰出错
}
INTCON->EXT_INT = (1 << EINT0); //清除INT0中断标志
VIC->SoftIntClr = (1 << VICIntSel_EINT0);//也应该清除安全些!!!
VIC->VectAddr = 0;
}
extern "C"
void IRQ_Eint2 (void) __irq{//IRQ中断函数EINT2IRQ被挂接在VICVectCntl1,按下P0.15
if (VIC->IRQStatus & (1 << VICIntSel_EINT2)) {
isr_evt_set (250, Nrf_Task);//发送无线消息
}
INTCON->EXT_INT = (1 << EINT2); //清除INT2中断标志
VIC->SoftIntClr = (1 << VICIntSel_EINT2);//也应该清除安全些!!!
VIC->VectAddr = 0;
}
extern "C" void IRQ_UART0 (void) __irq
{
Uart.Exec();
VIC->SoftIntClr = (1 << VICIntSel_UART0);
VIC->VectAddr = 0x00; /* 通知VIC中断处理结束 */
}
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; // 向量中断结束
}
//__inline
KeyObj::KeyObj(void)
{
KeyInit();
}
//__inline
void KeyObj::KeyInit(void)
{
P1->IODIR &= ~((1 << KEY1) | (1 << KEY2) | (1 << KEY3) | (1 << KEY4) | (1 << KEY5) | (1 << KEY6));
P1->IODIR &= ~((1 << KEYA) | (1 << KEYB) | (1 << KEYC) | (1 << KEYD));
for (int i = 0; i < 10; i ++) KeyTest[i] = 0;
KeyCount = 0;//键盘序号
}
//取串行键盘键值
//__inline
unsigned char KeyObj::GetKeyVal(void)
{
static const unsigned int KeyTestTab[10] = {
(1 << KEY1),
(1 << KEY2),
(1 << KEY3),
(1 << KEY4),
(1 << KEY5),
(1 << KEY6),
(1 << KEYA),
(1 << KEYB),
(1 << KEYC),
(1 << KEYD)
};
unsigned int KeyTestVal = 0xffffffff;
unsigned int KeyVal;
KeyVal = KEYPORT->IOPIN;
if ((KeyVal & KeyTestTab[KeyCount]) == 0) {
KeyTestVal = KeyCount;
}
return KeyTestVal;//无键压下为0xff
}
//键扫描及运行
//__inline
void KeyObj::Exec(void)
{
char str[64];
if (KeyCount == GetKeyVal()) {//有键压下(每次只取1键以实现“零耗时消除键盘抖动”)
if (KeyTest[KeyCount] < SystemKeyPushTime) {//100*20mS=2S//压键长短判别
KeyTest[KeyCount] ++;//计数每20mS键盘压键的次数(选2较好些)
if (KeyTest[KeyCount] == SystemKeyPushNum) {//键刚压下//短压键
// os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
KeyCommandExec(1);//短压键事件处理(1)
sprintf(str, "短压键事件处理: Key%1d", KeyCount);
Uart.puts(str);
os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
}
}
else {//长压键 20mS*100=2S
KeyTest[KeyCount] = SystemKeyPushNum;//再压3S继续执行下一次长压键
// os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
KeyCommandExec(2);//长压键3S事件处理(2)
sprintf(str, "长压键事件处理: Key%1d", KeyCount);
Uart.puts(str);
os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
}
}
else {//无键压下
if (KeyTest[KeyCount] != 0) {//键早已释放
if (KeyTest[KeyCount] >= SystemKeyPushNum) {//键释放
KeyTest[KeyCount] = -SystemKeyPushNum;//键释放次数
}
else {//键释放计数(负数)
KeyTest[KeyCount] ++;//键释放计数
if (KeyTest[KeyCount] >= 0) {///键释放时间到
// os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
KeyCommandExec(0);//键释放事件处理(0)
KeyTest[KeyCount] = 0;//清除压键计数器
sprintf(str, "释放键事件处理: Key%1d", KeyCount);
Uart.puts(str);
// os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
}
}
}
}
KeyCount ++;//为下次扫描做准备
if (KeyCount >= 10) KeyCount = 0;//只有10个键
}
//typedef void (KeyObj::* PFV)(void);//类成员函数指针
typedef void (* PV)(void);//一般函数指针
//__inline
//__forceinline
void KeyObj::KeyCommandExec(unsigned char mode)
{
//static PV KeyCommandTab[3][10] = {//键盘放事件处理表 (RAM=0x40000000)
//const PV KeyCommandTab[3][10] = {//键盘放事件处理表 (RAM=0x40000474)
static const PV KeyCommandTab[3][10] = {//键盘放事件处理表(FLASH ROM=0x00002148)
{&KeyObj::Key00, &KeyObj::Key01, &KeyObj::Key02, &KeyObj::Key03, &KeyObj::Key04, &KeyObj::Key05, &KeyObj::Key06, &KeyObj::Key07, &KeyObj::Key08, &KeyObj::Key09}, //键释放事件处理
{&KeyObj::Key10, &KeyObj::Key11, &KeyObj::Key12, &KeyObj::Key13, &KeyObj::Key14, &KeyObj::Key15, &KeyObj::Key16, &KeyObj::Key17, &KeyObj::Key18, &KeyObj::Key19}, //压键事件处理
{&KeyObj::Key20, &KeyObj::Key21, &KeyObj::Key22, &KeyObj::Key23, &KeyObj::Key24, &KeyObj::Key25, &KeyObj::Key26, &KeyObj::Key27, &KeyObj::Key28, &KeyObj::Key29} //长压键事件处理
};
PV func;//声明一般函数指针
if ((mode < 3) && (KeyCount <= 9)) {
// func = reinterpret_cast<PV>(KeyCommandTab[mode][keyval]);//从FLASH中取出键盘放事件处理表
func = KeyCommandTab[mode][KeyCount];//从FLASH中取出键盘放事件处理表
func();//运行KeyX0()~KeyX8()
}
}
/*------------------------
键释放事件处理
------------------------*/
/*----------------------------------
释放选择键
--------------------------------*/
//__inline
void KeyObj::Key00(void)
{
/// 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];
}
nRF.nRFTxBuff[9] = 0x81;
nRF.nRFWriteBuffers();
nRF.StartTx();//开始发送
/// os_dly_wait(1);
nRF.SetRxMode();//设置接收模式
os_evt_set (4888, Lcd_Task);//开关BEEP
os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
}
/*----------------------------------
释放上调键
--------------------------------*/
//__inline
void KeyObj::Key01(void)
{
}
/*----------------------------------
释放下调键
--------------------------------*/
//__inline
void KeyObj::Key02(void)
{
}
/*----------------------------------
释放保留键
--------------------------------*/
//__inline
void KeyObj::Key03(void)
{
}
/*----------------------------------
释放信号A
--------------------------------*/
//__inline
void KeyObj::Key04(void)
{
}
/*----------------------------------
释放信号B
--------------------------------*/
//__inline
void KeyObj::Key05(void)
{
}
/*----------------------------------
释放信号C
--------------------------------*/
//__inline
void KeyObj::Key06(void)
{
}
//__inline
void KeyObj::Key07(void)
{
}
//__inline
void KeyObj::Key08(void)
{
}
//__inline
void KeyObj::Key09(void)
{
}
/*------------------------
压键事件处理
------------------------*/
/*----------------------------------
单击选择键
--------------------------------*/
//__inline
void KeyObj::Key10(void)
{
}
/*----------------------------------
单击上调键
--------------------------------*/
//__inline
void KeyObj::Key11(void)
{
}
/*----------------------------------
单击下调键
--------------------------------*/
//__inline
void KeyObj::Key12(void)
{
}
/*----------------------------------
单击保留键
--------------------------------*/
//__inline
void KeyObj::Key13(void)
{
}
/*----------------------------------
单击信号A
--------------------------------*/
//__inline
void KeyObj::Key14(void)
{
}
/*----------------------------------
单击信号B
--------------------------------*/
//__inline
void KeyObj::Key15(void)
{
}
/*----------------------------------
单击信号C
--------------------------------*/
//__inline
void KeyObj::Key16(void)
{
}
//__inline
void KeyObj::Key17(void)
{
}
//__inline
void KeyObj::Key18(void)
{
}
//__inline
void KeyObj::Key19(void)
{
}
/*------------------------
长压键事件处理
------------------------*/
/*----------------------------------
长压选择键
--------------------------------*/
//__inline
void KeyObj::Key20(void)
{
}
/*----------------------------------
长压上调键
--------------------------------*/
//__inline
void KeyObj::Key21(void)
{
}
/*----------------------------------
长压下调键
--------------------------------*/
//_inline
void KeyObj::Key22(void)
{
}
/*----------------------------------
长压保留键
--------------------------------*/
//_inline
void KeyObj::Key23(void)
{
}
/*----------------------------------
长压信号A
--------------------------------*/
//__inline
void KeyObj::Key24(void)
{
}
/*----------------------------------
长压信号B
--------------------------------*/
//_inline
void KeyObj::Key25(void)
{
}
/*----------------------------------
长压信号C
--------------------------------*/
//__inline
void KeyObj::Key26(void)
{
}
inline
void KeyObj::Key27(void)
{
}
inline
void KeyObj::Key28(void)
{
}
//__inline
void KeyObj::Key29(void)
{
}
SystemObj::SystemObj(void)
{
volatile unsigned int start;
for (start = 0; start < 10000; start ++);
Disable_IRQ();//关中断
SystemInit();
}
void SystemObj::SystemInit(void)
{
if (SystemRamTest != 0x55aa) {
SystemRamTest = 0x55aa;
}
PortInit();
VicInit();
WdtInit();
BeepInit();
}
void SystemObj::PortInit(void)
{
PINSEL->PIN_SEL0 = 0x00000000; // 设置管脚连接GPIO
PINSEL->PIN_SEL1 = 0x00000000; // 设置管脚连接GPIO
PINSEL->PIN_SEL2 = 0x00000000; // 设置管脚连接GPIO
P0->IODIR = 0x00000000; // 设置P0口为输入
P1->IODIR = 0x00000000; // 设置P1口为输入
VIC->IntEnClr = 0xffffffff;
VIC->SoftIntClr = 0xffffffff;//清除所有软中断标志
VIC->IntSelect = 0;//全部中断为IRQ中断或默认中断
for(int i = 0; i <= 15; i ++) {
VIC->VectAddrs[i] = i;//刷新向量地址寄存器VICVectAddr0~VICVectAddr15
}
}
void SystemObj::WdtInit(void)
{
WDPORT->IODIR |= (1 << WDI); // 设置WDI控制口为输出
}
void SystemObj::VicInit(void)
{
PINSEL->PIN_SEL1 |= (P0_16_EINT0 << P0_16_PINSEL); //选择P0.16为掉电保护中断
INTCON->EXT_POLAR &= ~(1 << EXTPOLAR0); //INT0为低电平有效
INTCON->EXT_MODE |= (1 << EXTMODE0); //设置INT0为边沿触发
VIC->VectCntls[0] = VICIntSel_Enable//使能IRQ中断
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -