專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命
提供開發(fā)工具、應(yīng)用測試 完善的開發(fā)代碼案例庫分享
從全面的產(chǎn)品導(dǎo)入到強大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無限潛能!
提供新的芯片及解決方案,提升客戶產(chǎn)品競爭力
提供最新的單片機資訊,行業(yè)消息以及公司新聞動態(tài)
十年專注單片機方案開發(fā)的方案公司英銳恩,分享LCD時鐘的總結(jié),并由中斷暫禁的后果說開去。英銳恩現(xiàn)提供服務(wù)產(chǎn)品涉及主控芯片:8位單片機、16位單片機、32位單片機及各類運算放大器等。
;********************************************************************** ; ; Filename:lcd_time.asm ; Date:11-11-2004 ; File Version: v1.0 ; ; Author: Liyu ; Company: 614 ; ; ;********************************************************************** ; ; Notes: 為使分析完善,貼出這個還可以進(jìn)行許多優(yōu)化的源程序... ; 該程序是遵循上文提到的方案二而修改的,運行時的情況如上文所 ; 分析。小弟將對程序結(jié)構(gòu)進(jìn)行優(yōu)化... ; 有PIC16的MCD1/2的初學(xué)者可用該程序直接DEMO板調(diào)試運行... ; 一旦匯編語言的代碼較長時,就很懷念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 ; ; 中斷服務(wù)代碼 btfss INTCON,T0IE ; 判斷是否為T0中斷 goto other_int btfss INTCON,T0IF ; it 's the time of T0 int goto other_int bcf INTCON,T0IF ; 是T0中斷,清除中斷標(biāo)志 movlw 0x10 ; 微秒的高位字節(jié)加上定時時間 256x16分頻=4096=0x1000的高位(0x10) addwf us+1 goto end_int other_int ; 其他中斷服務(wù)代碼 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放在前面是權(quán)宜之計,可以不對PCLATH進(jìn)行處理 _table1 ;取第一行的顯示碼 addwf PCL ;地址偏移量加當(dāng)前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 ;設(shè)置RA口全部為普通數(shù)字IO口 clrf TRISA clrf TRISC ; 定義RA口,RC口全部為輸出 bcf STATUS,RP0 call _delay50ms ;調(diào)用廷時,剛上電LCD復(fù)位不一定有PIC快 movlw 01H movwf PORTC ; 清屏 call _enable movlw 38H movwf PORTC ; 8位數(shù)據(jù),16字x2行,5x7點陣 call _enable movlw 0CH ; 顯示器開、光標(biāo)不閃 movwf PORTC call _enable movlw 06H ; 文字不動,光標(biāo)自動右移 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計數(shù)器加1 movlw d'20' xorwf ms50,w ; ms50=20? skpz ; 是則跳過下條指令 goto clock_exit ; 否,1s時間未到 clrf ms50 ; 到1s,則清50ms計數(shù)器 incf sec ; 秒數(shù)加1 movlw d'60' xorwf sec,w skpz goto clock_exit1 clrf sec ;*************** movfw sec movwf bin call _bin_bcd movlw 0x30 ; 將秒數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0caH movwf PORTC ; 設(shè)定秒?yún)^(qū)顯示位置 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 ; 將分鐘數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0c7H movwf PORTC ; 設(shè)定分鐘區(qū)顯示位置 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碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf hour_h movfw bcd_l movwf hour_l movlw 0c4H movwf PORTC ; 設(shè)定小時的顯示位置 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 ; 將秒數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0caH movwf PORTC ; 設(shè)定第二行顯示位置 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 ; 將秒數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h
addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0c7H movwf PORTC ; 設(shè)定第二行顯示位置 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 ; 將秒數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf
hour_h movfw bcd_l movwf hour_l movlw 0c4H movwf PORTC ; 設(shè)定第二行顯示位置 call _enable movfw hour_h call _write movfw hour_l call _write goto clock_exit clock_exit bsf INTCON,T0IE return ;**************************************** _disp1 clrf count ; 送第一行數(shù)字程序 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 ; 將小時數(shù)轉(zhuǎn)換成兩位BCD碼 movwf bin call _bin_bcd movlw 0x30 ; 將小時的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf hour_h movfw bcd_l movwf hour_l movlw 0x3a movwf colon1 ; 將冒號:的ASCII碼填入顯示緩沖區(qū) movfw min movwf bin call _bin_bcd movlw 0x30 ; 將分鐘的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf min_h movfw bcd_l movwf min_l movlw 0x3a movwf colon2 ; 將冒號:
的ASCII碼填入顯示緩沖區(qū) movfw sec movwf bin call _bin_bcd movlw 0x30 ; 將秒數(shù)的兩位BCD碼轉(zhuǎn)換成對應(yīng)的ASCII碼字符 addwf bcd_h addwf bcd_l movfw bcd_h movwf sec_h movfw bcd_l movwf sec_l movlw 0x20 movwf space1 ; 將第二行時間后的顯示區(qū)域用空格填滿 movwf space2 movwf space3 movwf space4 movwf space5 ; 將第二行時間后的顯示區(qū)域用空格填滿 movwf space6 movwf space7 movwf space8 return ;**************************************** _disp2 movlw 0c0H movwf PORTC ; 設(shè)定第二行顯示位置 call _enable movlw 0x10 ; 共顯示16個字符 movwf count1 movlw 0x30 ; 獲取顯示緩沖區(qū)的首地址 movwf FSR ; 取得顯示字符的地址 again2 movfw INDF ; 間接尋址獲取字符ASCII碼 call _write ; 輸出到LCD顯示 incf FSR decfsz count1 ; 若顯示完畢,則退出,否則繼續(xù)顯示下一字符 goto again2 retlw 0 ;****************************************
_write ;送數(shù)據(jù)到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碼子程序來轉(zhuǎn)換 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 ;源程序結(jié)束