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.

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

Status
Not open for further replies.
You can fill the buffer line by line.... Lets start with 'A' hex 0x41..... We put our font pointer to 0x41 - 0x20 ( we started our characters at 0x20 ' ' ( space ) then we multiply by the size of the character (8) to find out the place we need to be...

I think you are scanning columns, if not then how to scan rows by creating buffer and if i want to see what is inside the buffer how to see??
One thing more will it be easier to use 4017 for scanning then using PORT B in code??

I need still more help to do this, i have changed just for testing
const unsigned char fnt
to long unsigned int for 32 bits saving then scrolling 4 text then single text from 8 bit unsigned char

i found this tutorial https://embedded-lab.com/blog/?p=2661
 
Last edited:
Code:
DisplayBuffer[i] = (DisplayBuffer[i] << ShiftAmount) BIT OR (CharacterRow[i] >> (8- ShiftAmount)

I am not getting how he is doing in above link.....actually i am bit confused with display buffer!!
 
hi,

I have seen your tut 13 code, yu have used vice way while programming....
anyway, i am confused with is part :-

Code:
addr = (([B]int[/B])*str++ - 0x20);
what is the use of int here???

Code:
unsigned char leds[8];			// led buffer
unsigned char leds2[8];			// 2nd led buffer
why two buffer not one??

Code:
if(leds2[x] & 1)
					leds[x]+=128;
				leds[x] >>= 1;
				leds2[x]>>= 1;
reason behind this, going over my head...



Code:
#include <htc.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
extern const char Font2[];void clear(void);unsigned char leds[16];
unsigned char pow[] = {1,2,4,8,16,32,64,128}; // power array
 display(char *str);int  data( int  a);int a;
int y;
main (){
TRISD=0B00000000;
TRISB=0B00000000;
while(1){	


		display("Hello love!!");

	
//char x[60]="Ram is love & NOT ALSO WHY ?? my no. 9760338261 ";
//	for(int i=0;i<60;i++){	
//display(&x[i]);
//__delay_ms(1);
//}
}}
  
 display(char *str)
	{

int addr;							// large table (requires an int)
		int z;	
while(*str!=0){
		// looping variable
		addr = ((int)*str++ - 0x20);	// locate character in table
addr *= 8;
for(z=0;z<8;z++){
	leds[z] = Font2[addr+z];	
}

y=24;
for(int o=0;o<24;o++){
y--;
for(int p=0;p<2;p++){


for(z=0;z<8;z++)

	{	
a=leds[z];
data(a);
DAD=pow[z];
__delay_ms(1);
}
}
}
}
	}

int  data( int  a)
{
DAD=0X00;
RST=0;
RST=1;
for (int k=0; k<y;k++) {  
CLK = 0;  
    if ((a & 0x01)==1) DATA = 1;
    else DATA =0;
    CLK =1; 
    a >>=1;
} }
 
Sorry I haven't replied... When I moderate posts I sometimes glance at the posts while I'm going through them all.... Trouble is they are then marked as read... Then I forget... Senility creeping in...

The reason I (Nigel) has two buffers was for the scrolling... As the tutorial scrolled left, right up and down... Its easier to triple buffer the output... You are scrolling left or right so it will be easy to implement double buffering...


You will find it hard to maintain the visual aspect of the LED matrix without using interrupts.

In the tutorial Nigel scripted, the leds are lit for 2.4mS each... 8 rows = 19.2mS or roughly 50hz... Same as a TV

Each led has a duty cycle of 12.5% this gives a good visual perspective.

If you need to light 28 columns at 50hz that's 686uS each LED ( this may be TOO dim )

If you bring the visual aspect down to @30hz thats 1.12mS each LED.. I would jack the current up a little to compensate..

As you can see to maintain this kind of scan rate, interrupts have to be used...
 
Last edited:
Code:
addr = (([B]int[/B])*str++ - 0x20);

I Still Confused with this int here??
Code:
leds[x]+=128;
				leds[x] >>= 1;
				leds2[x]>>= 1;
what is the use of 128 here ???

You will find it hard to maintain the visual aspect of the LED matrix without using interrupts.
so, interrupt will increase frame rate how??




Code:
#include <htc.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
extern const char Font2[];void clear(void);unsigned char leds[16];
unsigned char pow[] = {1,2,4,8,16,32,64,128}; // power array
 display(char *str);int  data( int  a);int a;
int y;
main (){
TRISD=0B00000000;
TRISB=0B00000000;
while(1){


                display("Hello love!!");


//char x[60]="Ram is love & NOT ALSO WHY ?? my no. 9760338261 ";
//      for(int i=0;i<60;i++){
//display(&x[i]);
//__delay_ms(1);
//}
}}

 display(char *str)
        {

int addr;                                                       // large table (requires an int)
                int z;
while(*str!=0){
                // looping variable
                addr = ((int)*str++ - 0x20);    // locate character in table
addr *= 8;
for(z=0;z<8;z++){
        leds[z] = Font2[addr+z];
}

y=24;
for(int o=0;o<24;o++){

y--;
for(int p=0;p<2;p++){


for(z=0;z<8;z++)

        {
a=leds[z];
data(a);
DAD=pow[z];
__delay_ms(1);
}
}
}
}
        }

int  data( int  a)
{
DAD=0X00;
RST=0;
RST=1;
for (int k=0; k<y;k++) {
CLK = 0;
    if ((a & 0x01)==1) DATA = 1;
    else DATA =0;
    CLK =1;
    a >>=1;
} }
 
Last edited:
The first comment
addr = (int)*str++ - 0x20);

This is a cast... Its a common C term... The addr variable is an int... *str points to a char... So the char will be expanded to an int, BEFORE it's assigned to addr.

The second comment
leds[x]+=128;

The last bit of the buffer, bit 7 ( value 0x80 or 128 ) is loaded IF the previous LSBit was shifted out...

so, interrupt will increase frame rate how??

Doesn't increase frame rate.... It keeps it constant...

Why don't you try to code from tutorial 1 ---- Up to tutorial 13... Starting at 13 may be a tad too hard..

You need to learn more basic C before you try and understand pointers, interrupts, bitwise operations..etc...
 
Code:
addr = (int)*str++ - 0x20);

++ what they are doing ??

I find one more problem when buffer size is increased from 8bit to 16bit or more than it asci/font is incremented from previous only..
for example: display("ad");
the value of a is taken then b not of d i mean to say addr is incrementing not going back to see what is the next character..!!
 
No You dont follow... Sorry I made a mistake it's using the character as a reference.. Look at it this way..

Each character in the ascii table is assigned a number.... We write a string..." HELLO WORLD!"

addr = (int) *str++ - 0x20; I'll disasemble this for you.

start at "*str".... * = pointer... So retrieve the character that is pointing to the variable pointer str

The first instance is "H"... H is enumerated as ASCII 0x48 or decimal 72..

Therefore we see addr = 0x48 - 0x20.. 0x20. is the start of our font... The space character = 0x20..

So... addr = 0x28 ( decimal 40 )..

Each character is 8 bytes, so then we multiply 40 x 8.... so the bitmap (8x8) that represents "H" starts at 320...

Back to the equation addr = (int) *str++ - 0x20;... As this is in a loop, In C we can post increment the string so AFTER the statement has been executed The pointer *str will be pointing at "E" ready for the next execution.... *str++ = when you have finished operating on *str... Increment to the next position in the string..
 
But when i use 16 bit buffer why it does not look back the charter in display is there anything wrong ??
 
The buffer needs to be the size of the display... So you can create an "Unseen display" in memory.

Have you considered having a go with a small GLCD 128x64 using the KS0107 chipset.... Its exactly the same process as programming that!!

I use an internal buffer ( the size of the screen ) and draw onto that.... Then I blit the result to the LCD...
 
HI,

I have successfully created buffer more than 8bit wide taking char from string.....
now i want your help for scrolling what method you are using for scrolling in your 13 code it was not clear to me..!!

Code:
#include <htc.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
extern const char Font2[];void clear(void);unsigned char leds[24];
unsigned char pow[] = {1,2,4,8,16,32,64,128};
 display(char *str);int  data( int  a);
int t;
main (){
   TRISD=0B00000000;
   TRISB=0B00000000;
   while(1){
               display("HEL");
      }
}

display(char *str) {
   int addr;                                                      
   int z;
   while(*str!=0){
       {
       addr = ((int)*str++ - 0x20); 
       addr *= 8;
       for(z=0;z<8;z++){
          leds[z] = Font2[addr+z];
         }
   }
   addr = ((int)*str++ - 0x20); 
   addr *= 8;
   int y=0;
   for(z=8;z<16;z++){
      leds[z] = Font2[addr+y];
      y++;
      }
   addr = ((int)*str++ - 0x20); 
   addr *= 8;
   int y=0;
   for(z=16;z<24;z++){
      leds[z] = Font2[addr+y];
      y++;
      }
   int a;
   t=30;
   for(int u=0;u<30;u++){
      t--;
      for(int p=0;p<10;p++){
         int w=0;
         for(z=0;z<24;z++) {	
            a=leds[z];
            data(a);
            DAD=pow[w];
            w++;
            if(w==8){w=0;}
            }
         }
      }
   }
}
        

int  data( int  a){
   DAD=0X00;
   RST=0;
   RST=1;
   for (int k=0; k<8;k++) {  
      CLK = 0;  
      if ((a & 0x01)==1) 
         DATA = 1;
      else DATA =0;
         CLK =1; 
      a >>=1;
      }
}
 
Last edited by a moderator:
Hi,

i want your help for scrolling with your methods as per tut. 13 code it was not clear to me..!!
 
Hi again,

What the difference between 74ls164 and 74hc164 b'coz combination of both in ckt was not properly working...
 
Yes I know you do, but your matrix is a lot larger.... When Nigel chose the 8x8 matrix Its small enough to have TWO led buffers One to hold the output and one to scroll in and out of.

Just Say you draw your columns 1 though 28... next frame you draw a blank column then 2 through 28..... then 3 though 28... the words will scroll off one by one to the right..

If you have a third buffer you can place it at the beginning so this will scroll on to the screen...

You only need to buffer one more character in the buffer if you need to scroll....

I, personally, would try to keep the buffer at the same size as the display and just write to the buffer.. If you use the interrupts as I said..

I am not going to build one to see if it works... ISIS have a problem displaying LED's when used like this...
 
Please explain more for scrolling .......

Code:
void scroll(char dir)
	{
	char x;
	switch (dir)
		{
		case 0:					// scroll left
			for(x=0;x<8;x++)
				{
				if(leds2[x] & 1)
					leds[x]+=128;
				leds[x] >>= 1;
				leds2[x]>>= 1;
				}
			DelayMs(100);
			break;
		case 1:					// scroll right
			for(x=0;x<8;x++)
				{
				if(leds2[x] & 128)
					leds[x]+=1;
				leds[x] <<= 1;
				leds2[x] <<= 1;
				}
			DelayMs(100);
			break;
		case 2:					// scroll up
			for(x=7;x>0;x--)
				leds[x] = leds[x-1];
			leds[0] = leds2[7];
			for(x=7;x>0;x--)
				leds2[x] = leds2[x-1];
			leds2[0] = 0;
			DelayMs(100);
			break;
		case 3:			 		// scroll down
			for(x=0;x<8;x++)
				leds[x] = leds[x+1];
			leds2[7] = leds[0];
			for(x=0;x<8;x++)
				leds2[x] = leds2[x+1];
			leds2[7] = 0;
			DelayMs(100);
		}

	}
 
You can't use the same code as in the tutorials, You'll need to modify it for columns instead of rows.... Essentially its easier to scroll columns than it is rows..

Flow chart

Flow.png


I can't really describe any more how to do it...

The interrupt moves the data from the buffers column by column to the display

The main routine fills the buffer with the correct data....
 
The interrupt moves the data from the buffers column by column to the display

I am still confused with the use of timer interrupt here?? how much time to set/ clock why???
 
I am still confused with the use of timer interrupt here?? how much time to set/ clock why???


It's just a better way to do this.... If you NEVER have to worry about the screen updating, then when you update the "Unseen screen buffer" its automatically updating all the LED's (screen)..

You just print to the buffer... Just imagine if you held your string in a permanent place in ram ... ie .. "HELLO WORLD!!" 13x8 = 104 byte buffer you could, in theory, just point to the buffer and increment it one at a time so the interrupt scroll through the entire message..
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top