Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Tough problem, don't know how to start!

Status
Not open for further replies.

kasuyama

New Member
Hey guys i'm new to microcontrollers and in my class we were given this problem:

Program a PIC 12F629 to output a square wave that is as close to 400 times slower than your actual internal clock frequency [i.e 100 times slower than your actual instruction cycle time]
This is to be displayed on GP1. You must use Timer0 and you must use the interrupt capability of Timer0. Your program that gets interrupted by the timer can be just "self goto self"

I have no idea how to go about this and I am completely lost. Any help would be appreciated!
Thanks.
 
Hi,
I would have thought the classwork should have prepared you enough to enable you, to at least make a start on an answering the question.

Can you post the program attempt that you have written.
 
To solve this problem you have to understand how the uC works inside. In this case it is regarding the Timer 0 function. There is a register in the IC that is dedicated to interupts, you need to enable timer0 as an interupt and specify where it is to go in the program once an interupt has occured. Find something else for the IC to do while it is waiting for a timer0 interupt. On interupt have it togle GPIO, 1.

The timer normaly devides the clock frequency by 4 as you may already know. You have to load a value into the timer0 counter other wise it will keep counting until it over flows and you will get the wrong outcome.

The interupt vector is 004h so you would specify that in your code as:

org 004h
then togle I/O port
retfie

Let's do some math now, the internal clock frequency is 4MHz so if you want to get a signal that is 400 times lower (remembering that it devides by 4 on the timer input) then you need to have an output that is 10kHz.

To have the IC delay for 100 instruction cycles, you need to preload the TIMER0 register with a value that will leave 100 instruction cycles to be executed before a time out occurs. Since TIMER0 only counts in one direction (up) then it would be:

max TMR0 conter - 100

So if the max timer0 counter value is FFh (255 decimal) then you would need to load a decimal value of 155 into the register. The hex form of this value is 9Bh.

You will need to address the following registers to set up timer0:
TMR0 (01h)
INTCON (0Bh) (8Bh)
OPTION (81h)
(see page 9 and 10 of the attached data sheet)

In the OPTION register bit 5 through bit 0 must all be clear. This will cause the timer0 to incriment every 2 instructon cycles (actually every 8 after the Fosc/4 input), it selects the input will be on the internal instruction cylce and it will incriment on a low to high transistion. (see page 12 of the attached data sheet)

In the INTCON register bit 7 must be set other wise the interupt will be ignored. Bit 5 must also be set and bit 2 should be clear. All other bits are not important to what you are trying to do so they can be set or left clear. (see page 13 in the attached data sheet)

On start up, you would have to tell the PIC to clear the timer0 register, or you can simply load the value 9B directly to the register. Be sure to have the program re load the value after it returns from an interupt other wise your timing will be very off. (you will have to wait until timer0 incriments past 255 from 0, that's 2040 instruction cycles)

Page 27 in the attached data sheet is a good place to start for learning how the TIMER0 register works.

Data Sheet for the PIC12F629:
http://www.datasheetcatalog.org/datasheet/microchip/41190c.pdf
 
To solve this problem you have to understand how the uC works inside. In this case it is regarding the Timer 0 function. There is a register in the IC that is dedicated to interupts, you need to enable timer0 as an interupt and specify where it is to go in the program once an interupt has occured. Find something else for the IC to do while it is waiting for a timer0 interupt. On interupt have it togle GPIO, 1.

The timer normaly devides the clock frequency by 4 as you may already know. You have to load a value into the timer0 counter other wise it will keep counting until it over flows and you will get the wrong outcome.

The interupt vector is 004h so you would specify that in your code as:

org 004h
then togle I/O port
retfie

Let's do some math now, the internal clock frequency is 4MHz so if you want to get a signal that is 400 times lower (remembering that it devides by 4 on the timer input) then you need to have an output that is 10kHz.

To have the IC delay for 100 instruction cycles, you need to preload the TIMER0 register with a value that will leave 100 instruction cycles to be executed before a time out occurs. Since TIMER0 only counts in one direction (up) then it would be:

max TMR0 conter - 100

So if the max timer0 counter value is FFh (255 decimal) then you would need to load a decimal value of 155 into the register. The hex form of this value is 9Bh.

You will need to address the following registers to set up timer0:
TMR0 (01h)
INTCON (0Bh) (8Bh)
OPTION (81h)
(see page 9 and 10 of the attached data sheet)

In the OPTION register bit 5 through bit 0 must all be clear. This will cause the timer0 to incriment every 2 instructon cycles (actually every 8 after the Fosc/4 input), it selects the input will be on the internal instruction cylce and it will incriment on a low to high transistion. (see page 12 of the attached data sheet)

In the INTCON register bit 7 must be set other wise the interupt will be ignored. Bit 5 must also be set and bit 2 should be clear. All other bits are not important to what you are trying to do so they can be set or left clear. (see page 13 in the attached data sheet)

On start up, you would have to tell the PIC to clear the timer0 register, or you can simply load the value 9B directly to the register. Be sure to have the program re load the value after it returns from an interupt other wise your timing will be very off. (you will have to wait until timer0 incriments past 255 from 0, that's 2040 instruction cycles)

Page 27 in the attached data sheet is a good place to start for learning how the TIMER0 register works.

Data Sheet for the PIC12F629:
http://www.datasheetcatalog.org/datasheet/microchip/41190c.pdf

You don't even need to get into the whole Timer0 thing. You can simply use the number of instruction cycles to do this. I'd like to see the response to Eric's post before I say any more, though.

Der Strom
 
Just wanted to clear up some inaccurate info'...

The internal oscillator frequency (Fosc) is 4-MHz (Tosc = 250 ns). That gets divided by four to produce an internal clock frequency of 1-MHz (Tcy = 1 us). When you divide that by four hundred (400) you should get 2500 Hz which has a period of four hundred microseconds (400 instruction cycles). In this case you want to enter the interrupt every 200 cycles and toggle the GP1 pin.

Since you're not interrupting anything but an empty while() loop in main, you don't need to save and restore context in the interrupt routine. All you really need to do is; (1) clear the TMR0 interrupt flag, (2) reload free running TMR0 for a precise 200 us interval, and (3) toggle the GP1 I/O pin.

Code:
;******************************************************************
;  interrupt vector                                               *
;******************************************************************
        org     0x004
        radix   dec
;
;  clear TMR0 interrupt flag & reload TMR0 for 200 us interval
;
v_int
        bcf     INTCON,T0IF     ; clear timer 0 interrupt flag    |B0
        movlw   -(200-1)+2      ;                                 |B0
        addwf   TMR0,F          ;                                 |B0
;
;  toggle the GP1 pin and return from interrupt
;
        movlw   b'00000010'     ; mask for GP1 pin                |B0
        xorwf   GPIO,F          ; toggle GP1 output               |B0
        retfie                  ;                                 |B0
There's some important information in the 12F629 datasheet worth noting. First, section 4.1 Timer0 Operation reminds us that TMR0 register won't increment for two cycles after it has been modified. That's why there's a +2 in the instruction operand above. Second, section 4.4 Prescaler says that modifying TMR0 will clear the prescaler and so it's important to use a 1:1 prescaler setting if you need "cycle accurate" intervals. Finally, the Note in section 2.2.2.2 - Option Register tells you how to get a 1:1 prescaler setting for TMR0.

Hope this helps.

Cheerful regards, Mike


<added>

While the link that Dragon Tamer provided points to an older version of the 12F629/12F675 Datasheet (41190C), the sections mentioned above are still valid. The most recent version of the 12F629/12F675 Datasheet (41190G) can be found here; https://www.electro-tech-online.com/custompdfs/2011/11/41190G.pdf
 
Last edited:
useful post mike. i didnt realise the 2 cycle increment delay ;) wort remembering should i ever need to get accurate
 
You must use Timer0 and you must use the interrupt capability of Timer0. Your program that gets interrupted by the timer can be just "self goto self"

Actually Der, you do. Not to be rude but it was stated in the OP. I agree though it would be simpler to time based on a number of wasted instruction cycles.
 
Last edited:
Actually Der, you do. Not to be rude but it was stated in the OP. I agree though it would be simpler to time based on a number of wasted instruction cycles.

Oops, I must have missed that part. Sorry about that :D
 
If he needs a very precise signal, he should consider the number of instruction cycles that will be used while the program is executing it's routine from the interupt.
 
Status
Not open for further replies.

Latest threads

Back
Top