Albpy
Albpy

Reputation: 11

How to calculate Delay in PIC MCU, in pic-as

I wrote a program for 1 second delay led blink program using mplab ide and pic-as assembler. But the led is not turn on. I cant spot the problem. I changed multiple delay values. The led mightily lights once pic is powered and staying in off position totally.

THE CODE: Processor - PIC 16f676

`

  CONFIG  FOSC = INTRCIO      

  CONFIG  WDTE = OFF          
  CONFIG  PWRTE = ON            
  CONFIG  MCLRE = OFF         
  CONFIG  BOREN = OFF          
  CONFIG  CP = OFF             
  CONFIG  CPD = OFF            

#include <xc.inc>


COUNTER_0 EQU 0x20
COUNTER_1 EQU 0x21
COUNTER_2 EQU 0x22
COUNTER_3 EQU 0x23

MOV24L macro dest, imm32
 MOVLW (imm32 >> 0) AND 0xff
 MOVWF dest+0
 
 MOVLW (imm32 >> 8) AND 0xff
 MOVWF dest+1
 
 MOVLW (imm32 >> 16) AND 0xff ;SHIFT IMMEDIATE VALUE 16-bit RIGHT
 MOVWF dest+2

 MOVLW (imm32 >> 16) AND 0xff ;SHIFT IMMEDIATE VALUE 16-bit RIGHT
 MOVWF dest+3
 ENDM 
 
psect resetVect, local, class=CODE, delta=2 
 resetVect:
    ORG 0000h
    PAGESEL Main
    GOTO Main

    
psect Code, delta = 2
 Main:
    BSF RP0
    BCF TRISA, 0
    CLRF ANSEL
    MOVLW 63
    MOVWF OSCCAL
 BLINK:
    BCF RP0
    MOVLW 0x00
    MOVWF PORTA
    CALL DELAY_1s
    MOVLW 0x01
    MOVWF PORTA 
    CALL DELAY_1s
    GOTO BLINK
 DELAY_1s:
    MOV24L COUNTER_0, 333332

 DELAY_MAIN_1:
    DECFSZ COUNTER_3
    GOTO DELAY_MAIN_1
    DECFSZ COUNTER_2
    GOTO DELAY_MAIN_1
    DECFSZ COUNTER_1
    GOTO DELAY_MAIN_1
    DECFSZ COUNTER_0
    GOTO DELAY_MAIN_1
    NOP
    NOP
    RETURN

END resetVect`

The led mightly lights once pic is powerd and staying in off position totaly.

Note : I double checked my breadboard connections with builtin codes and its fine.

I TRIED varios code . its ok

Upvotes: 1

Views: 343

Answers (1)

Kozmotronik
Kozmotronik

Reputation: 2520

At first glance your output is misconfigured, I detected that your output initialization code misses some code to init the RA0 as output properly. Look at the PIC16F676's pin diagram. RA0 pin is also multiplexed with an analog comparator module aside with ADC module. So you should disable both in order to use this pin as a digital IO.

PIC16F676 pin diagram

In the datasheet, section 3, example 1, microchip shows a sample init code in order to set PORTA pins as digital IO.

BCF     STATUS,RP0  ;Bank 0
CLRF    PORTA       ;Init PORTA
MOVLW   05h         ;Set RA<2:0> to
MOVWF   CMCON       ;digital I/O
BSF     STATUS,RP0  ;Bank 1
CLRF    ANSEL       ;digital I/O
MOVLW   0Ch         ;Set RA<3:2> as inputs
MOVWF   TRISA       ;and set RA<5:4,1:0> as outputs
BCF     STATUS,RP0  ;Bank 0

When it comes to your delay code, it looks a bit odd. First you use a macro to load immediate 32 bit value, but the dest+2 and dest+3 are loaded with the same value. Your intention was loading the dest+3 with imm32 >> 24.

Although you fix the macro, your delay values will not give you a 1 sec delay. Let's see how...

DELAY_1s:
    MOV24L COUNTER_0, 333332  ; 8 cycles here

 DELAY_MAIN_1:
    DECFSZ COUNTER_3    ; 1 cycle here because the MSB should be zero
    GOTO DELAY_MAIN_1   ; executed as NOP since COUNTER_3 is zero hence 1 cycle
    DECFSZ COUNTER_2    ; 5 * 2 * 2 = 20 cycles - first 2 comes from above 2 instructions and second 2 from below goto inst.
    GOTO DELAY_MAIN_1   ; 2 cycles
    DECFSZ COUNTER_1    ; 22 * 20 * 2 = 880 cycles
    GOTO DELAY_MAIN_1   ; 2 cycle
    DECFSZ COUNTER_0    ; 20 * 880 * 2 = 35200 cycles
    GOTO DELAY_MAIN_1   ; 2 cycle
    NOP                 ; 1 cycle
    NOP                 ; 1 cycle
    RETURN              ; 2 cycle

Total cycles 8 + 35200 + 4 = 35212.

You haven't specified your oscillator frequency. If we assume that it is 4MHz,

1 instruction cycle time = 1 / (4MHz / 4) = 1 microsecond.
Then total delay would be 35212 us = 35,212 ms, not even near to 1 second.

I would recommend yo to use nested loops as in this question so that you can fold the inner delay times by outer loops.

EDIT

Well I forgot to mention about the 333332 value. It is a decimal value unless you change the radix control of the assembly. Its hex representation is 0x51614.
If we split it into bytes then it would be:

MSB LSB
Hex 0 0x5 0x16 0x14
Decimal 0 5 22 20
According to your macro dest+3 & dest+2 dest+1 dest+0

As you can see in the table, your dest variables are loaded with those values according to your MOV24L macro. So I've calculated the loop values based on these values with only a difference of assumption of that you intended to load the dest3 with the MSB which would be 0.

However if I would have calculated based on how you load values in your unmodified macro, in this case the dest3 would have had the same value as dest2 which is 5. If we recalculate the delay cycles, this time we would get 176012 cycles = 176012us = ~176ms which is not near to 1 second also. Hope this is clear enough to tell you what happens in your design.

Upvotes: 2

Related Questions