金沙js5线路(中国)有限公司

技术热线: 4007-888-234

LCD时钟的总结,并由中断暂禁的后果说开去

更新时间: 2019-03-23
阅读量:2067

十年专注单片机方案开发的方案公司金沙js5线路,分享LCD时钟的总结,并由中断暂禁的后果说开去。金沙js5线路现提供服务产品涉及主控芯片:8位单片机、16位单片机、32位单片机及各类运算放大器等。

;********************************************************************** ; ; Filename:lcd_time.asm ; Date:11-11-2004 ; File Version: v1.0 ; ; Author: Liyu ; Company: 614 ; ; ;********************************************************************** ; ; Notes: 为使分析完善,贴出这个还可以进行许多优化的源程序... ; 该程序是遵循上文提到的方案二而修改的,运行时的情况如上文所 ; 分析。小弟将对程序结构进行优化... ; 有PIC16的MCD1/2的初学者可用该程序直接DEMO板调试运行... ; 一旦汇编语言的代码较长时,就很怀念C语言了,呵呵 ; ;********************************************************************** list p=16f877 ; list directive to define processor #include ; processor specific variable definitions ;__CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _RC_OSC & _WRT_ENABLE_ON & _LVP_ON & _DEBUG_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration 

word. ;meanings:_CP_OFF,Code_Protect Off;_WDT_ON,WatchDog On;_BOOEN_ON, ;_PWRTE_ON,Power_On delay timer On;_RC_OSC,RC OSC surge; ;***** VARIABLE DEFINITIONS w_temp EQU 0x70 ; variable used for context saving status_temp EQU 0x71 ; variable used for context saving pclath_temp EQU 0x72 fsr_temp EQU 0x73 RS EQU 1 RW EQU 2 E EQU 3 ;************************** cblock 0x20 hour min sec ms50 us :2 count tmp1 x y bin bcd_h bcd_l count1 endc cblock 0x30 ; 定义待显示的字符 space1 space2 space3 space4 hour_h hour_l colon1 min_h min_l colon2 sec_h sec_l space5 space6 space7 space8 endc ;*******************************************************************888 ORG 0x000 ; processor reset vector nop ; ICD need goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movfw STATUS ; move status register into W register clrf STATUS movwf status_temp ; save off contents of STATUS register movfw 

PCLATH movwf pclath_temp movfw FSR movwf fsr_temp ; ; 中断服务代码 btfss INTCON,T0IE ; 判断是否为T0中断 goto other_int btfss INTCON,T0IF ; it 's the time of T0 int goto other_int bcf INTCON,T0IF ; 是T0中断,清除中断标志 movlw 0x10 ; 微秒的高位字节加上定时时间 256x16分频=4096=0x1000的高位(0x10) addwf us+1 goto end_int other_int ; 其他中断服务代码 nop ; other isr code can be added end_int clrf STATUS movfw fsr_temp movwf FSR movfw pclath_temp movwf PCLATH movfw status_temp ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;****************************************** ;LCM显示时间 main nop call _init call _convert call _disp1 call _disp2 loop call _clock goto loop ;****************这里将_table1放在前面是权宜之计,可以不对PCLATH进行处理 _table1 ;取第一行的显示码 addwf PCL ;地址偏移量加当前PC值 dt " 

HH MM SS " retlw 00H ;****************************************** _init movlw 0x20 ; clear bank0 movwf FSR clear clrf INDF incf FSR btfss FSR,7 goto clear banksel OPTION_REG movlw b'00000011' movwf OPTION_REG clrf INTCON bsf INTCON,T0IE bsf INTCON,GIE banksel PORTC ; T0初始化完毕 banksel ADCON1 movlw 07H movwf ADCON1 ;设置RA口全部为普通数字IO口 clrf TRISA clrf TRISC ; 定义RA口,RC口全部为输出 bcf STATUS,RP0 call _delay50ms ;调用廷时,刚上电LCD复位不一定有PIC快 movlw 01H movwf PORTC ; 清屏 call _enable movlw 38H movwf PORTC ; 8位数据,16字x2行,5x7点阵 call _enable movlw 0CH ; 显示器开、光标不闪 movwf PORTC call _enable movlw 06H ; 文字不动,光标自动右移 movwf PORTC call _enable movlw 80H movwf PORTC ; 第一行显示位置 call _enable return ;**********************************8 _clock bcf INTCON,T0IE movlw 0xb0 addwf us movlw 0x3c skpnc movlw 0x3d addwf us+1 skpnc goto 

ms_time_out movlw 0x50 addwf us movlw 0xc3 skpnc movlw 0xc4 addwf us+1 goto clock_exit ms_time_out incf ms50 ; 50ms计数器加1 movlw d'20' xorwf ms50,w ; ms50=20? skpz ; 是则跳过下条指令 goto clock_exit ; 否,1s时间未到 clrf ms50 ; 到1s,则清50ms计数器 incf sec ; 秒数加1 movlw d'60' xorwf sec,w skpz goto clock_exit1 clrf sec ;*************** movfw sec movwf bin call _bin_bcd movlw 0x30 ; 将秒数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0caH movwf PORTC ; 设定秒区显示位置 call _enable movfw sec_h call _write movfw sec_l call _write ; 显示秒值 ;***************************************** incf min movlw d'60' xorwf min,w skpz goto clock_exit2 clrf min ; !!!!!!!!!!!!!!!!!!!! movfw min movwf bin call _bin_bcd movlw 0x30 ; 将分钟数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0c7H movwf PORTC ; 设定分钟区显示位置 call _enable movfw min_h call _write movfw min_l call _write ; 显示分钟

值 ;******************************** incf hour movlw d'24' xorwf hour,w skpz goto clock_exit3 clrf hour ;************************************* movfw hour movwf bin call _bin_bcd movlw 0x30 ; 将小时的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf hour_h movfw bcd_l movwf hour_l movlw 0c4H movwf PORTC ; 设定小时的显示位置 call _enable movfw hour_h call _write movfw hour_l call _write ; 显示小时值 ;********************************* goto clock_exit clock_exit1 ;*************** movfw sec movwf bin call _bin_bcd movlw 0x30 ; 将秒数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0caH movwf PORTC ; 设定第二行显示位置 call _enable movfw sec_h call _write movfw sec_l call _write goto clock_exit ;*************** clock_exit2 movfw min movwf bin call _bin_bcd movlw 0x30 ; 将秒数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h 

addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0c7H movwf PORTC ; 设定第二行显示位置 call _enable movfw min_h call _write movfw min_l call _write goto clock_exit ;********************************* clock_exit3 movfw hour movwf bin call _bin_bcd movlw 0x30 ; 将秒数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf 

hour_h movfw bcd_l movwf hour_l movlw 0c4H movwf PORTC ; 设定第二行显示位置 call _enable movfw hour_h call _write movfw hour_l call _write goto clock_exit clock_exit bsf INTCON,T0IE return ;**************************************** _disp1 clrf count ; 送第一行数字程序 again1 movf count,W ; 显示 HH MM SS call _table1 movwf tmp1 call _write incf count movf tmp1,W xorlw 00H btfss STATUS,Z goto again1 return ;**************************************** _convert movfw hour ; 将小时数转换成两位BCD码 movwf bin call _bin_bcd movlw 0x30 ; 将小时的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf hour_h movfw bcd_l movwf hour_l movlw 0x3a movwf colon1 ; 将冒号:的ASCII码填入显示缓冲区 movfw min movwf bin call _bin_bcd movlw 0x30 ; 将分钟的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0x3a movwf colon2 ; 将冒号:

的ASCII码填入显示缓冲区 movfw sec movwf bin call _bin_bcd movlw 0x30 ; 将秒数的两位BCD码转换成对应的ASCII码字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0x20 movwf space1 ; 将第二行时间后的显示区域用空格填满 movwf space2 movwf space3 movwf space4 movwf space5 ; 将第二行时间后的显示区域用空格填满 movwf space6 movwf space7 movwf space8 return ;**************************************** _disp2 movlw 0c0H movwf PORTC ; 设定第二行显示位置 call _enable movlw 0x10 ; 共显示16个字符 movwf count1 movlw 0x30 ; 获取显示缓冲区的首地址 movwf FSR ; 取得显示字符的地址 again2 movfw INDF ; 间接寻址获取字符ASCII码 call _write ; 输出到LCD显示 incf FSR decfsz count1 ; 若显示完毕,则退出,否则继续显示下一字符 goto again2 retlw 0 ;**************************************** 

_write ;送数据到LCD子程序 movwf PORTC bsf PORTA,RS bcf PORTA,RW bcf PORTA,E call _delay50ms bsf PORTA,E retlw 0 ;*********写入控制命令的子程序 _enable bcf PORTA,RS bcf PORTA,RW bcf PORTA,E call _delay50ms bsf PORTA,E retlw 0 ;******************************88 _delay50ms movlw 0x40 ;晶振为4 Mhz,延时约16ms movwf x loop_x movlw 0xff movwf y loop_y decfsz y goto loop_y decfsz x goto loop_x return ;************************** _bin_bcd ; 因为秒分钟小时的值不大于60,故采用此BCD码子程序来转换 movfw bin clrf bcd_h gtenth movwf bcd_l movlw d'10' subwf bcd_l,w skpc goto exit movwf bcd_l incf bcd_h goto gtenth exit retlw 0 ;**************************** end ;源程序结束

XML 地图