1. 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.
    Dismiss Notice

How to use Interrupt in PIC16F877A in C..??

Discussion in 'Microcontrollers' started by koolguy, Jan 14, 2013.

  1. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Please explain the procedure you are applying in post #97 the logic behind it!!

    Why it is easier???
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Oh come on.....

    [ 10101010 ] --> [10101010] Is harder as you need to check the digit falling out of one and ensure its in the new when shifting. It takes 8 x 2 x 8 operations to complete..

    [0] --> [0]
    [1] --> [1]
    [0] --> [0]
    [1] --> [1]
    [0] --> [0]
    [1] --> [1]
    [0] --> [0]
    [1] --> [1] ... Is just moving one byte at a time take 8 operations to complete..
     
  3. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    OK, then the use of 74164 will be only to shift like 4017....
    i found two problem while going through this method :
    1. While scanning columns the data on LED display shakes i mean ghosting images.
    2. the font we are using when saved in buffer are of vertical sort we want in horizontal..
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK

    1) this is what I have been talking about.... This is the scan rate that you need to maintain... Also you need to switch OFF the previous column and then light the new column.. It makes it a bit sharper...

    2) The font is the same font used in the KS0107 GLCD ...Here's the one I use..

    Code (text):

    // font.h
    //
    //  5x7
    //
    const char  font5x8[] = {
    0x00, 0x00, 0x00, 0x00, 0x00,// (space)
    0x00, 0x00, 0x5F, 0x00, 0x00,// !
    0x00, 0x07, 0x00, 0x07, 0x00,// "
    0x14, 0x7F, 0x14, 0x7F, 0x14,// #
    0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
    0x23, 0x13, 0x08, 0x64, 0x62,// %
    0x36, 0x49, 0x55, 0x22, 0x50,// &
    0x00, 0x05, 0x03, 0x00, 0x00,// '
    0x00, 0x1C, 0x22, 0x41, 0x00,// (
    0x00, 0x41, 0x22, 0x1C, 0x00,// )
    0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
    0x08, 0x08, 0x3E, 0x08, 0x08,// +
    0x00, 0x50, 0x30, 0x00, 0x00,// ,
    0x08, 0x08, 0x08, 0x08, 0x08,// -
    0x00, 0x30, 0x30, 0x00, 0x00,// .
    0x20, 0x10, 0x08, 0x04, 0x02,// /
    0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
    0x00, 0x42, 0x7F, 0x40, 0x00,// 1
    0x42, 0x61, 0x51, 0x49, 0x46,// 2
    0x21, 0x41, 0x45, 0x4B, 0x31,// 3
    0x18, 0x14, 0x12, 0x7F, 0x10,// 4
    0x27, 0x45, 0x45, 0x45, 0x39,// 5
    0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
    0x01, 0x71, 0x09, 0x05, 0x03,// 7
    0x36, 0x49, 0x49, 0x49, 0x36,// 8
    0x06, 0x49, 0x49, 0x29, 0x1E,// 9
    0x00, 0x36, 0x36, 0x00, 0x00,// :
    0x00, 0x56, 0x36, 0x00, 0x00,// ;
    0x00, 0x08, 0x14, 0x22, 0x41,// <
    0x14, 0x14, 0x14, 0x14, 0x14,// =
    0x41, 0x22, 0x14, 0x08, 0x00,// >
    0x02, 0x01, 0x51, 0x09, 0x06,// ?
    0x32, 0x49, 0x79, 0x41, 0x3E,// @
    0x7E, 0x11, 0x11, 0x11, 0x7E,// A
    0x7F, 0x49, 0x49, 0x49, 0x36,// B
    0x3E, 0x41, 0x41, 0x41, 0x22,// C
    0x7F, 0x41, 0x41, 0x22, 0x1C,// D
    0x7F, 0x49, 0x49, 0x49, 0x41,// E
    0x7F, 0x09, 0x09, 0x01, 0x01,// F
    0x3E, 0x41, 0x41, 0x51, 0x32,// G
    0x7F, 0x08, 0x08, 0x08, 0x7F,// H
    0x00, 0x41, 0x7F, 0x41, 0x00,// I
    0x20, 0x40, 0x41, 0x3F, 0x01,// J
    0x7F, 0x08, 0x14, 0x22, 0x41,// K
    0x7F, 0x40, 0x40, 0x40, 0x40,// L
    0x7F, 0x02, 0x04, 0x02, 0x7F,// M
    0x7F, 0x04, 0x08, 0x10, 0x7F,// N
    0x3E, 0x41, 0x41, 0x41, 0x3E,// O
    0x7F, 0x09, 0x09, 0x09, 0x06,// P
    0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
    0x7F, 0x09, 0x19, 0x29, 0x46,// R
    0x46, 0x49, 0x49, 0x49, 0x31,// S
    0x01, 0x01, 0x7F, 0x01, 0x01,// T
    0x3F, 0x40, 0x40, 0x40, 0x3F,// U
    0x1F, 0x20, 0x40, 0x20, 0x1F,// V
    0x7F, 0x20, 0x18, 0x20, 0x7F,// W
    0x63, 0x14, 0x08, 0x14, 0x63,// X
    0x03, 0x04, 0x78, 0x04, 0x03,// Y
    0x61, 0x51, 0x49, 0x45, 0x43,// Z
    0x00, 0x00, 0x7F, 0x41, 0x41,// [
    0x02, 0x04, 0x08, 0x10, 0x20,// "\"
    0x41, 0x41, 0x7F, 0x00, 0x00,// ]
    0x04, 0x02, 0x01, 0x02, 0x04,// ^
    0x40, 0x40, 0x40, 0x40, 0x40,// _
    0x00, 0x01, 0x02, 0x04, 0x00,// `
    0x20, 0x54, 0x54, 0x54, 0x78,// a
    0x7F, 0x48, 0x44, 0x44, 0x38,// b
    0x38, 0x44, 0x44, 0x44, 0x20,// c
    0x38, 0x44, 0x44, 0x48, 0x7F,// d
    0x38, 0x54, 0x54, 0x54, 0x18,// e
    0x08, 0x7E, 0x09, 0x01, 0x02,// f
    0x08, 0x14, 0x54, 0x54, 0x3C,// g
    0x7F, 0x08, 0x04, 0x04, 0x78,// h
    0x00, 0x44, 0x7D, 0x40, 0x00,// i
    0x20, 0x40, 0x44, 0x3D, 0x00,// j
    0x00, 0x7F, 0x10, 0x28, 0x44,// k
    0x00, 0x41, 0x7F, 0x40, 0x00,// l
    0x7C, 0x04, 0x18, 0x04, 0x78,// m
    0x7C, 0x08, 0x04, 0x04, 0x78,// n
    0x38, 0x44, 0x44, 0x44, 0x38,// o
    0x7C, 0x14, 0x14, 0x14, 0x08,// p
    0x08, 0x14, 0x14, 0x18, 0x7C,// q
    0x7C, 0x08, 0x04, 0x04, 0x08,// r
    0x48, 0x54, 0x54, 0x54, 0x20,// s
    0x04, 0x3F, 0x44, 0x40, 0x20,// t
    0x3C, 0x40, 0x40, 0x20, 0x7C,// u
    0x1C, 0x20, 0x40, 0x20, 0x1C,// v
    0x3C, 0x40, 0x30, 0x40, 0x3C,// w
    0x44, 0x28, 0x10, 0x28, 0x44,// x
    0x0C, 0x50, 0x50, 0x50, 0x3C,// y
    0x44, 0x64, 0x54, 0x4C, 0x44,// z
    0x00, 0x08, 0x36, 0x41, 0x00,// {
    0x00, 0x00, 0x7F, 0x00, 0x00,// |
    0x00, 0x41, 0x36, 0x08, 0x00,// }
    0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
    0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
    };

     
     
  6. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    How to maintain scan rate, pls give code hint???
    and then what is the use of 74164??
     
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Here is my setup

    Capture.png


    Here is my code to do this

    Code (text):

    #include<pic.h>
    #define _XTAL_FREQ 20000000L
    __CONFIG(0x3F18);

    char displayPointer=0;
    extern const char  font[];

    unsigned char buffer[26]; // buffer for screen

    void interrupt ISR()        // This just swaps the buffer to the display
        {
        if(TMR2IF)              // make sure its the timer interrupt.
            {
            PORTB = 0;                  // clear old data first
            if(displayPointer == 0 )    // 1st frame..
                RC4 = 1;                // Data = 1 on the first clock
            RC3 = 1;
            __delay_us(20);             // Clock the shift registers
            RC3 = 0;
            RC4 = 0;
            PORTB = buffer[displayPointer];  // Move buffer line by line       
            if(++displayPointer==24)        //  24 LED columns
                displayPointer = 0;         // back to first..
            }
        TMR2IF = 0;
        }

    void display(const char* str)
        {
        int addr;
        char x, y;
        while(*str != 0)                    // while there is still characters
            {
            addr = (int) *str++ - 0x20;     // get character
            addr *=5;
            for(y=0;y<5;y++)                // 5x8 font so 5 columns
                {
                buffer[25] = font[addr++];  // put it in buffer
                for(x=0;x<26;x++)
                    {
                    buffer[x] = buffer[x+1];    // shift all the columns <--
                    __delay_ms(5);              // so you can see it
                    }
                }
            buffer[25] = 0;                     // This is the scpace between
            for(x=0;x<26;x++)                   // the characters.. Or they will be too close
                {
                buffer[x] = buffer[x+1];        //  shift the space in
                __delay_ms(5);
                }                           // NOTE!!! your array is 28 not 24 like mine
            }  
        }


    void main(void)
        {
        ADCON1 = 0x6;
        T2CON = 0x1e;  
        PR2 = 129;                          // timer preload value
        TMR2IE = 1;                         // enable timer 2 interrupt
        PEIE = 1;                           // enable peripheral interrupt
        GIE = 1;                            // enableglobal interrupt
        TRISB = 0;                          // Port B as output...
        TRISC = 0;                          // Port C as ouput...
        while(1)
            {
            display("HELLO WORLD!!!    ");   // Here's the message
            }
        }   // End main
     
    This does work Each data column is loaded just off screen then scrolled into view..
     
    Last edited: Feb 17, 2013
  8. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hi again,
    which pic are you using and if we are not using A/D then why ADCON1 = 0x6; ??
    In ISR:-
    1. T2CON = 0x1e; -------->it mean 1:4 Postscale 1 = Timer2 is on 1x = Prescaler is 16, right??? then what the use of it here??
    2. PR2=129; -----------> Set the PWM period by writing to the PR2 register.
    3.TMR2IE = 1;---------------> TMR1IE: TMR1 Overflow Interrupt Enable bit
    4. if(TMR2IF)------------> TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
    1 = TMR2 to PR2 match occurred (must be cleared in software)
    0 = No TMR2 to PR2 match occurred


    One thing more i am not getting it is. the program start executing from main to display then where ISR is called???
    RC4/SDI/SDA and RC3/SCK/SCL are you using these SDI/SDA also or just simple ??
     
    Last edited: Feb 17, 2013
  9. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    You really have little experience in programming... I apologize, I assumed you at least knew how micro architecture worked.. I thought you used to program in assembly.

    A)... The same chip as you... PIC16F877A

    B).. ADCON1 = 0x6: // This makes PORTA digital I always use it if I don't need the ADC

    C).. I had to play around with PR2, T2 pre and post scalers to get the timing as I wanted..

    D).. PR2 is a preloaded figure, its not just used for PWM...

    FINALLY.... The whole point of interrupts is they are called when required...If you notice I set the Timer2 to interrupt when it overflows...

    This means that every 1.4mS a column is lit... My example has 24 columns.. Therefore we have 33mS per scan , You will be able to change the buffer to 29 and scan to 28 without there being much difference...

    I picked SDA and SCL because I just did....
     
  10. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    RESULT:-
    http://www.youtube.com/watch?v=DVRJwHjG3Xs&feature=youtu.be

    Code (text):
    #include<pic.h>
    __CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_XT);
    #define _XTAL_FREQ 4000000
    #define DAD PORTB
    #define RST RD7
    #define CLK RD4
    #define DATA RD5


     
    char displayPointer=0;
    extern const char  font[];
     
    unsigned char buffer[32]; // buffer for screen
     
    void interrupt ISR()        // This just swaps the buffer to the display
        {
        if(TMR2IF)              // make sure its the timer interrupt.
            {
            PORTB = 0;                  // clear old data first
            if(displayPointer == 0 )    // 1st frame..
                DATA = 1;               // Data = 1 on the first clock
            CLK = 1;
            __delay_us(20);             // Clock the shift registers
            CLK = 0;
            DATA = 0;
            PORTB = buffer[displayPointer];  // Move budffer line by line      
            if(++displayPointer==31)        //  24 LED columns
                displayPointer = 0;         // back to first..
            }
        TMR2IF = 0;
        }
     
    void display(const char* str)
        {
        int addr;
        char x, y;
        while(*str != 0)                    // while there is still characters
            {
            addr = (int) *str++ - 0x20;     // get character
        //  DAD=addr;
     addr *=5;
    //DAD=addr;
            for(y=0;y<5;y++)                // 5x8 font so 5 columns
                {
                buffer[31] = font[addr++];  // put it in buffer
           
        for(x=0;x<32;x++)
                    {
                    buffer[x] = buffer[x+1];    // shift all the columns <--
                    //DAD=buffer[x];
    __delay_ms(2);              // so you can see it
                    }
                }
            buffer[31] = 0;                     // This is the scpace between
            for(x=0;x<32;x++)                   // the characters.. Or they will be too close
                {
                buffer[x] = buffer[x+1];        //  shift the space in
                __delay_ms(30);
                }                           // NOTE!!! your array is 28 not 24 like mine
            }  
        }
     
     
    void main(void)
        {
        ADCON1 = 0x6;
        T2CON = 0x1e;  
        PR2 = 129;                          // timer preload value
        TMR2IE = 1;                         // enable timer 2 interrupt
        PEIE = 1;                           // enable peripheral interrupt
        GIE = 1;                            // enableglobal interrupt
        TRISB = 0;                          // Port B as output...
        TRISD = 0; 
    RST=1;                      // Port C as ouput...
        while(1)
            {
            display("HELLO WORLD!!!    ");   // Here's the message
            }
        }   // End main
     
  11. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    OK, that mean you are using serial communication for better result?
     
  12. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    No! I could have used any pins.... I'm using timer2 to get the results I wanted...

    You couldn't really use he MSSP module for this.... Especially with the shift registers I picked...

    When using a clocking data method it just seems right to use these two pins... Its forward thinking really...
     
  13. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    I am really not getting you, what are you trying to say....
    anyway why the text is mirror images and flickering so much i am using 4mhz crystal that's why?? and RD5 and RD4 pin for clk and data to 74164
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Do you want the project... So you can see!!

    I have used a 20mhz xtal... But you can change the code to produce the same output....
     
  15. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9

    not working with 20mhz crystal (12pf capacitor) the serial data & clk was giving pulse but portb is zero at all time don't know why???
     
  16. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Did you use my code? Have you loaded the font into memory..... The font5x8 code was pasted before.... You need to incorporate it

    Capture.png
     
  17. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hi,

    there was some silly problem i find in it ...anyway now its it working after....
    __CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);

    here it is..
    http://www.youtube.com/watch?v=z-5hMcrszNo&feature=youtu.be

    The problem is only column scanning making scroling flickering can't we increase freq more tahn 20mhz of 877a??
    or Row scanning??
     
    Last edited: Feb 18, 2013
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Play with the setting of PR2.... Also the small delay after each buffer shift... I used these settings on ISIS... With real LEDs you may need a faster scan... take PR2 down to 90 or 80, the brightness of the LEDs will suffer though

    Nice video....
     
  19. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    thanks


    I am still confused with the code logic anyway what is the use of PR here??
    i am using 32 column now and confused with you are using sometimes 24 26 buffer like that why??
     
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    PR2 determine the LED ON time, at the moment its 1.4mS... As I said if you make this smaller, the LEDs are going to be duller... Compromise situation...


    I only need a 25 byte buffer for a 24 column display... So you can draw the columns off screen..
     
  21. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hi,

    Now i am using two different led per 74164 output both anode are tie up to 74164 directly and the cathode to BC547 via PORTB...
    the base R is 3.3K and I am using a series resistance of ~150/220ohms connected to gnd common of BJT. the problem is that some row light very little don't know why??
    the single Red of other display was working fine....
     

    Attached Files:

    • ab.jpg
      ab.jpg
      File size:
      159.3 KB
      Views:
      84
    • ac.jpg
      ac.jpg
      File size:
      178.4 KB
      Views:
      87

Share This Page