Help with Multiplexing PIC16F819

Discussion in 'Embedded Systems and Microcontrollers' started by KyAZ, Oct 25, 2009.

  1. KyAZ

    Thread Starter New Member

    Apr 10, 2009
    2
    0
    Hello all:

    I am constructing a temperature display which will read in from a thermocouple or some other device on RA0, and display the result on four digits. RA1 - RA4 will be digit select while portb will be a-g and decimal point. I am having trouble getting initial values for each digit onto my seven segment displays, it is not putting out the first digit, which should be a zero. Can anyone help me? Attached is my incomplete code.

    #include <system.h>
    #pragma CLOCK_FREQ 8000000 //config clock to 8mhz.
    #pragma DATA _CONFIG, _INTRC_IO & _WDT_OFF & _CP_OFF & _PWRTE_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF

    const char SSEG[] = {
    0b11000000, // 0, LED Segment: A,B,C,D,E,F
    0b11111001, // 1, LED Segment: B,C
    0b10100100, // 2, LED Segment: A,B,D,E,G
    0b10110000, // 3, LED Segment: A,B,C,D,G
    0b10011001, // 4, LED Segment: B,C,F,G
    0b10010010, // 5, LED Segment: A,C,D,F,G
    0b10000010, // 6, LED Segment: A,C,D,E,F,G
    0b11111000, // 7, LED Segment: A,B,C
    0b10000000, // 8, LED Segment: A,B,C,D,E,F,G
    0b10010000, // 9, LED Segment: A,B,C,D,F,G
    0b11000110, // C, LED Segment: A,D,E,F
    0b10001110 // F, LED Segment: A,E,F,G
    };

    unsigned char DispDigit[4];
    unsigned char DigitCount;

    void interrupt (void)
    {

    if(intcon.2 = 1) { // TIMER0 Interrupt Flag


    /* Pull Low the Segment */
    portb = DispDigit[DigitCount];


    /* Activate the Digit and Advanced to next Digit */
    porta = ~(1 << DigitCount++);

    /* Reset the Digit Count */
    if (DigitCount > 3)
    DigitCount = 0;
    tmr0 = 156; // Initial Value for 3.2 ms Interrupt
    intcon.2 = 0; // Clear TIMER0 interrupt flag
    }
    }

    void main(void)
    {
    unsigned int value;

    osccon = 0x70; //setting oscilator to 8MHz
    trisa = 0x01; //RA0 as input, all others as output
    trisb = 0x00; //configure port B pins as output
    adcon0 = 0xC1; //Analog to Digital Converter Register 0 - Int osc, RA0 selected
    adcon1 = 0x8E; /*Analog to Digital Converter Register 1 - Right justified, RA0 as input,
    all others output*/


    /* Init TIMER0: Period: 1/(Fosc/4) x Prescaler x TMR0
    0.0005 ms x 64 * 100 = 3.2 ms */
    option_reg = 0x05; // 1:64 Prescaler
    tmr0 = 156; // Interupt every 3.2 ms
    intcon.5 = 1; // Enable interrupt on TMR0 overflow
    intcon.7 = 1; // Global interrupt enable
    /* Initial variables used */
    DigitCount = 0;
    DispDigit[0] = SSEG[10]; // Centigrade Sign
    DispDigit[1] = SSEG[0]; // Zero Digit
    DispDigit[2] = SSEG[0]; // Zero Digit
    DispDigit[3] = SSEG[0]; // Zero Digit
    while( 1 ) //endless loop
    {
    adcon0.2 = 1; //Initiate Go/Done bit
    while(adcon0.2) continue; // Wait conversion done

    value = ADRESL; // Get the 8 bit LSB result
    value += (ADRESH << 8); // Get the 2 bit MSB result
    }
    }
     
    Last edited: Oct 25, 2009
  2. eng1

    New Member

    Oct 25, 2009
    13
    0
    Could you provide a schematic which shows how the displays are connected? Is pin RA4 controlling the first digit that does not work?
    My first guess is that this digit is never enabled. I would split this instruction into two lines:
    Code ( (Unknown Language)):
    1.  
    2. // porta = ~(1 << DigitCount++);
    3.  
    4.  
    5. DigiCount++;
    6. porta = ~(1 << DigitCount);
    7.  
    8.  
    In this way, you are sure that DigiCount is incremented first and it can control pins RA1 to RA4 as supposed; not RA0 (that is an input anyways) to RA3.
     
    Last edited: Oct 26, 2009
  3. KyAZ

    Thread Starter New Member

    Apr 10, 2009
    2
    0
    RA1 = hundreds, RA2 = tens, RA3 = ones, RA4 = 1/10

    Splitting up that code activated RA4, but RA1 is now off.
     
    Last edited: Oct 27, 2009
Loading...