Help programming a pic12f683 in assembly

Markd77

Joined Sep 7, 2009
2,806
No idea I'm afraid, I keep all my code in the main file so I've never seen errors like that.
Maybe someone else will know.
As a guess, when you start a project it asks if you want absolute or relative. I always use absolute, but you may need to use relative for the external files.
I think that in an absolute file, even if you don't put org 0x00, it will default to that.
 

be80be

Joined Jul 5, 2008
2,072
He would need to post the whole thing use MPlab to zip up the whole project
and post it but it more then likely your trying to use absolute code with relocatable code

extThe EXTERNestatement must be included before the label is used. At least one label must be specified on the line. If label is defined in the current module, MPASM assembler will generate a duplicate label error.
ern statement must be included before the label is used. At least one label must be specified on the line. If label is defined in the current module, MPASM assembler will generate a duplicate label error.

Rich (BB code):
    __CONFIG    _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
    errorlevel -302
    errorlevel -312

       ; EXTERN    adc                ; You can't use these here
       ; EXTERN    EEPROMRW
       ; EXTERN    Interrupt_on_change
 
Last edited:

Thread Starter

Daemon

Joined Jun 20, 2009
33
Thanks guys

All that is left to do is the low voltage cutoff stuff.

View attachment SimpleTimer.txtRename as asm

SimpleTimerCct.gif


I need to include this code we worked on earlier Mark and figure out how to do the adc conversion. i think I want to mask some bits off of the results so I am only dealing with 4 digits.
Rich (BB code):
    CBLOCK    0x21
NumH
NumL
    ENDC
            
    
Init_ADC    org        0x004
; Set ADCON0
            movlw   b'10001101'
            movwf   ADCON0
            CALL SampleTime ;Acquisiton delay
; Set ADSEL
            BANKSEL ANSEL
            MOVLW b'00011000' ;Fosc 8,an3
            MOVWF ANSEL ; and GP4 as analog
            BANKSEL ADCON0
        return

Read_ADC
            bsf    ADCON0, GO        ;initiate conversion
            btfsc   ADCON0, GO
            goto    $-1            ;wait for ADC to finish

            movf    ADRESH,W
            andlw   0x03
            movwf   NumH
            BANKSEL ADRESL
            movf    ADRESL,W
            BANKSEL    ADRESH
        movwf    NumL            ;return result in NumL and NumH
        return    
SampleTime    nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            return
 

be80be

Joined Jul 5, 2008
2,072
I'm didn't test this but you where trying to over write your code this will build

Assembly is top down code you don't need org in there all over the place

Rich (BB code):
;****************************************************
;SimpleTimer.asm                                     *
;
;14-6-2011                                          *
;****************************************************
;
    list    p=12F683
    radix    dec
    include    "p12f683.inc"
    
        errorlevel    -224    ; Don't complain about tris
        errorlevel    -302    ; Don't complain about BANK 1 Registers


    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************
  CBLOCK    0x21
     temp1        
     temp2        
    pushes        
    flashes        
    on_time     
    off_time   
    minutes     
    loops       
    delA        
    delB    
    NumH
    NumL
    w_temp
    status_temp 
    ENDC
    ORG     0x000             ; processor reset vector
    goto    main              ; go to beginning of program
    

    ORG     0x004             ; interrupt vector location
    movwf   w_temp            ; save off current W register contents
    movf    STATUS,w          ; move status register into W register
    movwf    status_temp       ; save off contents of STATUS register


;ADC for low voltage cutoff setting.    
        
Init_ADC
; Set ADCON0
            movlw   b'10001101'
            movwf   ADCON0
            CALL SampleTime ;Acquisiton delay
; Set ADSEL
            BANKSEL ANSEL
            MOVLW b'00011000' ;Fosc 8,an3
            MOVWF ANSEL ; and GP4 as analog
            BANKSEL ADCON0
        return

Read_ADC
            bsf    ADCON0, GO        ;initiate conversion
            btfsc   ADCON0, GO
            goto    $-1            ;wait for ADC to finish

            movf    ADRESH,W
            andlw   0x03
            movwf   NumH
            BANKSEL ADRESL
            movf    ADRESL,W
            BANKSEL    ADRESH
        movwf    NumL            ;return result in NumL and NumH
        return    
SampleTime    nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            return

;****************************************************************
;Beginning of program
;****************************************************************
            
        nop
        nop
        nop
        nop
        nop
SetUp    bsf        STATUS, RP0    ;Bank 1            
           movlw    b'11111000'        ;Set TRIS  GP0,1,2 out   GP3,4,5 input
        movwf    TRISIO               ;    
        BCF        STATUS, RP0        ;bank 0
        movlw   07h             ;turn off Comparator ports
        movwf   CMCON0           ;must be placed in bank 0  
        
                    ;read 3 locations in EEPROM                    
        
        BANKSEL EEDAT            
        MOVF    EEDAT,W            ;EEPROM location 0 for flashes of LED                 
        bsf        EECON1,0        ;to show number of 5 mins                        
        movf    EEDATA,w     
        bcf        STATUS, RP0    
        movwf    flashes            ;EEPROM 0 into flashes                
        
        BANKSEL EEDAT            
        incf    EEADR        ;EEPROM location 1 for on_time                    
        bsf        EECON1,0    ;starts EEPROM read operation storing result in EEDATA                        
        movf    EEDATA,w    ;move read data into w
        bcf        STATUS, RP0    
        movwf    on_time     ;EEPROM 1 into on_time
        
        BANKSEL EEDAT            
        incf    EEADR        ;EEPROM location 2 for off_time                         
        bsf        EECON1,0                            
        movf    EEDATA,w    
        bcf        STATUS, RP0    
        movwf    off_time    ;EEPROM 2 into off_time 
        goto     main    
        
    
    
;********************
;* Delays             *
;********************

_327mS    goto    $+1
        decfsz     delA,f
        goto     $-2
        decfsz     delB,f
        goto     $-4    
        retlw     00        
                    
        
;****************************
;* Sub Routines             *
;****************************
            
SwA_Pressed
        
        incf    flashes,f            
        movlw   07
        xorwf   flashes,w     ;if flashes=7
        btfss   STATUS,Z  ;z=1 if flashes=7
        goto    $+3
        clrf    flashes
        goto    $-6    
                    
                    ;put flashes into EEPROM 0
        
        movf    flashes,w    ;put flashes into w    
        bsf        STATUS,RP0    ;select bank1    
        movwf    EEDATA            
        clrf    EEADR             
        bcf        STATUS,RP0    ;select bank0
        call     write
        
                   ;put same value into EEPROM 1 for on_time
                   
        movf    flashes,w    ;put flashes into w    
        bsf        STATUS,RP0    ;select bank1    
        movwf    EEDATA            
        incf    EEADR             
        bcf        STATUS,RP0    ;select bank0
        call     write
        
                ;flash LED 1-5 times
        
        movf    flashes,w
        movwf    temp1     ;save flashes in temp1 for decrementing
        bsf        GPIO,0   ;turn on LED    
        call    _327mS
        bcf        GPIO,0   ;turn off LED    
        call    _327mS
        decfsz  temp1,f
        goto    $-5        
        btfss    GPIO,5    ;loop until SwA is released
        goto    $-1
        retlw    00
        
                  ;SwB = minutes = off_time
SwB_Pressed
        
        incf    minutes,f            
        movlw   06
        xorwf   minutes,w     ;if minutes=6
        btfss   STATUS,Z  ;z=1 if minutes=6
        goto    $+3
        clrf    minutes
        goto    $-6    
                    
                    ;put minutes into EEPROM 2 as off_time
        
        movf    minutes,w    ;put minutes into w    
        bsf        STATUS,RP0    ;select bank1    
        movwf    EEDATA    
        movlw   2        
        movwf    EEADR             
        bcf        STATUS,RP0    ;select bank0
        call     write
        
               ;flash LED 1-5 times
        
        movf    minutes,w
        movwf    temp1     ;save minutes in temp1 for decrementing
        bsf        GPIO,0   ;turn on LED    
        call    _327mS
        bcf        GPIO,0   ;turn off LED    
        call    _327mS
        decfsz  temp1,f
        goto    $-5        
        btfss    GPIO,4    ;loop until SwB is released
        goto    $-1
        retlw    00
 

be80be

Joined Jul 5, 2008
2,072
Couldn't post in one go here the rest

Rich (BB code):
       ;microcontroller loops this sub-routine producing ON time 
        ;as stored in EEPROM location 1        
        ;look for sw press every 327mS
        
time_on
        movlw    1
        BANKSEL EEDAT ;
        MOVF EEDAT,W ;EEDAT not changed                    
        movwf    EEADR                                    
        bsf        EECON1,0    ;starts EEPROM read operation. Result in EEDATA                        
        movf    EEDATA,w    ;move read data into w
        bcf        STATUS, RP0
        movwf    on_time     ;will be 1-5
                            ;convert each value of "on_time" to 5 minutes
                            ;327mS x 16 x 58 = 5 minutes 
        swapf      on_time,f    ;rlf x 4 = 16 = swap nibbles    
        movlw   .58
        movwf    loops                    
        bsf        GPIO,1        ;turn on relay
        call    _327mS
        btfss    GPIO,5        ;test switchA
        goto    SwA_Pressed
        btfss    GPIO,4        ;test switchB
        goto    SwB_Pressed 
        decfsz  loops,f
        goto    $-6          
        decfsz  on_time,f
        goto    $-.11
        retlw   00
        
        ;microcontroller loops this sub-routine producing OFF time 
        ;as stored in EEPROM location 2
        ;look for sw press every 327mS        
        
        
        
time_off
        movlw    2
        bsf        STATUS, RP0            
        movwf    EEADR                                    
        bsf        EECON1,0    ;starts EEPROM read operation. Result in EEDATA                        
        movf    EEDATA,w    ;move read data into w
        bcf        STATUS, RP0
        movwf    off_time    ;will be 1-5
                            ;327mS x 3 = 1 second                           
        addwf    off_time,f  ; multiply by 3    
        addwf    off_time,f        
        movlw   .60
        movwf    loops                                            
        bcf        GPIO,1        ;turn off relay
        call    _327mS
        btfss    GPIO,5        ;test switchA
        goto    SwA_Pressed
        btfss    GPIO,4        ;test switchB
        goto    SwB_Pressed 
        decfsz  loops,f
        goto    $-6       
        decfsz  off_time,f
        goto    $-.11
        retlw   00        
        
    
write    bsf        STATUS, RP0    ;select bank1    
        bsf        EECON1,WREN    ;enable write        
        movlw    55h         ;unlock codes
        movwf    EECON2
        movlw    0aah
        movwf    EECON2
        bsf        EECON1,WR    ;write begins
        bcf        STATUS, RP0    ;select bank0        
        btfss    PIR1,EEIF    ;wait for write to complete
        goto    $-1
        bcf        PIR1,EEIF
        bsf        STATUS, RP0    ;select bank1
        bcf        EECON1,WREN    ;disable other writes
        bcf        STATUS, RP0    ;select bank0                    
        retlw    00                
        
                        
;************************
;* Main                 *
;************************

main        
        call    time_on
        call    time_off
        goto    main
                
;************************
;*EEPROM                 *
;************************
                                
        
                            
        END
I zipped the whole thing
 

Attachments

Thread Starter

Daemon

Joined Jun 20, 2009
33
New code is attached.

View attachment SimpleTimer-2.asm.txt

I have been advised I still need to do the following
"Work out if I want right or left justified.
Create an output that reads each bit in "A_Dvalue" and see what value the A/D converter has produced when the supply voltage is 10v. To do this, add a LED and 270R to pin 6 and make one LED "0" and the other "1" Bit test each bit in the file and output with a delay to read the file"

Am I supposed to add 2 leds? or 1 plus the original one in the project?
I attempted to use stimulus but perhaps I never set it up correctly.
I tried to fire gp4 and gp5 and set them low and I got a message that no stimulus file was attached to ADRESL for A/D

Could someone step me through this please.
I assume the code will poll the voltage input all the time. So if I connect a 10v supply to the circuit I will need to see what value is then in A_Dvalue
I do not know how to create an output that reads each value in A-Dvalue or how to make one led 0 and another 1 and output with a delay to read the file.
 

Markd77

Joined Sep 7, 2009
2,806
Looking at your schematic, the 33K resistor should be going upwards instead of to the pin. The values look OK.
If you only want 8 bit resolution on the ADRES which would be around 0.1V then you should use left justified which gives you the 8 most significant bits in ADRESL.
That would give you a result of around 125 for 10V if my maths is right.
As a test you could just compare ADRESL to 125 and if it is higher light an LED, if lower turn it off. Then vary the input voltage and see if it lights up at the correct point. There may not be any need for your program to change the value if you don't need massive accuracy (ie. if anything from 9.5 to 10.5V would be OK as the cutoff).

I never figured out how to use the stimulus for the A/D converter. I usually resort to commenting out the line which saves the ADRES and then manually changing the contents of the file which it is saved into. It works OK for debugging so long as you remember to uncomment it to program the chip.
 

Thread Starter

Daemon

Joined Jun 20, 2009
33
Okay. I have an extra led set up on the output instead of the relay and motor so how can I set that up?
I really need a variable power supply for this test too.
I would probably need more accuracy than 1v but I could perhaps set it to 9-10v as if it goes below 9 v it starts to damage the battery.
 
Top