0
\$\begingroup\$

The code below worked for my 10F206, but now I use a 10F200 and for some reason the led
does not blink anymore.
(compiler: pic-as 2.30, IDE: MPLAB X IDE 5.40) It compiles but the led stays off.
When I use the simulator and debug the program and step over with F8
it jumps to the first instruction after the label "Start" after calling the subroutine "Delay".

I deleted the line with the cmcon0 register, because the PIC10F200 doesn't have a comparator in contrast to the PIC10F206, but it does not help.

    PROCESSOR   10F200
    PAGEWIDTH   132
    RADIX       dec
    
    #include <xc.inc>

    config MCLRE = OFF
    config CP = OFF
    config WDTE = OFF
    
    PSECT   StartCode,class=CODE,delta=2
    global  Start
     
Start:
    movlw 11000000B
    option      ;to turn off T0CKI

    movlw 00000000B  ;center frequency and turn fosc4 off
    movwf 05h        ;to turn off FOSC4 from GPI2
    ;osccal register is at 05h
    
    movlw 01110001B  ;bit 3 to 0 for turning comparator off
    movwf 07h
    ;cmcon0 is at 07h, but it doesn't appear in the special function register

    movlw 11111101B  ;set GP1 to output direction
    tris 6
    
Loop:
    BCF 06h,1
    ;gpio is at 06h ;GP1 is bit 1 (could also try 01h)
    call Delay
    BSF 06h,1 ;turn LED off again
    call Delay
    goto Loop ;loop forever
    
Delay:
    movlw 100  ;put the decimal number 100 into w
    movwf 11h  ;put 100 in register 0Ah
    ;register 11h should be general purpose register that I can use
    ;to put in values
    movwf 12h
    ;put 100 in 12h
Delay_Loop:
    DECFSZ 11h, 1
    ;decrement the register and store the result in itself
    ;and skip the next instruction if the result was zero
    goto Delay_Loop
    
    DECFSZ 12h, 1
    ;the same with the second register that I filled
    goto Delay_Loop
    retlw 0

end Start
```
\$\endgroup\$
4
  • 2
    \$\begingroup\$ For us not enlightened: What are the differences between PIC10F200 and PIC10F206? -- What do you mean by "jumps [...] after calling"? Does it jump to Start on the retlw 0, or does it jump to Start on the goto Loop? \$\endgroup\$ – the busybee Feb 27 at 21:32
  • 1
    \$\begingroup\$ Your basic code looks good. Assembled in MPLAB v8.92 simulated OK. 6 blinks-per-second. In v8.92, had to comment-out config and PSECT. Perhaps you had a hardware problem connecting the LED to GPIO pin? \$\endgroup\$ – glen_geek Feb 28 at 22:26
  • \$\begingroup\$ @the busybee The simulator jumps to Start after retlw 0. PIC10F200 does not have a "comparator" like PIC10F206 (these are on pin 4 and pin 5), it has less program memory and data memory, it has less general purpose registers. \$\endgroup\$ – theerrormagnet Mar 2 at 10:10
  • \$\begingroup\$ OK. Since retlw 0 simply pops the return address from the stack, I'm sure this can't go wrong. If the simulation returns to the wrong place, it can be a bug in the simulator. Try to find a way to prove your assumption with the real thing. \$\endgroup\$ – the busybee Mar 2 at 13:11
1
\$\begingroup\$

Your problem is the MPLABX project is not setup correctly.

When you do not setup the code section start addresses the linker uses a default behavior, that Microchip using God like wisdom, has the XC8 linker locate code starting from the highest memory location. This "feature" causes the linker start the last instruction word of your code at address 0xFF in the PIC10F200 address space.

User code is not "supposed" to overwrite the last instruction word of baseline PIC controllers. The linker "should" produce a diagnostic message when a project tries to do this. I don't see one.

Now MPLABX and the device programming tools make your situation more complex.

This location is "protected" by the MPLABX IDE so even though your code placed a RETLW 0 instruction at address 0xFF the simulator puts a MOVLW 0 instruction at this location. The device programming tools go a bit further in they read the instruction word at this location, erase the part, write the code (except this location), then restore the previously read instruction word.

This is why the return instruction at the end of your delay function goes missing and the program counter winds up at address 0x00.

To get this to work the MPLABX project must be setup to set the address of the code sections for the target PIC controller correctly.

The pic-as(v2.xx) tool chain requires an explicit command line option to do this. There is an addition bug with the XC8 linker that requires another command line option as a workaround as well.

This is your code updated to build correctly with MPLABX:

;
; File:     main.S
; Target:   PIC10F200
; Author:   dan1138
; Date:     2021-MAR-10
; Compiler: pic-as(v2.30)
; IDE:      MPLABX v5.40
;
; Description:
;
;   Example 2 project for the PIC10F200 controller using the pic-as(v2.31) tool chain.
;
; Add this line in the project properties box "pic-as Global Options -> Additional options": 
;
;   -Wa,-a -Wl,-DCODE=2,-pStartCode=0h,-pResetVec=0ffh
;
    PROCESSOR   10F200
    PAGEWIDTH   132
    RADIX       dec
;
; Include target specific definitions for special function registers
;
#include <xc.inc>
;
; Set the configuration word
;
 config WDTE = OFF       ; Watchdog Timer (WDT disabled)
 config CP = OFF         ; Code Protect (Code protection off)
 config MCLRE = ON       ; Master Clear Enable (GP3/MCLR pin function  is MCLR)
;
; Declare one byte in RAM
;
    PSECT   MainData,global,class=RAM,space=1,delta=1,noexec
    global  Delay_v1, Delay_v2
Temp:       DS      1
Delay_v1:   DS      1
Delay_v2:   DS      1
;
; See: https://electronics.stackexchange.com/questions/550331/pic10f200-blinking-led-pic-as-assembly
;
    PSECT   StartCode,class=CODE,delta=2
    global  Start
Start:
    movwf   OSCCAL      ;Set factory default for the oscillator calibration
    ;osccal register is at 05h

    movlw   11000000B
    option              ;to turn off T0CKI

#ifdef CMCON0           ;CMCON0 is at 07h, but it exists only for the PIC10F206
    movlw   01110001B   ;bit 3 to 0 for turning comparator off
    movwf   CMCON0
#endif

    movlw   11111101B   ;set GP1 to output direction
    tris    GPIO
    
Loop:
    BCF     GPIO,GPIO_GP1_POSITION
    ;gpio is at 06h ;GP1 is bit 1 (could also try 01h)
    call    Delay
    BSF     GPIO,GPIO_GP1_POSITION ;turn LED off again
    call    Delay
    goto    Loop        ;loop forever
    
Delay:
    movlw   100         ;put the decimal number 100 into w
    movwf   Delay_v1    ;put 100 in register 0Ah
    ;register 11h should be general purpose register that I can use
    ;to put in values
    movwf   Delay_v2
    ;put 100 in 12h
Delay_Loop:
    DECFSZ  Delay_v1,F
    ;decrement the register and store the result in itself
    ;and skip the next instruction if the result was zero
    goto    Delay_Loop
    
    DECFSZ  Delay_v2,F
    ;the same with the second register that I filled
    goto    Delay_Loop
    retlw 0
;
; The PIC10F200 reset vector is the highest 
; instruction word in the code space.
;
; This is used to load the WREG with the factory 
; oscillator calibration value then  the program 
; counter rollover to zero to start the code.
;
    PSECT   ResetVec,class=CODE,delta=2
    global  ResetVector
ResetVector:

    end     ResetVector 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.