cluemein
cluemein

Reputation: 882

How do I implement a one second clock on a PIC16F1938 in PIC assembly to turn a light on for one second?

I have a few thoughts on the matter, mainly that the PIC I will be using does not have enough timer bits per se to count to a second, but using the prescaler and postscaler, I can effectively get myself up to 18 bits. However, I need 23 bits, leaving me short 5 bits. I had a couple of ideas, such as storing a count of each time it uses up 18 bits in the timer, (vocabulary isn't correct probably, but I think it can be seen what I am trying to say). Also, someone suggested using flags (are these like the counter idea?). I am using MPLAB X IDE to write the program for the chip. I also need to do two of these programs for blinking a light, one with interrupts and one without, though right now I am simply working on the one without interrupts, that is what my question is in regards to. For quick reference, the tick rate of the clock on the PIC is 8,000,000 tics per second. As for ports, registers, I am not sure what I need to use. If anyone could provide a piece of example code for just something simple, like getting the clock to blink the light to begin with on a shorter interval using a 1:1 on both the prescaler and postscaler, that would help a lot. I am so rusty with this kind of programming, it has been roughly atleast a year since I used a PIC let alone actually wrote in PIC assembly (with which I had mixed results).

Upvotes: 1

Views: 3361

Answers (1)

GJ.
GJ.

Reputation: 10937

Use on timer overflow interrup!

At initiation of MCPU, init one of timers, let's say Timer0 (8 bit timer) and inside TMR0 interupt increment another counter variable TickRoller which count ms, than count ms and switch on/off the LED:

TickRoller      res 1                ;Define Interrupt tick 1ms timer
;Set OPTION reg
;{
        movlw   B'00000000'          ;Prescaler is assigned to the Timer0 module
                                     ;Prescaler TMR0 Rate 2
        BANKSEL OPTION_REG
        movwf   OPTION_REG            
;}

;Set INTCON reg and enable interrupts
;{
        bcf     CPSCON0, T0XCS        ;Timer0 clock source is controlled by FOSC/4
        movlw   B'10100000'           ;Enables the Timer0 interrupt
                                      ;Clear TMR0IF
                                      ;Enable global interrupts
        movwf   INTCON                ;Set INTCON register 
;}

After that write interrupt rutine at address 0x0004 like:

__Interrupt         code    0x0004
;INTERRUPT
;{
;Timer0 interrupt in use, overflow every 512 cycles @ CPU clock 32MHz = 64uS
        bcf INTCON, TMR0IF               ;Reenable timer interrupt
;Tick Roller
;{  
        incf    TickRoller, f           
        btfss   TickRoller, 4       ;TickRoll event every 0.001024s
        retfie                      ;Bit 4 of TickRoller not set so exit from interrupt 
        clrf    TickRoller          ;Reset event counter
;
;       your rutine
;       count up to 1000 and change the LED state every second  
;
        retfie                       ;exit from interrupt         
;}

Do not forget to main program rutine!

;Main Program loop
{
MainLoop
        clrwdt                       ;Clear wdt timer
;
;       ... 
;
        goto  MainLoop
}

That's all...

Upvotes: 1

Related Questions