Lab2

Use PIC10F206 to blink an LED using TMR0.

With this method, the μC can do useful work during the delay period.

Because the 8-bit timer is limited to 256 counts, the required 0.5 second delay is broken into 8 bursts of 62+ milliseconds.  The mainline code must poll the timer before the end of each burst in order to restart.

Below is the schematic. The  components labeled *-sbb go on the solderless breadboard. The source code only uses D1-sbb, but Lab2_1 uses both LEDs,

lab2_1_schematic

Show text file suitable for cut-and-paste.

/*
 * File:   lab2.c
 * Author: Brian
 *
 * DESCRIPTION: use TMR0 to delay. See halfSecondDelay() below for details.
 * Using the timer allows us to do some other processing.
 */

#include <xc.h>
#include <stdint.h>

// CONFIG
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config CP = OFF         // Code Protect (Code protection off)
#pragma config MCLRE = OFF      // Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)

void initTimer(void) {
    /*
     * if we set prescaler=256, then TMR0 increments once every 256 microsec
     * timer runs continuously.
     */

    OPTION = 0b11000111;
    /*
     *  OPTION bits:
     *      <2:0> PS = prescale value, 7=divide by 256
     *      3 PSA = assign prescaler, 0=TMR0
     *      4 TOSE = TMR0 source edge select, don't care
     *      5 TOCS = TMR0 clock source select, 0=system clock
     *      6 notGPPU = enable weak pull-ups, 1=disable
     *      7 notGPWU = Wake up on pin change 1=disable
     */
}

void halfSecondDelay(void) {
    uint8_t loopCounter;
    /*
     * 0.5 second delay = 500,000 microsec
     * sytem clock period = 1 usec
     * output of prescaler = 1 usec * 256 = 256 usec
     * need TMR0 to count 500000 / 256 = 1953.125 times, but TMR0 can only
     * count 0..255.
     * So, we must repeat 1953 / 256 = 7.63 passes. Round up to 8 passes.
     * What number should we load into TMR0 to make 8 passes work?
     *      1953.125 / 8 = 244.1406
     * The technique is to preload TMR0 with K so it counts like this:
     *      K, K+1, K+2, .. 254, 255, 0
     * If we preload TMR0 with K = 256 - 244 = 12 the result is:
     *      1 usec * 256 * 244 * 8 = 499712 usec
     * Yields -0.058% error. Good enough!
     */
    loopCounter = 8;
    while (loopCounter--) {
        TMR0 = 12;
        while (TMR0 > 0) {
            /* stay in this loop until TMR0 rolls over to 0
             *
             * additional activity is possible here, but it must be shorter
             * than 256 * 244 = 62,464 microseconds = 62.464 milliseconds
             */
        }
    }
}

void main(void) {
    /* Initialize I/O and Peripherals for application */
    TRISGPIO = 0b1101;  // make GP1 an output pin
    CMPON = 0;          // disable the Comparator so we can use GP1 for IO
    initTimer();

    while (1) {
        GP1 = 1;        // turn LED on
        // was _delay(500000);
        halfSecondDelay();

        GP1 = 0;        // turn LED off
        // was _delay(500000);
        halfSecondDelay();
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Tools, techniques, design approaches and fun!