相关连接: [匠人DIY旋转时钟 系列文章 (连载中…)]
//--------------------------------------------------------
// 项目:
// 模块:中断服务
// 说明:
// 设计:程序匠人(版权所有,引用者请保留原作者姓名)
//--------------------------------------------------------
/*
版本说明:
Interruption.c 2008-2-10 15:36
*/
//--------------------------------------------------------
//--------------------------------------------------------
//插入文件包
//--------------------------------------------------------
#include "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 ; //查表显示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 ; //查表显示钟摆小球的当前列
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 {
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 {
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 ; //查表显示当前字符的当前列 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
//
// 版权所有:程序匠人(引用者请保留原作者姓名)
//
//--------------------------------------------------------
文章评论(0条评论)
登录后参与讨论