Отговори на тема  [ 3 мнения ] 
Няколко стари програми за PIC16F877 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пон Авг 24, 2020 3:45 pm
Мнения: 169
Местоположение: София, Люлин 3
Мнение Няколко стари програми за PIC16F877
Здравейте! Имам няколко стари разработки на програми за мониторинг на FM предаватели. Тези програми са правени за една фирма, отдавна престанала да произвежда предаватели, а и вече и тя не съществува. Самите предаватели (20-тина броя) най-вероятно са претопени като скрап. Тук ще ви представя една за мониторинг на 30W трансмитер (по-скоро възбудител за мощно стъпало), която чрез избор на оператора може да измерва и показва следните параметри: мощност (падаща и обратна) към антената (мощния усилвател), честота, напрежение и ток на изходното стъпало, аудио сигнала L и R. Индикацията е стандартен двуредов LCD индикатор (LCD MODULE VSTM-1602B например) като се използва четири шинно прехвърляне на данните. Честотата не се измерва, а се изчислява по позициите на задаващите суитчове в синтезатора (използван е фабричен италиански синтезатор). За измерване на сигналите P, U и I се използват аналоговите входове на PIC. Мощността се измерва като напрежителен сигнал от насочен отклонител (реализиран като пасивни линии около изходната писта на печатната платка и съответни товарни резистори и диоди). По интересна е визуализацията на аудио сигнала като бар ленти, работещи в реално време - точно както са в модерните аудиосистеми с LCD индикатори. Публикувам ASM файл с учебна цел, така, че и начинаещи да могат да го разберат и да ползват фрагменти, които им допадат за нови разработки. Всъщност, "стари" програми няма, има нови процесори, нови езици, но принципите на програмирането си остават същите. Разбира се, стилът на програмиране зависи от програмиста, но този, който сега се учи, е добре да се запознае с различни стилове за да "отбере" онова, което му допада най-много.
Тъй като едва ли някой ще повтори програмата едно към едно, не привеждам схемата (която не съм разработвал аз и безвъзвратно съм загубил, все пак това е от 2005г!)
Ако има интерес, мога да представя програма за мониторинг на 1KW мощен усилвател, съставен от две стъпала по 500W, като там се контролират двете стъпала поотделно, както и общите мощности, подавани към фидера.
Имам и програми за управление ва несложни машинарии (нарязващи, преси и др.). За тях има по-пълни описания със схеми. За съжаление, нито от предавателите, нито от машинариите има образци за демонстрации, тъй като всичко е заминало за скрап.
Код:
       include <p16f877.inc>
;
;
;TU30_217.asm
;EXPRESS
;
;Signal bits
EN      EQU   0   ; LCD Enable control line
RW      EQU   1   ; LCD Read/write control line
RS      EQU   2   ; LCD Register-Select control line
EX      EQU   4   ; External fault
PK      EQU   5   ; Offset 50KHz
UL      EQU   6   ; Unlock
UP      EQU   7   ; Key up
;
;Flags bits
FK      EQU   0   ; Key push
FO      EQU   1   ; Over message position
FZ      EQU   2   ; First zero
;
;Ports assigments
LCD_PORT   EQU   PORTB   ; LCD data&control lines interface
EX_CON      EQU   PORTC   ;
FREQ_H      EQU   PORTC   ;
FREQ_L      EQU   PORTD   ;
;
;Variables
DELAY_1      EQU   0x20   ;
DELAY_2      EQU   0x21   ;
CHAR_F      EQU   0x22   ;
COMMAND_F   EQU   0x23   ;
H_BYTE      EQU     0x24   ; High byte of the 16 bit result
L_BYTE      EQU     0x25   ; Low byte of the 16 bit result
COUNT_B      EQU   0x26   ; loop counter B
R0      EQU     0x27   ;
R1      EQU   0x28   ; RAM for output BCD
R2      EQU   0x29   ;
TEMP_F      EQU   0x2A   ;
ACCaLO      EQU     0x2B   ;
ACCaHI      EQU     0x2C   ;
ACCbLO      EQU     0x2D   ;
ACCbHI      EQU     0x2E   ;
ACCcLO      EQU     0x2F   ;
ACCcHI      EQU     0x30   ;
ACCdLO      EQU     0x31   ;
ACCdHI      EQU     0x32   ;
K_COUNT      EQU   0x33   ;
PAUSE_1      EQU   0x34   ;
PAUSE_2      EQU   0x35   ;
PAUSE_3      EQU   0x36   ;
FLAGS      EQU   0x37   ;
POS      EQU   0x38   ;
DEV_BYTE   EQU   0x39   ;
COUNT_C      EQU   0x3A   ;
COUNT_D      EQU   0x3B   ;
MPY_F      EQU   0x3C   ;
DEV_SKIP   EQU   0x3D   ;
;
;Constants
DisplayON   EQU   0x00C   ;      
DdramADDR   EQU   0x080   ;         
;
;
   org     0
        goto    Start           
;       
        org     4
   goto   Start      ;
;
Start
;
   call   INIT      ;
   call   ExtFault   ;
   call   Unlock      ;
main
   call   Route      ;
   goto   main      ;
;   
;
;*******************************************************************************;
;
; - Used in LCDINIT subroutine
; - Required delay factor must be in W
;************************************ a 500uS delay @ 4MHz X-tal
;
X500MKS
   MOVWF   DELAY_2      ;
DLOOPB   MOVLW   0x0A5      ;
   MOVWF   DELAY_1      ;
DLOOPA   DECFSZ   DELAY_1,f   ;
   GOTO   DLOOPA      ;
   DECFSZ   DELAY_2,f   ;
   GOTO   DLOOPB      ;
   RETURN         ;
;
INIT
   CALL   PAUSE2S      ;
   CALL   SETLCD      ;
   CALL   LCDCLEAR   ;
   BSF   STATUS, RP0     ; Bank 1
   BCF   STATUS, RP1    ; 
   MOVLW   B'11111111'   ;       
   MOVWF   PORTA      ; inputs
   MOVWF   PORTC      ; inputs 
   MOVWF   PORTD      ; inputs       
   BCF   STATUS, RP0     ; Bank 0
   CLRF   FLAGS      ;
   call   CountInit   ;
   CALL   ADCINIT      ;
   RETURN          ;   
;
ADCINIT
   BSF   STATUS,RP0   ;
   MOVLW   B'10000000'     ; Result is right justified
   MOVWF   ADCON0          ; select ch0-ch7 as analog inputs
   BCF   STATUS,RP0    ;
   RETURN         ;
;
PAUSE05S
   MOVWF   TEMP_F      ;
   MOVLW   0x01      ;
   MOVWF   PAUSE_3      ;
LOOPP_3   MOVLW   0xFF      ;
   MOVWF   PAUSE_2      ;
LOOPP_2   CLRWDT         ;
   MOVLW   0xFF      ;
   MOVWF   PAUSE_1      ;
LOOPP_1   DECFSZ   PAUSE_1,f   ;
   GOTO   LOOPP_1      ;
   DECFSZ   PAUSE_2,f   ;
   GOTO   LOOPP_2      ;
   DECFSZ   PAUSE_3,f   ;
   GOTO   LOOPP_3      ;
   MOVF   TEMP_F,w   ;
   RETURN         ;
;   
PAUSE2S
   MOVWF   TEMP_F      ;
   MOVLW   0x04      ;
   MOVWF   PAUSE_3      ;
LOOPP_6   MOVLW   0xFF      ;
   MOVWF   PAUSE_2      ;
LOOPP_5   CLRWDT         ;
   MOVLW   0xFF      ;
   MOVWF   PAUSE_1      ;
LOOPP_4   DECFSZ   PAUSE_1,f   ;
   GOTO   LOOPP_4      ;
   DECFSZ   PAUSE_2,f   ;
   GOTO   LOOPP_5      ;
   DECFSZ   PAUSE_3,f   ;
   GOTO   LOOPP_6      ;
   MOVF   TEMP_F,w   ;
   RETURN         ;
;
; Test LCD busy flag (DB7 from HD44780)
;
LCDBUSY
   BSF   STATUS,RP0   ; Select Register page 1
   MOVLW   0xF0      ; Set PORTB for input
   MOVWF   LCD_PORT   ;
   BCF   STATUS,RP0   ; Select Register page 0
   BCF   LCD_PORT, RS   ; Set LCD for command mode
   BSF   LCD_PORT, RW   ; Setup to read busy flag
   BSF   LCD_PORT, EN   ; LCD E-line High
   MOVF   LCD_PORT, w   ; Read busy flag + DDram address
   BCF   LCD_PORT, EN   ; LCD E-line Low
   ANDLW   0xF0      ; Check Busy flag, High = Busy
   MOVWF   TEMP_F      ;
   BSF   LCD_PORT, EN   ; LCD E-line High
   SWAPF   LCD_PORT, w   ; Read busy flag + DDram address
   BCF   LCD_PORT, EN   ; LCD E-line Low
   ANDLW   0x0F      ; Check Busy flag, High = Busy
   IORWF   TEMP_F, w   ;
   ANDLW   0x80      ;
   BTFSS   STATUS, Z   ;
   GOTO   LCDBUSY      ;
   BCF   LCD_PORT, RW   ;
   BSF   STATUS, RP0   ; Select Register page 1
   CLRF    LCD_PORT   ; Set PORTB for output
   BCF   STATUS, RP0   ; Select Register page 0
   RETURN         ;
;
SETLCD   
   BSF     STATUS, RP0   ; Select Register BANK 1
        BCF     STATUS, RP1   ;     
        CLRF    LCD_PORT   ; Set LCD_PORT as outputs
        BCF     STATUS, RP0   ; Select Register BANK 0
        CLRF    LCD_PORT   ; All LCD_PORT output should Low.
;
   CALL   LCDINIT   ;
   MOVLW   0x028      ;
   CALL    LCDCMD      ;
   MOVLW   DisplayON   ;         
   CALL    LCDCMD      ;         
   CALL    LCDCLEAR   ;       
   MOVLW   0x02      ;       
   CALL    LCDEMODE   ;         
   MOVLW   DdramADDR   ;     
   CALL    LCDCMD      ;         
   RETURN         ;
;
; - Send character to LCD
; - Required character must be in W
;
LCDDATA
   MOVWF   CHAR_F      ; Save character from W in CHAR_F
   CALL   LCDBUSY      ; Wait for LCD to be ready
   MOVF   CHAR_F,w   ; Get character from CHAR_F
   ANDLW   0xF0      ;
   MOVWF   LCD_PORT   ; Send upper half-byte to LCD
   BSF   LCD_PORT, RS   ; Set LCD in data mode
   CALL   LCDCLK      ;
   SWAPF   CHAR_F,w   ;
   ANDLW   0xF0      ;
   MOVWF   LCD_PORT   ; Send lower half-byte to LCD
   BSF   LCD_PORT, RS   ; Set LCD in data mode
   CALL   LCDCLK      ; Send character to LCD
   BCF   LCD_PORT, RS   ;
   RETURN         ;
;
; - Sends command to LCD
; - Required command must be in W
;
LCDCMD
   MOVWF   COMMAND_F   ; Save command from W in COMMAND_F
   CALL   LCDBUSY      ; Wait for LCD to be ready
   MOVF   COMMAND_F,w   ; Get character/data from COMMAND_F
   ANDLW   0xF0      ;
   MOVWF   LCD_PORT   ; Send upper half-byte to LCD
   CALL   LCDCLK      ;
   SWAPF   COMMAND_F,w   ;
   ANDLW   0xF0      ;
   MOVWF   LCD_PORT   ; Send lower half-byte to LCD
   CALL   LCDCLK      ; Send character/data to LCD
   RETURN         ;
;
LCDCLK
   NOP         ;
   BSF   LCD_PORT, EN   ; Set E-line High
   NOP         ;
   BCF   LCD_PORT, EN   ; Set E-line Low
   NOP         ;
   RETURN         ;
;
LCDINIT
   MOVLW   D'30'      ; Power-up delay
   CALL   X500MKS      ; 30 * 0.5 = 15mS
   MOVLW   B'00110000'   ; Set 8-bit interface
   MOVWF   LCD_PORT   ;
   CALL   LCDCLK      ;
   MOVLW   D'10'      ;
   CALL   X500MKS      ; 10 * 0.5 = 5mS
   CALL   LCDCLK      ;
   MOVLW   D'1'      ;
   CALL   X500MKS      ; 1 * 0.5 = 0.5mS
   CALL   LCDCLK      ;
   MOVLW   B'00100000'   ; Set 4-bit interface
   MOVWF   LCD_PORT   ;
   CALL   LCDCLK      ;
   RETURN         ;
;
LCDCLEAR
   MOVLW   0x001      ;
   CALL   LCDCMD      ;
   RETURN         ;
;
LCDHOME
   MOVLW   0x002      ;
   CALL   LCDCMD      ;
   RETURN         ;
;
; - Set entry mode of the LCD
; - Required entry mode must be set in W
;   b0   : 0 = no display shift, 1 = display shift
;   b1   : 0 = auto-decrement, 1 = auto-increment
;   b2 - b7 : don't care
;
LCDEMODE
   ANDLW   0x003      ; Strip upper bits
   IORLW   0x004      ; Function set
   CALL   LCDCMD      ;
   RETURN         ;
;
; - Set display control
; - Required entry mode must be set in W
;   b0   : 0 = cursor blink off, 1 = cursor blink on
;   b1   : 0 = cursor off, 1 = cursor on
;   b2 - b7 : don't care
;
LCDDMODE
   ANDLW   0x007      ; Strip upper bits
   IORLW   0x008      ; Function set
   CALL   LCDCMD      ;
   RETURN         ;
;
; Set the Display-Data-RAM address.
; DDRAM data is read/written after this setting
; - Required entry mode must be set in W
; b0 - b6 : required DDRAM address
; b7 : don't care
;
LCDSDDA
   IORLW   0x080      ;
   CALL   LCDCMD      ;
   RETURN         ;
;   
; Set the Character-Generator-RAM address.
; DDRAM data is read/written after this setting
; - Required entry mode must be set in W
; b0 - b5 : required CGRAM address
; b6 - b7 : don't care
;
LCDSCGA
   ANDLW   0x03F      ;
   IORLW   0x040      ;
   CALL   LCDCMD      ;
   RETURN         ;
;
GETVAL
   BCF   STATUS,RP0   ;
   CLRF   ADRESH          ; clear result register ADRESH.
   BSF   STATUS,RP0   ;
   CLRF   ADRESH          ; clear result register ADRESL.
   BCF   STATUS,RP0   ;
   MOVLW   D'20'      ;
   CALL   X500MKS      ; setup time >= 10uS.
   BSF   ADCON0,2        ; start new conversion
loopE
   BTFSC   ADCON0,2   ; a/d done?
   GOTO   loopE      ; no then keep checking
   GOTO   READRES    ; yes then update new value.
;   
READRES
   BSF   STATUS,RP0   ;
   MOVF   ADRESH,w   ; get a/d value
   BCF   STATUS,RP0   ;
   MOVWF   L_BYTE      ;
   MOVF   ADRESH,w   ; get a/d value
   MOVWF   H_BYTE      ;
   RETURN         ;
;
GETPO
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   call   Calc      ;
   CALL   B2BCD      ;
   RETURN         ;
;
Calc
   movf   H_BYTE,w   ;
   movwf   ACCbHI      ;
   movf   L_BYTE,w   ;
   movwf   ACCbLO      ;
   clrf   ACCaHI      ;
   movlw   D'150'      ;
   movwf   ACCaLO      ;
   call   D_add      ;
   movf   ACCbHI,w   ;
   movwf   ACCaHI      ;
   movf   ACCbLO,w   ;
   movwf   ACCaLO      ;
   call   D_mpy      ;
   movf   ACCbLO,w   ;   
   movwf   ACCbHI      ;
   movf   ACCcHI,w   ;   
   movwf   ACCbLO      ;
   clrf    ACCaHI      ;
   movlw   D'3'      ;
   movwf   ACCaLO      ;
   call   DIV      ;
   movf   ACCbLO,w   ;
   movwf   L_BYTE      ;
   movf   ACCbHI,w   ;
   movwf   H_BYTE      ;
   call   MPL2      ;
   movf   H_BYTE,w   ;
   iorlw   0x00      ;
   btfsc   STATUS,Z   ;
   call   subcalc      ;
   return         ;
;
subcalc
   movf   L_BYTE,w   ;
   sublw   0x63      ;
   btfsc   STATUS,C   ;
   call   READRES      ;
   return         ;
;
GETRF
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   call   Calc      ;
   CALL   B2BCD      ;
   RETURN         ;
;
GETDV
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   CALL   B2BCD      ;
   RETURN         ;
;
GETLC
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   RETURN         ;
;
GETRC
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   RETURN         ;
;
GETU1
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   call   MPL2      ;
   CALL   B2BCD      ;
   RETURN         ;
;
GETU2
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   call   MPL2      ;
   CALL   B2BCD      ;
   RETURN         ;
;
GETU3
   CALL   GETVAL      ;
   CALL   CHCKOVRLD   ;
   call   CalcU3      ;
   CALL   B2BCD      ;
   RETURN         ;
;
CalcU3
   movf   L_BYTE,w   ;
   movwf   ACCbLO      ;
   movf   H_BYTE,w   ;
   movwf   ACCbHI      ;
   movlw   .5      ;
   movwf   ACCaLO      ;
   clrf   ACCaHI      ;
   call   D_mpy      ;
   movf   ACCcHI,w   ;
   movwf   H_BYTE      ;
   movf   ACCcLO,w   ;
   movwf   L_BYTE      ;
   return         ;   
;
GETFQ
   call   ReadFQ      ;
   movf   R0,w      ;
   iorlw   0x00      ;
   movlw   0x00      ;
   btfsc   STATUS,Z   ;
   movlw   0x10      ;
   addwf   R0,f      ;
   movlw   0x00      ;
   btfsc   EX_CON,PK   ;
   movlw   0x50      ;
   movwf   R2      ;
   return         ;
;
ReadFQ
   movf   FREQ_L,w   ;
   movwf   R1      ;
   movf   FREQ_H,w   ;
   andlw   0x0F      ;
   movwf   R0      ;
   return
;
CHCKOVRLD
   BCF   STATUS,Z   ;
   MOVF   L_BYTE,W   ;
   SUBLW   0xFF      ;
   BTFSC   STATUS,Z   ;
   GOTO   CHK2      ;
   RETURN         ;
;
CHK2
   BCF   STATUS,Z   ;
   MOVF   H_BYTE,W   ;
   SUBLW   0x03      ;
   BTFSC   STATUS,Z   ;
   GOTO   OVRMESS      ;
   RETURN         ;
;
OVRMESS
   MOVLW   0x00      ;
   btfss   FLAGS,FO   ;
   MOVLW   0x40      ;
   CALL   LCDSDDA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'O'      ;
   CALL   LCDDATA      ;
   MOVLW   'U'      ;
   CALL   LCDDATA      ;
   MOVLW   'T'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'O'      ;
   CALL   LCDDATA      ;
   MOVLW   'F'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'R'      ;
   CALL   LCDDATA      ;
   MOVLW   'A'      ;
   CALL   LCDDATA      ;
   MOVLW   'N'      ;
   CALL   LCDDATA      ;
   MOVLW   'G'      ;
   CALL   LCDDATA      ;
   MOVLW   'E'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   0x00      ;
   btfss   FLAGS,FO   ;
   MOVLW   0x40      ;
   CALL   LCDSDDA      ;
   CALL   PAUSE05S   ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE05S   ;
   goto   Route      ;
;   
B2BCD   bcf     STATUS,0   ; clear the carry bit
   movlw   D'16'      ;
   movwf   COUNT_B      ;
   clrf    R0      ;
   clrf    R1      ;
   clrf    R2      ;
loop16  rlf     L_BYTE, F   ;
   rlf     H_BYTE, F   ;
   rlf     R2, F      ;
   rlf     R1, F      ;
   rlf     R0, F      ;
;
   decfsz  COUNT_B, F   ;
   goto    adjDEC      ;
   RETURN         ;
;
adjDEC  movlw   R2      ;
   movwf   FSR      ;
   call    adjBCD      ;
;
   movlw   R1      ;
   movwf   FSR      ;
   call    adjBCD      ;
;
   movlw   R0      ;
   movwf   FSR      ;
   call    adjBCD      ;
;
   goto    loop16      ;      
;
adjBCD  movlw   3      ;
   addwf   0,W      ;
   movwf   TEMP_F      ;
   btfsc   TEMP_F,3   ; test if result > 7
   movwf   0      ;
   movlw   30      ;
   addwf   0,W      ;
   movwf   TEMP_F      ;
   btfsc   TEMP_F,7   ; test if result > 7
   movwf   0      ; save as MSD
   RETLW   0      ;
;
LCDBCDH
   CLRF   TEMP_F      ;
   MOVWF   TEMP_F      ;
   SWAPF   TEMP_F,w   ;
   CALL   LCDBCDL      ;
   RETURN         ;
;
LCDBCDL
   ANDLW   0x0F      ;
   ADDLW   0x30      ;
   RETURN         ;
;
DIV2
   RRF   H_BYTE,f   ;
   RRF   L_BYTE,f   ;
   RETURN         ;
;
MPL2
   RLF   L_BYTE,f   ;
   RLF   H_BYTE,f   ;
   RETURN         ;
;
;
DIV     movlw   D'16'      ; for 16 shifts
   movwf   TEMP_F      ;
   movf    ACCbHI,W   ; move ACCb to ACCd
   movwf   ACCdHI      ;
   movf    ACCbLO,W   ;
   movwf   ACCdLO      ;
   clrf    ACCbHI      ;
   clrf    ACCbLO      ;
   clrf    ACCcHI      ;
   clrf    ACCcLO      ;
;
dloop   bcf     STATUS,C   ;
   rlf     ACCdLO, F   ;
   rlf     ACCdHI, F   ;
   rlf     ACCcLO, F   ;
   rlf     ACCcHI, F   ;
   movf    ACCaHI,W   ;
   subwf   ACCcHI,W   ; check if a>c
   btfss   STATUS,Z   ;
   goto    nochk      ;
   movf    ACCaLO,W   ;
   subwf   ACCcLO,W   ; if msb equal then check lsb
nochk   btfss   STATUS,C   ; carry set if c>a
   goto    nogo      ;
   movf    ACCaLO,W   ; c-a into c
   subwf   ACCcLO, F   ;
   btfss   STATUS,C   ;
   decf    ACCcHI, F   ;
   movf    ACCaHI,W   ;
   subwf   ACCcHI, F   ;
   bsf     STATUS,C   ; shift a 1 into b (result)
nogo    rlf     ACCbLO, F   ;
   rlf     ACCbHI, F   ;
   decfsz  TEMP_F, F   ; loop untill all bits checked
   goto    dloop      ;
   RETURN         ;
;
FIRSTZERO
   CLRF   TEMP_F      ;
   BSF   FLAGS,FZ   ;
   MOVWF   TEMP_F      ;
   ANDLW   0x0F      ;
   BCF   STATUS,Z   ;
   IORLW   0x00      ;
   BTFSS   STATUS,Z   ;
   CALL   PFZ      ;
   RETURN         ;
;
PFZ
   MOVF   TEMP_F,w   ;
   CALL   LCDDATA      ;
   BCF   FLAGS,FZ   ;
   RETURN         ;
;
SECONDZERO
   CLRF   TEMP_F      ;
   MOVWF   TEMP_F      ;
   ANDLW   0x0F      ;
   BCF   STATUS,Z   ;
   IORLW   0x00      ;
   BTFSC   FLAGS,FZ   ;
   BTFSS   STATUS,Z   ;
   CALL   SCZ      ;
   RETURN         ;
;
SCZ
   MOVF   TEMP_F,w   ;
   CALL   LCDDATA      ;
   RETURN         ;
;
Route
   movf   K_COUNT,w   ;
   sublw   0x00      ;
   btfsc   STATUS,Z   ;
   goto   POUT      ;
   movf   K_COUNT,w   ;
   sublw   0x01      ;
   btfsc   STATUS,Z   ;
   goto   DEVIA      ;
   movf   K_COUNT,w   ;
   sublw   0x02      ;
   btfsc   STATUS,Z   ;
   goto   AUDIO   ;
   movf   K_COUNT,w   ;
   sublw   0x03      ;
   btfsc   STATUS,Z   ;
   goto   VOLT12   ;
   movf   K_COUNT,w   ;
   sublw   0x04      ;
   btfsc   STATUS,Z   ;
   goto   VOLT3      ;
   movf   K_COUNT,w   ;
   sublw   0x05      ;
   btfsc   STATUS,Z   ;
   goto   FREQ      ;
   call   CountInit   ;
   return         ;
;
CountInit
   clrf   K_COUNT      ;
   return         ;
;
NEXT
   incf   K_COUNT,f   ;
   goto   Route      ;
;
POUT
   call   PrintP      ;
   call   DisplayP   ;
   return         ;
;
DEVIA
   call   PrintDV      ;
   call   DisplayDV   ;
   return         ;
;
AUDIO
   call   PrintAF      ;
   call   DisplayAF   ;
   return         ;
;
VOLT12
   call   PrintU12   ;
   call   DisplayU12   ;
   return         ;
;
VOLT3
   call   PrintU3      ;
   call   DisplayU3   ;
   return         ;
;
FREQ
   call   PrintFQ      ;
   call   DisplayFQ   ;
   return         ;
;
DEBONCE
   movlw   .20      ;
   call   X500MKS      ;
   btfss   EX_CON,UP   ;
   btfss   FLAGS,FK   ;
   retlw   H'00'      ;
   bcf   FLAGS,FK   ;
   retlw   H'FF'      ;
;
Modul
   movwf   POS      ;
   btfsc   POS,0      ;
   goto   NEXT      ;
   return         ;
;
ModulFQ
   movwf   POS      ;
   btfsc   POS,0      ;
   goto   Route      ;
   return         ;
;
TKeyPO   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutPO      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayP   ;
;
ShutPO
   bsf   FLAGS,FK   ;
   goto   DisplayP   ;
;
TKeyDV   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutDV      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayDV   ;
;
ShutDV
   bsf   FLAGS,FK   ;
   goto   DisplayDV   ;
;
TKeyLC   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutLC      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayAF   ;
;
ShutLC
   bsf   FLAGS,FK   ;
   goto   DisplayAF   ;
;
TKeyRC   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutRC      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayAF   ;
;
ShutRC
   bsf   FLAGS,FK   ;
   goto   DisplayAF   ;
;
TKeyU1   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutU1      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayU12   ;
;
ShutU1
   bsf   FLAGS,FK   ;
   goto   DisplayU12   ;
;
TKeyU2   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutU2      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayU12   ;
;
ShutU2
   bsf   FLAGS,FK   ;
   goto   DisplayU12   ;
;
TKeyU3   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutU3      ;
   call   DEBONCE      ;
   call   Modul      ;
   goto   DisplayU3   ;
;
ShutU3
   bsf   FLAGS,FK   ;
   goto   DisplayU3   ;
;
TKeyFQ   CLRWDT         ;
   call   ExtFault   ;
   call   Unlock      ;
   btfsc   EX_CON,UP   ;
   goto   ShutFQ      ;
   call   DEBONCE      ;
   call   CountInit   ;
   call   ModulFQ      ;
   goto   DisplayFQ   ;
;
ShutFQ
   bsf   FLAGS,FK   ;
   goto   DisplayFQ   ;
;
ExtFault
   btfsc   EX_CON,EX   ;
   goto   ServEF      ;
   return         ;
;
Unlock
   btfss   EX_CON,UL   ;
   call   ServUL      ;
   return
;
ServEF
   call   PrintEF      ;
   call   PAUSE05S   ;
   btfsc   EX_CON,EX   ;
   goto   ServEF      ;
   call   CountInit   ;
   goto   main      ;
;
ServUL
   call   ExtFault   ;
   call   PrintUL      ;
   call   PAUSE05S   ;
   btfss   EX_CON,UL   ;
   goto   ServUL      ;
   call   StartFREQ   ;
   call   CountInit   ;
   goto   main      ;
;
PrintEF
   call   LCDCLEAR   ;
   movlw   0x01      ;
   CALL   LCDSDDA      ;
   movlw   'E'      ;
   call   LCDDATA      ;
   movlw   'X'      ;
   call   LCDDATA      ;
   movlw   'T'      ;
   call   LCDDATA      ;
   movlw   'E'      ;
   call   LCDDATA      ;
   movlw   'R'      ;
   call   LCDDATA      ;
   movlw   'N'      ;
   call   LCDDATA      ;
   movlw   'A'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   ' '      ;
   call   LCDDATA      ;
   movlw   'F'      ;
   call   LCDDATA      ;
   movlw   'A'      ;
   call   LCDDATA      ;
   movlw   'U'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   'T'      ;
   call   LCDDATA      ;
   movlw   0x43      ;
   CALL   LCDSDDA      ;
   movlw   'T'      ;
   call   LCDDATA      ;
   movlw   'U'      ;
   call   LCDDATA      ;
   movlw   'R'      ;
   call   LCDDATA      ;
   movlw   'N'      ;
   call   LCDDATA      ;
   movlw   ' '      ;
   call   LCDDATA      ;
   movlw   'O'      ;
   call   LCDDATA      ;
   movlw   'F'      ;
   call   LCDDATA      ;
   movlw   'F'      ;
   call   LCDDATA      ;
   movlw   '!'      ;
   call   LCDDATA      ;
   call   PAUSE2S      ;
   return
;
PrintUL
   call   LCDCLEAR   ;
   movlw   0x02      ;
   CALL   LCDSDDA      ;
   movlw   'P'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   ' '      ;
   call   LCDDATA      ;
   movlw   'U'      ;
   call   LCDDATA      ;
   movlw   'N'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   'O'      ;
   call   LCDDATA      ;
   movlw   'C'      ;
   call   LCDDATA      ;
   movlw   'K'      ;
   call   LCDDATA      ;
   movlw   'E'      ;
   call   LCDDATA      ;
   movlw   'D'      ;
   call   LCDDATA      ;
   movlw   0x42      ;
   CALL   LCDSDDA      ;
   movlw   'P'      ;
   call   LCDDATA      ;
   movlw   'L'      ;
   call   LCDDATA      ;
   movlw   'E'      ;
   call   LCDDATA      ;
   movlw   'A'      ;
   call   LCDDATA      ;
   movlw   'S'      ;
   call   LCDDATA      ;
   movlw   'E'      ;
   call   LCDDATA      ;
   movlw   ' '      ;
   call   LCDDATA      ;
   movlw   'W'      ;
   call   LCDDATA      ;
   movlw   'A'      ;
   call   LCDDATA      ;
   movlw   'I'      ;
   call   LCDDATA      ;
   movlw   'T'      ;
   call   LCDDATA      ;
   movlw   '!'      ;
   call   LCDDATA      ;
   call   PAUSE2S      ;
   return
;
PrintP   
   CALL   LCDCLEAR   ;
   MOVLW   'P'      ;
   CALL   LCDDATA      ;
   MOVLW   'o'      ;
   CALL   LCDDATA      ;
   MOVLW   'u'      ;
   CALL   LCDDATA      ;
   MOVLW   't'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   '='      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   movlw   0x40      ;
   CALL   LCDSDDA      ;
   MOVLW   'P'      ;
   CALL   LCDDATA      ;
   MOVLW   'r'      ;
   CALL   LCDDATA      ;
   MOVLW   'e'      ;
   CALL   LCDDATA      ;
   MOVLW   'f'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   '='      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   RETURN         ;
;
DisplayP
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10000001'   ; RC, A/D is ON, Channel 1 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bsf   FLAGS,FO   ;
   movlw   0x07      ;
   CALL   LCDSDDA      ;
   CALL   GETPO      ;
   MOVF   R0,w      ;
   CALL   LCDBCDL      ;
   CALL   FIRSTZERO   ;      
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   SECONDZERO   ;      
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
;   MOVLW   '.'      ;
;   CALL   LCDDATA      ;
;   MOVF   R2,w      ;
;   CALL   LCDBCDH      ;
;   CALL   LCDDATA      ;      
;   MOVF   R2,w      ;
;   CALL   LCDBCDL      ;
;   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'W'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10001001'   ; RC, A/D is ON, Channel 1 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bcf   FLAGS,FO   ;
   movlw   0x47      ;
   CALL   LCDSDDA      ;
   CALL   GETRF      ;
   MOVF   R0,w      ;
   CALL   LCDBCDL      ;
   CALL   FIRSTZERO   ;      
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   SECONDZERO   ;      
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
;   MOVF   R2,w      ;
;   CALL   LCDBCDL      ;
;   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'W'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE05S   ;
   CALL   TKeyPO      ;
   RETURN
;
PrintDV   
   CALL   LCDCLEAR   ;
   MOVLW   'D'      ;
   CALL   LCDDATA      ;
   MOVLW   'E'      ;
   CALL   LCDDATA      ;
   MOVLW   'V'      ;
   CALL   LCDDATA      ;
   MOVLW   'I'      ;
   CALL   LCDDATA      ;
   MOVLW   'A'      ;
   CALL   LCDDATA      ;
   MOVLW   'T'      ;
   CALL   LCDDATA      ;
   MOVLW   'I'      ;
   CALL   LCDDATA      ;
   MOVLW   'O'      ;
   CALL   LCDDATA      ;
   MOVLW   'N'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   RETURN         ;
;
DisplayDV
   bcf   FLAGS,FO   ;
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10010001'   ; RC, A/D is ON, Channel 1 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   call   GETVAL      ;
   decfsz   DEV_SKIP,f   ;
   goto   label      ;
   call   DevDig      ;
label   movlw   0x40      ;
   call   LCDSDDA      ;
   call   BarGraf      ;
   call   TKeyDV      ;
   return         ;
;
DevDig
   movlw   .10      ;
   movwf   DEV_SKIP   ;
   movlw   0x0A      ;
   CALL   LCDSDDA      ;
   CALL   GETDV      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   SECONDZERO   ;
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;
   MOVLW   'k'      ;
   CALL   LCDDATA      ;
   MOVLW   'H'      ;
   CALL   LCDDATA      ;
   MOVLW   'z'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   Return         ;
;
PrintAF   
   CALL   LCDCLEAR   ;
   MOVLW   'L'      ;
   CALL   LCDDATA      ;
   movlw   0x40      ;
   CALL   LCDSDDA      ;
   MOVLW   'R'      ;
   CALL   LCDDATA      ;
   RETURN         ;
;
DisplayAF
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10011001'   ; RC, A/D is ON, Channel 1 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bsf   FLAGS,FO   ;
   movlw   0x01      ;
   call   LCDSDDA      ;
   call   GETLC      ;
   call   BarGraf      ;
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10100001'   ; RC, A/D is ON, Channel 1 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bcf   FLAGS,FO   ;
   movlw   0x41      ;
   call   LCDSDDA      ;
   call   GETRC      ;
   call   BarGraf      ;
   call   TKeyLC      ;
   RETURN
;
PrintU12
   CALL   LCDCLEAR   ;
   MOVLW   'U'      ;
   CALL   LCDDATA      ;
   MOVLW   '1'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   '='      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   movlw   0x40      ;
   CALL   LCDSDDA      ;
   MOVLW   'U'      ;
   CALL   LCDDATA      ;
   MOVLW   '2'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   '='      ;
   CALL   LCDDATA      ;
   MOVLW   '-'      ;
   CALL   LCDDATA      ;
   return         ;
;
DisplayU12
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10101001'   ; RC, A/D is ON, Channel 0 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bsf   FLAGS,FO   ;
   MOVLW   0x05      ;
   CALL   LCDSDDA      ;
   CALL   GETU1      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVF   R2,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'V'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10110001'   ; RC, A/D is ON, Channel 0 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   bcf   FLAGS,FO   ;
   MOVLW   0x45      ;
   CALL   LCDSDDA      ;
   CALL   GETU2      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVF   R2,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'V'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE05S   ;
   CALL   TKeyU1      ;
   RETURN
;
PrintU3
   CALL   LCDCLEAR   ;
   MOVLW   'U'      ;
   CALL   LCDDATA      ;
   MOVLW   '3'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   '='      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   return         ;
;
DisplayU3
   bcf   FLAGS,FO   ;
   BCF   STATUS,RP1   ;
   BCF   STATUS,RP0   ;
   MOVLW   B'10111001'   ; RC, A/D is ON, Channel 0 is selected
   MOVWF   ADCON0      ;
   BSF   ADCON0, GO   ; Start A/D convertion
   MOVLW   0x05      ;
   CALL   LCDSDDA      ;
   CALL   GETU3      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVF   R2,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'V'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE05S   ;
   CALL   TKeyU3      ;
   RETURN         ;
;
PrintFQ
   CALL   LCDCLEAR   ;
   movlw   0x04      ;
   CALL   LCDSDDA      ;
   MOVLW   'E'      ;
   CALL   LCDDATA      ;
   MOVLW   'X'      ;
   CALL   LCDDATA      ;
   MOVLW   'P'      ;
   CALL   LCDDATA      ;
   MOVLW   'R'      ;
   CALL   LCDDATA      ;
   MOVLW   'E'      ;
   CALL   LCDDATA      ;
   MOVLW   'S'      ;
   CALL   LCDDATA      ;
   MOVLW   'S'      ;
   CALL   LCDDATA      ;
   return         ;
;
DisplayFQ
   MOVLW   0x43      ;
   CALL   LCDSDDA      ;
   CALL   GETFQ      ;
   movf   R0,w      ;
   call   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   movf   R0,w      ;
   call   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'M'      ;
   CALL   LCDDATA      ;
   MOVLW   'H'      ;
   CALL   LCDDATA      ;
   MOVLW   'z'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE05S   ;
   CALL   TKeyFQ      ;
   RETURN
;
StartFREQ
   call   PrintFQ      ;
   MOVLW   0x43      ;
   CALL   LCDSDDA      ;
   CALL   GETFQ      ;
   movf   R0,w      ;
   call   LCDBCDH      ;
   CALL   FIRSTZERO   ;
   movf   R0,w      ;
   call   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVF   R1,w      ;
   CALL   LCDBCDL      ;
   CALL   LCDDATA      ;      
   MOVLW   '.'      ;
   CALL   LCDDATA      ;
   MOVF   R1,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVF   R2,w      ;
   CALL   LCDBCDH      ;
   CALL   LCDDATA      ;      
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   MOVLW   'M'      ;
   CALL   LCDDATA      ;
   MOVLW   'H'      ;
   CALL   LCDDATA      ;
   MOVLW   'z'      ;
   CALL   LCDDATA      ;
   MOVLW   ' '      ;
   CALL   LCDDATA      ;
   CALL   PAUSE2S      ;
   CALL   PAUSE2S      ;
   RETURN
;
BarGraf
   movlw   0x0F      ;
   movwf   COUNT_C      ;
   movlw   0xFF      ;
   movwf   COUNT_D      ;
   call   READRES      ;
   call   DIV2      ;
   call   DIV2      ;
   swapf   L_BYTE,w   ;
   andlw   0x0F      ;
   movwf   DEV_BYTE   ;
nextBar
   incf   COUNT_D,f   ;
   movf   DEV_BYTE,w   ;
   subwf   COUNT_D,w   ;
   btfss   STATUS,C   ;
   goto   OverTest   ;
   goto   PrintSpace   ;
Noname
   decfsz   COUNT_C,f   ;
   goto   nextBar      ;   
   return         ;
;
OverTest
   movf   COUNT_D,w   ;
   sublw   0x09      ;
   btfss   STATUS,C   ;
   goto   PrintOver   ;
   goto   PrintBar   ;
;
PrintSpace
   movlw   ' '      ;
   call   LCDDATA      ;
   goto   Noname      ;
;
PrintBar
   movlw   0xDB      ;
   call   LCDDATA      ;
   goto   Noname      ;
;
PrintOver
   movlw   0xFF
   call   LCDDATA      ;
   goto   Noname      ;
;
D_add
   movf   ACCaLO,W   ; Addition ( ACCb + ACCa -> ACCb )
   addwf   ACCbLO, F   ; add lsb
   btfsc   STATUS,C   ; add in carry
   incf   ACCbHI, F   ;
   movf   ACCaHI,W   ;
   addwf   ACCbHI, F   ; add msb
   retlw   0      ;
;
setmpy
   movlw   D'16'      ; for 16 shifts
   movwf   MPY_F      ;
   movf   ACCbHI,W   ;move ACCb to ACCd
   movwf   ACCdHI      ;
   movf   ACCbLO,W   ;
   movwf   ACCdLO      ;
   clrf   ACCbHI      ;
   clrf   ACCbLO      ;
   clrf   ACCcHI      ;
   clrf   ACCcLO      ;
   retlw   0      ;
;
D_mpy                           ;results in ACCb(16 msb's) and ACCc(16 lsb's)
   call   setmpy      ;
mloop   rrf   ACCdHI, F       ;rotate d right
   rrf   ACCdLO, F   ;
   btfsc   STATUS,C   ;need to add?
   call   D_add      ;
   rrf   ACCbHI, F   ;
   rrf   ACCbLO, F   ;
   rrf   ACCcHI, F   ;
   rrf   ACCcLO, F   ;
   decfsz   MPY_F, F   ;loop until all bits checked
   goto   mloop      ;
   retlw   0      ;
;
   end


Съб Апр 24, 2021 10:05 am
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Мар 16, 2006 8:42 am
Мнения: 10892
Местоположение: Гьотеборг
Мнение Re: Няколко стари програми за PIC16F877
Интересно, а още по-интересно защо FM предаватели от 2005 трябва да се топят за скрап?
Ако са били за индустрилани модеми, добре - но ако е за някакви локални радиостанции - защо?
Ако правещия схемите е жив, и иска да напише нещо за тях - ще е интересно. Не държа да се вижда схемата, може и да не е подходящо за показване. Но покрай тия неща винаги има интересни истории, а техническата история си е интересна тема.

Като каза FM предаватели, и се сещам за един FSK модеми на Моторола, които се използваха за разни язовири и напоителни канала (от стария ректор на ФКТТ и брат му), както и за едни едночипови предаватели на Rohm, които имаха много по-прозаични цели - за локално пре-предаване на музика.


Вто Ное 23, 2021 5:43 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пон Авг 24, 2020 3:45 pm
Мнения: 169
Местоположение: София, Люлин 3
Мнение Re: Няколко стари програми за PIC16F877
В първите години след 1989 имаше наплив да се правят радия (Романтика, Експрес ...), а още нямаше добра търговска мрежа и контакти с европейски производители. Тогава имаше една фирма към МВР "Радиоелектронни системи", която произвеждаше в малки серии FM предаватели (първите дори бяха на стария FM обхват и с руски ВЧ транзистори). Програмите ми са писани 2005г като реплика на вече писани преди мен програми, но предишният програмист напусна. Аз, вместо да се ровя в неговите сорсове (не ми допадна стила - линейно програмиране без да ползва call - return), си написах мои. Т.е. предавателите бяха направени доста преди това, но при ремонт (или подмяна) трябваше да се програмират нови процесори. Мощностите бяха до 250 - 500W, към 2005г направиха 1kW с американски модули (2х500W). Обикновено се ползваха възбудител 30W (приведената програма е за него) и крайни стъпала с посочените мощности.
В последствие радията "забогатяха", европейския пазар се отвори за БГ и те си закупиха вносни (главно италиански, които са 1:1 американски). Няма да правя сравнения, но все едно сте си купили ДВГ с дървени бутала за БГ предавателите. Колко съм търчал по тавани и бараки за ремонт...


Пет Дек 03, 2021 11:36 am
Профил YIM
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 3 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни