|
相关连接: [匠人DIY旋转时钟 系列文章 (连载中…)]
//-------------------------------------------------------- // 项目: // 模块:中断服务 // 说明: // 设计:程序匠人(版权所有,引用者请保留原作者姓名) //-------------------------------------------------------- /* 版本说明: Interruption.c 2008-2-10 15:36
*/ //--------------------------------------------------------
//-------------------------------------------------------- //插入文件包 //-------------------------------------------------------- #i nclude "common.h" //--------------------------------------------------------
//-------------------------------------------------------- //显示段码表(模拟表盘) //-------------------------------------------------------- const tU08 LED_TAB_12369[]= { //编号 字符 0X3E, 0X0, 0X0, 0X3A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2E, //0 12 正向 0X3E, 0X2, 0X2, 0X2, 0X3E, 0X2, 0X2, 0X2, 0X3E, //1 3 左旋90度 0X2E, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3E, //2 6 左旋180度 0X3E, 0X20, 0X20, 0X20, 0X3E, 0X22, 0X22, 0X22, 0X3E, //3 9 左旋270度 };
//-------------------------------------------------------- //显示段码表 //-------------------------------------------------------- const tU08 LED_TAB_A[]= { //编号 字符 0X3E, 0X22, 0X22, 0X22, 0X22, 0X22, 0X22, 0X22, 0X3E, //0 0 0X0, 0X0, 0X20, 0X24, 0X3E, 0X20, 0X20, 0X0, 0X0, //1 1 0X3A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2E, //2 2 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3E, //3 3 0X18, 0X18, 0X14, 0X14, 0X12, 0X3E, 0X10, 0X10, 0X10, //4 4 0X2E, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3A, //5 5 0X3E, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3A, //6 6 0X2, 0X2, 0X2, 0X2, 0X2, 0X32, 0XA, 0X6, 0X2, //7 7 0X3E, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3E, //8 8 0X2E, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0X3E, //9 9 0X0, 0X0, 0X0, 0X0, 0X14, 0X0, 0X0, 0X0, 0X0, //10 : 0X2, 0X0, 0X0, 0X1C, 0X22, 0X22, 0X22, 0X22, 0X22, //11 ℃ 0X8, 0X1C, 0X1C, 0X3E, 0X3E, 0X3E, 0X1C, 0X1C, 0X8, //12 钟摆小球 0X0, 0X0, 0X0, 0X0, 0X0, 0X0, 0X0, 0X0, 0X0, //13 空白 0X0, 0X4, 0X4, 0X4, 0X1E, 0X24, 0X24, 0X14, 0X0, //14 t 0X8, 0X8, 0X8, 0X8, 0X8, 0X8, 0X8, 0X8, 0X8, //15 - };
//-------------------------------------------------------- //中断服务程序 //-------------------------------------------------------- void interrupt ISR(void) { tU08 i,j ;
//================ //TMR1中断,用于显示扫描控制 //================ if ( TMR1IF && TMR1IE) { TMR1IF = 0 ; //清除中断标志 TMR1ON = 0 ; //TMR1暂停 TMR1HL = TMR1HL + DISP_TIME_SET ; //TMR1重新赋初值 TMR1ON = 1 ; //TMR1启动
if ( ++TIMR1_JSQ > 250 ) TIMR1_JSQ = 250 ; //TIMR1溢出计数器+1,>最大值,=最大值
if ( ++DISP_LINE > 179 ) DISP_LINE = 0 ; //显示列计数器+1,>最大值,=0 //======== //根据显示列计数器,刷新显示缓冲区 //======== //清IO临时缓冲区 PORTA_TMP = 0B00111100 ; PORTB_TMP = 0B11111110 ; PORTC_TMP = 0B00001011 ;
if ( MOTOR_ST_FLAG ) //电机状态标志=1?(0=关闭,1=开启) { //显示状态 if ( SET_EN_FLAG == 0 ) { //根据显示状态判断 switch( DISP_MODE ) { case 0: //显示状态0:模拟钟 //标整点,以及显示数字12,3,6,9 if ( (DISP_LINE >= 176) || (DISP_LINE <= 4)) //12点 { i=DISP_LINE+4+9*0 ; if ( i>=180) i=i-180 ; } else if ( (DISP_LINE >= 41) && (DISP_LINE <= 49)) //3点 { i=DISP_LINE-41+9*1 ; } else if ( (DISP_LINE >= 86) && (DISP_LINE <= 94)) //6点 { i=DISP_LINE-86+9*2 ; } else if ( (DISP_LINE >= 131) && (DISP_LINE <= 139)) //9点 { i=DISP_LINE-131+9*3 ; } else { i = 255 ; //禁止后面的查表动作 switch (DISP_LINE) { case 180*1/12 : //1点 case 180*2/12 : //2点 case 180*4/12 : //4点 case 180*5/12 : //5点 case 180*7/12 : //6点 case 180*8/12 : //7点 case 180*10/12 : //10点 case 180*11/12 : //11点 LED01_TMP = 0 ; break; } } if ( i < (9*4) ) PORTB_TMP &= ~LED_TAB_12369[i] ; //查表显示12,3,6,9 //显示指针"时" i = H_LINE ; j = H_LINE ; if ( ++i > 179 ) i=0 ; //i+1,结果>179,则清零 if ( --j > 179 ) i=179 ; //j-1,结果为负,则重新赋值179 if ( ( DISP_LINE == H_LINE ) || ( DISP_LINE == i ) || ( DISP_LINE == j )) { LED09_TMP = 0 ; LED10_TMP = 0 ; LED11_TMP = 0 ; LED12_TMP = 0 ; LED13_TMP = 0 ; } //显示指针"分" if ( DISP_LINE == M_LINE ) { LED08_TMP = 0 ; LED09_TMP = 0 ; LED10_TMP = 0 ; LED11_TMP = 0 ; LED12_TMP = 0 ; LED13_TMP = 0 ; } //显示指针"秒" if ( DISP_LINE == S_LINE ) { LED06_TMP = 0 ; LED07_TMP = 0 ; LED08_TMP = 0 ; LED09_TMP = 0 ; LED10_TMP = 0 ; LED11_TMP = 0 ; LED12_TMP = 0 ; LED13_TMP = 0 ; } break; case 1: //显示状态1:数字钟 //显示钟摆 i = ZB_LINE - 4 ; //计算钟摆小球的起始行 j = ZB_LINE + 4 ; //计算钟摆小球的终止行 if ( (DISP_LINE >= i ) && (DISP_LINE <= j ) ) { i = DISP_LINE - i + 9*12; PORTB_TMP &= ~LED_TAB_A[i] ; //查表显示钟摆小球的当前列 if ( DISP_LINE == ZB_LINE ) //钟摆线位置判断 { LED06_TMP = 0 ; LED07_TMP = 0 ; LED08_TMP = 0 ; LED09_TMP = 0 ; LED10_TMP = 0 ; LED11_TMP = 0 ; LED12_TMP = 0 ; LED13_TMP = 0 ; } } break; case 2: //显示状态2:温度计 //显示温度曲线 i = 44 ; //定位第0个X轴坐标点 for ( j=0; j<TEMP_LS_QUEUE_SUM; j++ ) { if ( DISP_LINE == i ) //匹配X轴坐标点 { LED07_TMP = 0 ; //画X轴线 i=TEMP_LS_QUEUE[j]; //载入当前坐标点对应的的温度值 if ( i >= TEMP_LSPJ ) //当前历史纪录>=平均温度 { i = i-TEMP_LSPJ; //求差值 //根据差值,显示不同的坐标 switch( i ) { case 0: LED07_TMP = 0 ; break; case 1: LED08_TMP = 0 ; break; case 2: LED09_TMP = 0 ; break; case 3: LED10_TMP = 0 ; break; case 4: LED11_TMP = 0 ; break; default: LED12_TMP = 0 ; break; } } else //当前历史纪录<平均温度 { i = TEMP_LSPJ-i; //求差值 //根据差值,显示不同的坐标 switch( i ) { case 0: LED07_TMP = 0 ; break; case 1: LED06_TMP = 0 ; break; case 2: LED05_TMP = 0 ; break; case 3: LED04_TMP = 0 ; break; case 4: LED03_TMP = 0 ; break; default: LED02_TMP = 0 ; break; } } break; } i = i + 4 ; //定位下一个X轴坐标点 } break; case 3: //显示状态3:闹钟 //显示进度条 if ( ( DISP_LINE > 65 ) && ( DISP_LINE <= ZB_LINE ) ) { LED04_TMP = 0 ; }
if ( ( DISP_LINE > 65 ) && ( DISP_LINE < 115 ) ) { LED03_TMP = 0 ; LED05_TMP = 0 ; } else if ( ( DISP_LINE == 65 ) || ( DISP_LINE == 115 ) ) { LED03_TMP = 0 ; LED04_TMP = 0 ; LED05_TMP = 0 ; } break; default: break; } } /* //设置状态 else { //根据设置状态判断 switch( SET_MODE ) { case 0: //设置状态0:时钟"时" break; case 1: //设置状态1:时钟"分" break; case 2: //设置状态2:闹钟"时" break; case 3: //设置状态3:闹钟"分" break; case 4: //设置状态4:闹铃时间 break; case 5: //设置状态5:报时功能 break; default: break; } } */ //显缓区(字符串队列) 送显示 if ( DISP_QUEUE_FLAG ) //显缓区(字符串队列)开启标志(0=未开启,1=开启) { i = 137 ; //定位字符0起始位置 for ( j=0; j<DISP_QUEUE_SUM; j++ ) { if ( (DISP_LINE >= i) && (DISP_LINE < (i+9) )) //匹配字符位置 { j = DISP_QUEUE[j] ; //载入待显示字符 i = DISP_LINE - i ; i = i + j * 8 ; i = i + j ; PORTB_TMP &= ~LED_TAB_A[i] ; //查表显示当前字符的当前列 PORTB_TMP &= ~LED_TAB_A[ DISP_LINE- i + 9*DISP_QUEUE[j]] ; break; } i = i + 11 ; //定位下一个字符位置 if ( i>=180 ) i = i-180 ; } }
//画外框 LED00_TMP = 0 ; //画内框 LED13_TMP = 0 ;
}
//======== //送显 //======== PORTA = PORTA_TMP ; PORTB = PORTB_TMP ; PORTC = PORTC_TMP ;
} //================ //INT中断 //================ if ( INTF && INTE ) { INTF = 0 ; //清除中断标志 MOTOR_STOP_JSQ = 0 ; //电机停转计时器=0
if ( TIMR1_JSQ < 20 ) { MOTOR_ST_FLAG = 0 ; //电机状态标志=0(0=关闭,1=开启) SET_EN_FLAG = 0 ; //设置使能标志=0(0=禁止,1=使能) } else { MOTOR_ST_FLAG = 1 ; //电机状态标志=1(0=关闭,1=开启)
//调整单列显示时间设置值(模糊控制) if ( TIMR1_JSQ > 180 ) { if ( TIMR1_JSQ > 220 ) DISP_TIME_SET = DISP_TIME_SET - 8 ; else if ( TIMR1_JSQ > 200 ) DISP_TIME_SET = DISP_TIME_SET - 4 ; else if ( TIMR1_JSQ > 185 ) DISP_TIME_SET = DISP_TIME_SET - 2 ; else DISP_TIME_SET = DISP_TIME_SET - 1 ;
if ( DISP_TIME_SET < 400 ) DISP_TIME_SET = 400 ; //钳位 } else if ( TIMR1_JSQ < 180 ) { if ( TIMR1_JSQ < 140 ) DISP_TIME_SET = DISP_TIME_SET + 8 ; else if ( TIMR1_JSQ < 160 ) DISP_TIME_SET = DISP_TIME_SET + 4 ; else if ( TIMR1_JSQ < 175 ) DISP_TIME_SET = DISP_TIME_SET + 2 ; else DISP_TIME_SET = DISP_TIME_SET + 1 ; if ( DISP_TIME_SET > 65100 ) DISP_TIME_SET = 65100 ; //钳位 } }
//计数器处理 TIMR1_JSQ = 0 ; //TIMR1溢出计数器 = 0 DISP_LINE = DISP_LINE_ADJ ; //显示列计数器(0~179)=校正值 }
//================ //TMR0中断 //中断频率=Fosc/(指令周期*TMR0赋初值)=18M/(4*250)=18KHZ //中断周期=1/中断频率=55.556us //================ if ( T0IF && T0IE ) { T0IF = 0 ; //清除中断标志 TMR0 = TMR0 + (256-(250-2)) ; //TMR0赋初值 if ( ++TIME_US > 179 ) //"微秒"+1,结果>最大值? { TIME_US = 0 ; //"微秒"=0 T_10MS_FLAG = 1 ; //10毫秒定时溢出标志=1 } }
//================ //串口接收中断 //================ if ( RCIF && RCIE ) { //说明:RCIF由硬件决定是否清零,不必软件清除 do //循环处理,把硬件缓冲队列中接收到的数据都存入软件缓冲队列 { if ( FERR ) //帧错误? { i = RCREG ; //读取当前发生错误的接收结果,并丢弃 } else { COMM_BUF[COMM_PUT_PTR] = RCREG ; //读取当前接收结果,并存入接收缓冲队列 if ( ++COMM_PUT_PTR >= COMM_BUF_NUM ) COMM_PUT_PTR=0 ; //接收数据存放指针+1,结果>=通讯缓冲区大小,则清零 if ( OERR ) //溢出错误? { CREN = 0 ; CREN = 1 ; //重新复位接收模块,令OERR标志清零 } } } while ( RCIF ) ; //RCIF=1时,说明把硬件缓冲队列中还有待处理的数据 }
} //-------------------------------------------------------- // // THE END // // 版权所有:程序匠人(引用者请保留原作者姓名) // //--------------------------------------------------------
|