Вторая жемчужина моей коллекции. Дело в том, что АЦП (ADC) широко применяется в 10-битном формате. Для нас естественен вывод результата в десятичном формате.
Ниже приводится код преобразования 0x2CD в десятичное число 732, данные введены в регистры данных — в качестве примера для проверки.
Код PIC_ASSEMBLER
; Assembly source line config statements
PROCESSOR 16F18855
#include <xc.inc>
; CONFIG1
CONFIG FEXTOSC = OFF ;Oscillator not enable// CRYSTAL Oscillator mode selection bits (HS above 4MHz; PFM set to high power)
CONFIG RSTOSC = EXT1X ; Power-up default value for COSC bits (EXTOSC operating per FEXTOSC bits)
CONFIG CLKOUTEN = OFF ; Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
CONFIG CSWEN = ON ; Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor disable bit (FSCM timer disabled)
; CONFIG2
CONFIG MCLRE = OFF ; Master Clear disable bit (MCLR pin is port defined function)
CONFIG PWRTE = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG LPBOREN = OFF ; Low-Power BOR enable bit (ULPBOR disabled)
CONFIG BOREN = OFF ; Brown-out reset disable bits
CONFIG BORV = HI ; Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 2.7V
CONFIG ZCD = OFF ; Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
CONFIG PPS1WAY = ON ; Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
CONFIG STVREN = ON ; Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
; CONFIG3
CONFIG WDTCPS = WDTCPS_31 ; WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
CONFIG WDTE = OFF ; WDT disabled ; SWDTEN ignored
CONFIG WDTCWS = WDTCWS_7 ; WDT Window Select bits (window always open (100%); software control; keyed access not required)
CONFIG WDTCCS = SC ; WDT input clock selector (Software Control)
; CONFIG4
CONFIG WRT = OFF ; UserNVM self-write protection bits (Write protection off)
CONFIG SCANE = not_available ; Scanner Enable bit (Scanner module is available for use)
CONFIG LVP = OFF ; Low Voltage Programming Disaable bit (MCLR/Vpp must be used for programming)
; CONFIG5
CONFIG CP = OFF ; UserNVM Program memory code protection bit (Program Memory code protection disabled)
CONFIG CPD = OFF ; DataNVM code protection bit (Data EEPROM code protection disabled)
;objects in common (Access bank) memory
PSECT udata ; 0x20
R0 : DS 1 ; equ 12 ; RAM Assignments
R1 : DS 1 ; equ 13
R2 : DS 1 ; equ 14
;this must be linked to the reset vector
PSECT resetVec,class=CODE,reloc=2
resetVec: ; это метка и двоеточие после метки — обязательно
goto main ;наверное метка resetVec: должна быть выше строки PSECT resetVec,class=CODE,reloc=2
/* find the highest PORTA value read, storing this into
the object max */
PSECT code
main:
B2_BCD: bcf STATUS,0 ; clear the carry bit
movlw 10
movwf CountB
movlw 0xA0 ;Указатель на начальную ячейку памяти
;BANKSEL FSR0
movwf FSR0L ; open indirect bank 0xA0,0xA1,0xA2
movlw 0x0F
movwf INDF0 ; Data inR0 — cell N0
;CLRF INDF0
INCF FSR0L
movlw 0x10
movwf INDF0 ;FSR0 Data in R1 — cell N1
;CLRF INDF0
INCF FSR0L
movlw 0x11
movwf INDF0 ; Data in R2- cell N2
adjDEC: movlw 0xA0;- first bank /R2
Banksel FSR0L
MOVWF FSR0L;movwi ++FSR0; load new address bank 0xA3 =++FSR0 i ++FSR0;INDF0;FSR0;movwf FSR
movf R2
movwf INDF0
;movwf temp
;movwf ++FSR0L;INDF0; memory cell A2???
;movf INDF0,1
call adjBCD
;
INCF FSR0L
movf R1
movwf INDF0
;movwf —FSR0L; i FSR0++;INDF1;FSR1;movwf FSR
call adjBCD
;
INCF FSR0L
movf R0
movwf INDF0
;movwi FSR0++;INDF1+1;FSR1+ ;movwf FSR
call adjBCD
;
goto Loop10
;
adjBCD: movlw 3
addwf INDF0,0;FSR0L,0;INDF0,1;R2,0;W;R2;0,W
;movf FSR0L,0;INDF1
movwf temp
btfsc temp,3 ; test if result > 7 (b’1000’=Hx08 carry from 7 to 8 = B’0111′ to B’1000′
movwf INDF0;FSR0L;INDF0;R2;0
movlw 30h ;B’0011 0000′
addwf INDF0,0;FSR0L;INDF0;R2,0;0,W
;movf FSR0L;INDF1,0
movwf temp
btfsc temp,7 ; test if result > 7 bit=H 0x40 =D64
movwf INDF0 ;FSR0L;R2;0 ; save as MSD
RETLW 0
;START
mainbcd:
movlw 2;
movwf H_byte
SWAPF H_byte,1
rlf H_byte,1
rlf H_byte,1
movlw 0xDC;0xDC
movwf L_byte ; The 16 bit binary number = FFFF
call B2_BCD ; After conversion the Decimal Number
; ; in R0,R1,R2 = 06,55,35
;
;self goto self
;org 1FF
goto mainbcd
END;