PCA定时器跑马灯

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PCA软件定时器实现跑马灯

值得注意的是:与一般的51单片机定时器不同,PCA软件定时/计数方式有2种:

①与一般定时器一样的功能,从给定初始值开始计数直到计数到十六进

制数0FFFFH后产生定时器溢出以及溢出中断。

②从给定初始值开始计数直到计数到一个给定的比较门限值后产生定时

器溢出以及溢出中断。

这里我们采用第二种软件定时器延时方法。

思路:设置PCA定时器的脉冲时钟频率,清计数器并设置比较门限值,使定时时间为50ms;然后设置定时器工作在16位计数器模式;设置使能中断,启动PCA

定时/计数器开始计数。当计数器值与比较门限值相等时,就转到PCA中断程序。中断时,先关闭中断,并清中断标志;然后清除计数器,并自加计数寄存

器,当为20时(20*50ms=1s)则判断第四个灯是否亮过。若亮过则转第一个灯亮,否则就亮相应的灯,然后再开中断并返回主程序。若计数寄存器不为20

PCA计数器计数频率为11.0592M/12分频=0.9216M,注意,11.0592M是单片机晶体振荡器的振荡频率。

计数周期=1/0.9216M=1.085μs

定时时间为50ms时所需计数次数为50ms/1.085μs=46083=B403H

流程图如下所示

程序如下:

;-----------------------------------------------------

;定义寄存器地址

CMOD EQU 0D9H

CCON EQU 0D8H

CH EQU 0F9H

CL EQU 0E9H

CCAPM0 EQU 0DAH

CCAP0H EQU 0FAH

CCAP0L EQU 0EAH

CR EQU CCON.6

CCF0 EQU CCON.0

;------------------------------------------------------

ORG 0000H

AJMP MAIN

ORG 0033H ;PCA中断入口

AJMP INTV

ORG 0050H

MAIN: MOV CMOD,#00H;设置PCA脉冲时钟为Fosc/12 MOV R0,#0EFH

MOV P1,R0

MOV R1,#00H

;--------------------------------------

;PCA计数器清零

MOV CH,#00H

MOV CL,#00H

;--------------------------------------

;设置PCA比较/捕获模块寄存器值

MOV CCAP0L,#3

MOV CCAP0H,#0B4H

;--------------------------------------

;设置PCA模式为比较:软件定时器

MOV CCAPM0,#49H

MOV IE,#0C0H ;使能中断

SETB CR ;PCA计数器开始计数

WAIT: AJMP WAIT ;等待中断

;--------------------------------------

;中断服务程序

INTV: MOV A,IE ;停止中断

ANL A,#0BFH

MOV IE,A

CLR CCF0 ;清中断标志

MOV CH,#00H ;清计数器

MOV CL,#00H

INC R1

CJNE R1,#14H,NEXT ;中断20次则执行下面程序,否则到NEXT开中断MOV R1,#00H

MOV A,R0

RL A

MOV R0,A

CJNE R0,#0FEH,START ;判断第四个灯没亮过则点亮,否则转到第一个灯MOV R0,#0EFH

START:MOV P1,R0

NEXT: MOV A,IE ;开中断

ORL A,#40H

MOV IE,A

RETI

END

/* case 3:{//保存高报警值

gas.ErrorValue=gas.TempDataValue;

gas.StopTime=0;gas.Menuflag=4;

SaveSystemData();

}break;

case 4:{//零点标定

if(stPPMValue

{

gas.SystemStatusFlag|=CAL_MIN_FLAG;

}

gas.StopTime=0;gas.Menuflag=5;

}break;

case 5:{//量程标定

if(stPPMValue>gas.WarnValue)

{

gas.CalibrateValue=gas.TempDataValue;

gas.SystemStatusFlag|=CAL_MAX_FLAG;

}

gas.StopTime=0;gas.Menuflag=0;

}break;

}

gas.KeyValueTime[0]=0;

gas.KeyValue=0;

}

/////////////////////SET键进入////////////////////

/* if(gas.KeyValueTime[0]>20)

{

switch(gas.Menuflag)

{

case 0:{ gas.Menuflag=1;

gas.TempDataValue=550;

}break;

case 2:{//保存低报警值

gas.WarnValue=gas.TempDataValue;

gas.StopTime=0;gas.Menuflag=3;

SaveSystemData();

}break;

case 3:{//保存高报警值

gas.ErrorValue=gas.TempDataValue;

gas.StopTime=0;gas.Menuflag=4;

SaveSystemData();

}break;

case 4:{//零点标定

if(stPPMValue

{

gas.SystemStatusFlag|=CAL_MIN_FLAG;

}

gas.StopTime=0;gas.Menuflag=5;

}break;

case 5:{//量程标定

if(stPPMValue>gas.WarnValue)

{

gas.CalibrateValue=gas.TempDataValue;

gas.SystemStatusFlag|=CAL_MAX_FLAG;

}

gas.StopTime=0;gas.Menuflag=0;

}break;

相关文档
最新文档