发表于:2005-09-14 00:11:00
77楼
发一段程序大家看看,是可执行的,我已经标注每句程序的作用了,望有兴趣的朋友互相探讨.
;建锋电子技术服务部 HTTP://JFDZMCU.COM
; JFDZ16888@163.COM
;4位0-9999LED的数码管计数显示学习程序
;由于84a的资源较少,采用了扩展芯片74ls47n,动态扫描显示
;*********************************************************
LIST P=PIC16F84A ;列表选芯片型号
#INCLUDE P16F84A.INC
__CONFIG B'11111111110001';_CP_OFF&_WDT_OFF&_PWRITE_ON&_XT_OSC
;没有代码保护
;看门狗关
;上电廷时器开
;XT振荡模式
;*******************************************************
RTCC EQU 01H ;定义各寄存器
PC EQU 02H
STATUS EQU 03H
C EQU 0
RP0 EQU 5
;----------------------
PORTA EQU 05H
TRISA EQU 85H
PORTB EQU 06H
TRISB EQU 86H
LONE EQU 1FH ;对LED数码管的6位,选定位选
CONE EQU 1EH ;和各位的送数寄存器地址
COUNT1 EQU 1DH
LTWO EQU 1CH
CTWO EQU 1BH
COUNT2 EQU 1AH ;为了人眼视觉观察,选定延时寄存器
COUNT3 EQU 19H ;地址
COUNT4 EQU 18H
COUNT5 EQU 17H
COUNT6 EQU 16H
COUNT7 EQU 28H
COUNT8 EQU 28H
LTHREE EQU 27H
CTHREE EQU 26H
LFOR EQU 25H
CFOR EQU 24H
;********************************************************
ORG 0000H ;复位矢量
GOTO START
ORG D'20' ;从地址D'20'开始存放程序
START
BSF STATUS,RP0 ;选储存体BANK1
MOVLW B'00010000'
MOVWF TRISA ;设A口第4位为输入
MOVLW B'00000000'
MOVWF TRISB ;设B口为输出
BCF STATUS,RP0 ;恢复数据寄存器体0
;************************************************************
MOVLW 0
MOVWF PORTB
LOOP BTFSC PORTA,4 ;人工启动计数
GOTO LOOP
DISP0 CLRF LONE ;对1-4位的位选和1-4位的计数位
CLRF CONE ;清零
CLRF COUNT1
CLRF LTWO
CLRF CTWO
CLRF LTHREE
CLRF CTHREE
CLRF LFOR
CLRF CFOR
CLRF COUNT6
CALL DISPLY ;调用显示子程序
GOTO SCAN ;跳到SCAN执行
SCAN BTFSS PORTA,4 ;判断A口第4位,
GOTO INCK ;为1,没按下,继续判断,
INCK INCF LONE,0 ;LONE+1存入W
ANDLW B'00001111' ;W内容清高4位,保护低4位,存入W
XORLW B'00001010' ;LONE+1与常数10比较
BTFSS STATUS,Z ;LONE+1为9吗?(到9时,Z变为1)
GOTO NOCY01 ;否,跳转到LED的第一位继续计数
GOTO LOP2 ;是,跳转到第2位的位选
NOCY01 INCF LONE,1 ;LONE继续加一,存到本身
MOVF LONE,0 ;把LONE+1后的数据送W
ANDLW B'00001111' ;W内容清高4位,保护低4位,再存入W
MOVWF CONE ;再把W的数据送CONE寄存器
CALL DISPLY ;调用显示程序
GOTO SCAN ;跳转到标号处继续判断
;*********************************************
LOP2 CLRW ;0送W
INCF LTWO,0 ;LTWO+1存入W
ANDLW B'00001111' ;W内容清高4位,保护低4位,存入W
XORLW B'00001010' ;LTWO+1与常数10比较
BTFSS STATUS,Z ;LTWO+1为9吗?(到9时,Z变为1)
GOTO NOCY02 ;否,跳转到LED的第2位继续计数
GOTO LOP3 ;是,跳转到第3位的位选
NOCY02 INCF LTWO,1 ;LTWO继续加一,存到本身
MOVF LTWO,0 ;把LTWO+1后的数据送W
ANDLW B'00001111' ;W内容清高4位,保护低4位,再存入W
MOVWF CTWO ;再把W的数据CTWO送寄存器
CLRF LONE ;清零第一位的位选寄存器
CLRF CONE ;和第一位寄存器的数据
CALL DISPLY ;调用显示程序
GOTO SCAN ;跳转到标号处继续判断
LOP3 CLRW ;0送W
INCF LTHREE,0 ;LTHREE+1存入W
ANDLW B'00001111' ;W内容清高4位,保护低4位,存入W
XORLW B'00001010' ;LTHREE+1与常数10比较
BTFSS STATUS,Z ;LTHREE+1为9吗?(到9时,Z变为1)
GOTO NOCY03 ;否,跳转到LED的第3位继续计数
GOTO LOP4 ;是,跳转到第4位的位选
NOCY03 INCF LTHREE,1 ;LTHREE继续加一,存到本身
MOVF LTHREE,0 ;把LTHREE+1后的数据送W
ANDLW B'00001111' ;W内容清高4位,保护低4位,再存入W
MOVWF CTHREE ;再把W的数据送CTHREE寄存器
CLRF LONE ;清零第1,2位的位选寄存器
CLRF CONE ;和第1,2位寄存器的数
CLRF LTWO
CLRF CTWO
CALL DISPLY ;调用显示程序
GOTO SCAN ;跳转到标号处继续判断
LOP4 CLRW ;0送W
INCF LFOR,0 ;LFOR+1存入W
ANDLW B'00001111' ;W内容清高4位,保护低4位,存入W
XORLW B'00001010' ;LFOR+1与常数10比较
BTFSS STATUS,Z ;;LFOR+1为9吗?(到9时,Z变为1)
GOTO NOCY04 ;否,跳转到LED的第4位继续计数
GOTO DISP0 ;是,跳转到起始位.
NOCY04 INCF LFOR,1 ;LFOR继续加一,存到本身
MOVF LFOR,0 ;把LFOR+1后的数据送W
ANDLW B'00001111' ;W内容清高4位,保护低4位,再存入W
MOVWF CFOR ;再把W的数据送CFOR寄存器
CLRF LONE ;清零第1,2,3位的位选寄存器
CLRF CONE ;和第1,2,3位寄存器的数
CLRF LTWO
CLRF CTWO
CLRF LTHREE
CLRF CTHREE
CALL DISPLY ;调用显示程序
GOTO SCAN ;跳转到标号处继续判断
;*********************************************
DISPLY MOVLW D'34' ;计数显示34次同一值
MOVWF COUNT2
LOOP5 BSF PORTA,0 ;关第1位LED
BSF PORTA,1 ;关第2位LED
BSF PORTA,2 ;关第3位LED
BSF PORTA,3 ;关第4位LED
CALL A7MS ;调用关闭延时
q SWAPF PORTB,0 ;取B口数据半字节交换后存入W
ANDLW B'11110000' ;高4位不变,低4位清零存入W
ADDWF CONE,0 ;W内的数据与CONE内的数据相加存入W
MOVWF COUNT1 ;把W内的数据存入COUNT1
SWAPF COUNT1,0 ;COUNT1内的数据半字节交换后存入W
MOVWF PORTB ;第一位数送B口显示
BCF PORTA,3 ;第一位数的位显打开
CALL B5MS ;延时观察
BSF PORTA,3 ;关闭第一位
CALL A7MS ;延时
q2 SWAPF PORTB,0 ;取B口数据半字节交换后存入W
ANDLW B'11110000' ;高4位不变,低4位清零存入W
ADDWF CTWO,0 ;W内的数据与CTWO内的数据相加存入W
MOVWF COUNT1 ;把W内的数据存入COUNT1
SWAPF COUNT1,0 ;COUNT1内的数据半字节交换后存入W
MOVWF PORTB ;第2位数送B口显示
BCF PORTA,2 ;第2位数的位显打开
CALL B5MS ;延时观察
BSF PORTA,2 ;关闭第2位
CALL A7MS ;延时
q3 SWAPF PORTB,0 ;取B口数据半字节交换后存入W
ANDLW B'11110000' ;高4位不变,低4位清零存入W
ADDWF CTHREE,0 ;W内的数据与CTHREE内的数据相加存入W
MOVWF COUNT1 ;把W内的数据存入COUNT1
SWAPF COUNT1,0 ;COUNT1内的数据半字节交换后存入W
MOVWF PORTB ;第3位数送B口显示
BCF PORTA,1 ;第3位数的位显打开位
CALL B5MS ;延时观察
BSF PORTA,1 ;关闭第3位
CALL A7MS ;延时
q4 SWAPF PORTB,0 ;取B口数据半字节交换后存入W
ANDLW B'11110000' ;高4位不变,低4位清零存入W
ADDWF CFOR,0 ;W内的数据与CFOR内的数据相加存入W
MOVWF COUNT1 ;把W内的数据存入COUNT1
SWAPF COUNT1,0 ;COUNT1内的数据半字节交换后存入W
MOVWF PORTB ;第4位数送B口显示
BCF PORTA,0 ;第4位数的位显打开位
CALL B5MS ;延时观察
BSF PORTA,0 ;关闭第4位
CALL A7MS ;延时
DECFSZ COUNT2,1 ;同一值重复显示34次结束
GOTO LOOP5 ;跳到标号LOOP5处
MOVLW B'00011111'
MOVWF PORTA
RETURN ;返回到调用程序下一条
A7MS MOVLW H'13' ;延时程序
MOVWF COUNT3
DECFSZ COUNT3,1
GOTO $-1
RETURN ;调用返回
B5MS MOVLW D'10' ;延时程序以便观察LED的显示
MOVWF COUNT4
DDY1 MOVLW D'10'
MOVWF COUNT5
DDY2 DECFSZ COUNT5,1
GOTO DDY2
DECFSZ COUNT4,1
GOTO DDY1
RETURN ;调用返回
DELAY1 DECFSZ COUNT7,1
GOTO DELAY1
DECFSZ COUNT8,1
GOTO DELAY1
RETURN
;***************************************************
END ;结束