logic gate project in ATmega8. Plz help!

Go To Last Post
38 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am building a project that simulates various logic gates in ATMega8. I have two inputs through switches (Vcc,1 or ground,0)and one LED at output showing 1 or 0, the end result of logic operation (AND,OR,NAND,etc.)

Here is the code i tried but its not working, must be there some error in it. Kindly check and correct it quickly, i need to submit it by this week. Any other easy technique can be used...

#include
#include
#include
#include

void MyDelay ( int iDelay );

int main()
{
DDRC = 0xFF; //all as output

DDRD=0; //all as input
PORTD=0xFF; //pullup enabled

DDRB=0; //all as input
PORTB=0xFF; //pullup enabled

//short int a,b,c;

int a=0;
int b=0;
int c=0;

while(1)
{

a=PIND0;
b=PIND1;
c=a&b; //AND gate
PORTC=c;

//else
//{PORTC=0;}

MyDelay ( 50);

}

return 0;
}

void MyDelay ( int iDelay )
{
int i;

for ( i = 0; i < iDelay; i++ )
;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

PIND0

That is just

#define PIND0 0
#define PIND1 1
#define PIND2 2
...

See your chip include files.

Take a visit to the Tutorials forum and find the one with "Bit Manipulation" in the title.
https://www.avrfreaks.net/index.p...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the reply.

I have see iom8.h file, it already has all PINs of D port defined as above. Please check whether I am performing the operation in correct manner. Is all logic Ok? I just want to use 2 bits as input and i have used int data type?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
it already has all PINs of D port defined as above.

Your missing the point. Your code doesn't work because of the defines. Your code:

a=PIND0; 
b=PIND1;

translates to:

a=0; 
b=1;

which obviously does nothing useful. You have to read the value of PIND, then use PIND0 and PIND1 to extract the value of the bits that you need. If you had actually read the thread that Lee linked to, then you would already know what is wrong with your code.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok thanks, i got the point. Please can someone correct it and let me know how to extract a bit so that I can build AND gate out of it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're still not getting it are you? The link "theusch" gave in his post tells you exactly what you need to know. How about actually reading it? The bottom line is that to test the PD1 input use:

if (PIND & (1<<PIND1)) {

but you are going to have to eventually read that link to understand why.

(Hey, a split infinitive - does this have anything to do with the fact that I have "Star Trek:First Contact" on right now?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all of you for taking pain.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have finally made the following code but it is still not showing up. Kindly plz check and let me know what the error is.

#include 

#define _AND_OPERATION		0x02
#define _OR_OPERATION		0x04
#define _NAND_OPERATION		0x08
#define _NOR_OPERATION		0x10
#define _XOR_OPERATION		0x20


void MyDelay ( int iDelay );

int main()
{
	DDRC = 0xFF;    //all as output

	DDRD=0;         //all as input
	PORTD=0xFF;     //pullup enabled

	DDRB=0;         //all as input
	PORTB=0xFF;     //pullup enabled

	unsigned char a=0;
	unsigned char b=0;
	unsigned char c=0;
	unsigned char d=0;

    while(1)
    {
    	a = PIND & (1 << PIND0) ; // store 0th bit of PIND into 'a'
		
		b = PIND & (1 << PIND1) ; // store 1st bit of PIND into 'a'
		b >>= 1 ; // perform bitwise right-shift on contents of 'b' one time (align with 'a') 

		switch( PINB )
		{
			case _AND_OPERATION:
				c = a & b; 	// perform the AND operation
				break ;
			
			case _OR_OPERATION:
				 c = a | b;	// perform the OR  operation
				break ;

			case _NAND_OPERATION:
				d = (a & b);
     				c=~d;		// perform the NAND operation
				break ;
			case _NOR_OPERATION:
				d=(a|b); 	// perform the NORoperation
     				c=~d;
				break ;
			case _XOR_OPERATION:
				c= a ^ b;     // perform XOR operation
    				break ;
  	
		}
				
		PORTC = c ; // output to 0th bit PORTC the contents of AND-ed result

    	MyDelay ( 100);
    }

	return 0;
}



void MyDelay ( int iDelay )
{
    int i;

    for ( i = 0; i < iDelay; i++ )
        ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure you're putting the correct values into PORTB? if not, the results won't be what you expect. I would suggest you confirm these values or simplify your code to do only one of your logic operations.

You might want to run the code in the AVRStudio simulator to see what is happening.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have already checked the code in debugger, it is absolutely fine. Please tell me some quick tips to check the errors in hardware.

One other thing i have noticed is that all PORTB pins have voltage = 5 (Vcc) already.

Kartman wrote:
Are you sure you're putting the correct values into PORTB? if not, the results won't be what you expect. I would suggest you confirm these values or simplify your code to do only one of your logic operations.

You might want to run the code in the AVRStudio simulator to see what is happening.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for a start also maky the portb test defines like this ( 1<<PBx). This will make it more readable and thus give you better point with the teacher.

also another question that is going to be asked by your teacher and you should have also asked yourself is, what is going to happen if you activate multiple lines on portB an the same time.

Now I'm wondering what level of code was given to you to start with and what was the exact goal of the exercise. What code was to be used? was it to demo the while loop, the for loop or the switch case ?

This because even though we are really helping you as you have actually done a lot of work yourself( a very big plus as most students want us to write their code for them) sometimes it is better to go back to the teacher and ask him the question. This because he then can perhaps clarify things that the thought where clear, but none of the students actually understood.

In addition to that when we start saying you need to do it entirly different then the teacher will also think that you did not make the stuff yourself and then give you other problems.

Just another thing to think about:
- Do you need to make the pin high or low the get the LED on/off ?

ow and by the way. Please start using the code buttons on top of the reply window to format your code. This will make the threads a lot better readable.

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No code or requirements of the project were given to us. Its all upto us how we make it up, our teacher just want us to use it and develop something useful.

To get LED ON, i think pin should be logic 1.

Please tell me how can i get out of this problem. The output LED does not turn ON.....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok,

"I thinks" are never the correct answer when you are having problems. The only way to get out of trouble is to know things for sure.

so a big step back to cretae a big step forward.....

first write a small program that turns the LEd on
hint -> only init portc and set the entire port to the apropriate level so the led goes on. Now you know if you have to make the pin high or low to get the LED on.
after this is succesfull write 2 simple sub routines called 'LED_ON' and 'LED_OFF' that turn the led on and off. For now you can just make the entire portC high or low, but you have to keep in mind that in the end you need to re-write it to only set the specific pin...

The second step is to use the AVR simulator to see where it all goes wrong. This involves pen and paper too as you want to write out what you want to do and then check in the simulator if this is actually happening.
do this for all your sub calculations seperate so you know all your calculations are ok. This means remove the switch statement.

Now the basic blocks are more or les working.

Next is creating the switch statement. First mit the calculations and just make the LED go on or off depending on the selected case. also check what happens if multiple lines are set as I think you have a mayor problem there that you have not yet discovered.

when that is done you can put it all together and should end up with w aorking design.
This is a step by step approach that you should always try to follow. It seems that you need more time then but in the end it will save you time.

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And make sure when pressed, your switches will pull down the port pins, and not up. If they pull up, you must disable the internal pull-ups.

axos88

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No guys, its not functioning.....

My observation: No error in code but still all PINS B and D initially at logic1. The output LED never glows....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well for one thing your delay is not going to work. It will be discarded by the optimiser. If you need a delay use

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

forget about port B and D......

for a start get the LEd to go on (first app)and then OFF(second app). you can not get more basic then that.
init port c as output ( what you already have done )
then make the entire port high or low stop the program ( with a wait forever loop that you already know how to make) and see what the responce of the led is.

if that works the way you expected to or in the end works and you know why it works that way then and only then you are ready for the next step.

see my previous e-mail.

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have already tried that. I was able to turn ON output LED (connected to pin C0) by just PORTC=0x01.

I dont know whats wrong with my project.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
      switch( PINB )

->

      switch( ~PINB )

Or are your switches connected to VCC? Then you need external pull downs, not the internal pull ups.

Stefan Ernst

Last Edited: Tue. Nov 17, 2009 - 11:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a cotton pickin moment. You are selecting your logic function by using the middle 5 bits in B. You have them set to inputs and the pull-ups enabled - so far so good.

So when no function is selected what value do you think you will read from the PORT?

My money is on it being 0xFF (as the bits are all pulled up). If you then select NOR I presume you do this by pulling bit 4 to Gnd. So what will the entire PIND now read?

My money is on it being 0xEF. Yet in your switch() statement you are looking for the entire bit pattern on PINB being 0x10 for "NOR". Well that's not going to happen is it.

So try inverting your logic

Cliff

PS Note that if you use ~PINB then 0xEF becomes 0x10 ;-)

Last Edited: Tue. Nov 17, 2009 - 11:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok, so step one taken...
I asume that when you write portC = 0x00 the led will be off....
for your info: you now have a debug interface for the rest of your program...... not yet an end solution for your LED vs calculations problem.
so you have 2 routines: one is LED_ON and the other LED_OFF.... if not make them as you will need them.

now a few steps that you can do without forum intervention. ( at least when all should work fine )
1 detect a high level and a low level on a single pin. so when PIND0 is high the LED is ON and when it is low the LEd is OFF. hint: do this inside the forever loop so it gets continuesly updated.
if that works try to get PIND1 to do the same ( agian just PIND1 thus disregarding PIND0

if that works make it such that the LED only goes on when both pins are high. ( hint forget about different functions for now and thus functions selection )

then finally (for a starter to keep you going, and I hope that beyond this point you can figure out what to do next ) do the same for portB making sure that all these switches can be read succesfull.

have fun

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use gate selection as follows:

To use AND operation: I only connect Vcc to PINB1

To use OR operation: I only connect Vcc to PINB2

Is this way correct?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is this way correct?

No the AVR provides pull-UPs, not pull-DOWNs which makes the inputs active LOW not active HIGH. So connect the signal to Gnd, not Vcc to make it active and then invert your software logic to take account of this.

The alternative if you want to do this more "traditionally" is to forget the AVR's internal pull-ups and instead leave them de-activated and connect some external pull-down's. Now your logic is not inverted and your existing software is OK(ish)

Personally I still don't like the fact that you have three unknown input bits in the mix (0, 6 and 7). As long as all 8 bits are pulled to a known state I guess it's OK but when you come to use them later for something else you will need to be masking out the active bits in the middle (0x3E or 0xC1)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

talhahs wrote:
I dont know whats wrong with my project.

The problem is you are trying to advance to quickly..

First turn the LED on and off (using the proper method given in the Bit Manipulation thread (PORTD |= (1<<PD0)..etc) and proper delay routines from util/delay.h

Second learn how to use buttons - no button = no led, button press = led.

After this, return to your logic project.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

talhahs wrote:

Is this way correct?

My question is was it correct ? If you would have followed the stepps I have described a few times now you should have been able to see the result...

and also I agree with Special_D as I already said before.... You are taking to big a steps at a time and keep on falling in the process, but knowing what made you fall so you are not learning...

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
PS Note that if you use ~PINB then 0xEF becomes 0x10 ;-)

So i can use it? Changing PINB to ~PINB will solve my problem (keeping rest of the code unchanged)?? I got the active low thing....

Is this the final code??

#include 

#define _AND_OPERATION		0x02
#define _OR_OPERATION		0x04
#define _NAND_OPERATION		0x08
#define _NOR_OPERATION		0x10
#define _XOR_OPERATION		0x20


void MyDelay ( int iDelay );

int main()
{
	DDRC = 0xFF;    //all as output

	DDRD=0;         //all as input
	PORTD=0xFF;     //pullup enabled

	DDRB=0;         //all as input
	PORTB=0xFF;     //pullup enabled
	
	unsigned char a=0;
	unsigned char b=0;
	unsigned char c=0;
	unsigned char d=0;

    while(1)
    {
    	a = ~PIND & (1 << PIND0) ; // ~ added ,store 0th bit of PIND into 'a'
		
		b = ~PIND & (1 << PIND1) ; // ~ added, store 1st bit of PIND into 'a'
		b >>= 1 ; // perform bitwise right-shift on contents of 'b' one time (align with 'a') 

		switch( ~PINB )   //~ added
		{
			case _AND_OPERATION:
				c = a & b; 	// perform the AND operation
				break ;
			
			case _OR_OPERATION:
				 c = a | b;	// perform the OR  operation
				break ;

			case _NAND_OPERATION:
				d = (a & b);
     				c=~d;		// perform the NAND operation
				break ;
			case _NOR_OPERATION:
				d=(a|b); 	// perform the NORoperation
     				c=~d;
				break ;
			case _XOR_OPERATION:
				c= a ^ b;     // perform XOR operation
    				break ;
  
		}
				
		PORTC = c ; // output to 0th bit PORTC the contents of AND-ed result

    	MyDelay ( 50);
    }

	return 0;
}



void MyDelay ( int iDelay )
{
    int i;

    for ( i = 0; i < iDelay; i++ )
        ;
}

Guys! Thanks a lot for teaching me so much in less time. I will try burning the code tomorrow, i will be happy if its okay. :P

If u still find something wrong with the above code, then plz edit it & send me the final code that i should directly burn without changing a bit. I have project submission day after tomorrow and a report to prepare too.

If that can also not be done, then plz send me some other project which is easy in logic as above one, but is 100% working.

PLease get my above code working that will be the best option..... :cry:

Last Edited: Tue. Nov 17, 2009 - 07:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:

      switch( PINB )

->

      switch( ~PINB )

Or are your switches connected to VCC? Then you need external pull downs, not the internal pull ups.

The dip switches are placed such that:

pressed position - provide VCC

released position - provide GND

But i now understood the active low thing, thats causing problem....so the dip switches will be inverted too?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

Is this way correct?

No the AVR provides pull-UPs, not pull-DOWNs which makes the inputs active LOW not active HIGH. So connect the signal to Gnd, not Vcc to make it active and then invert your software logic to take account of this.

The alternative if you want to do this more "traditionally" is to forget the AVR's internal pull-ups and instead leave them de-activated and connect some external pull-down's. Now your logic is not inverted and your existing software is OK(ish)

Personally I still don't like the fact that you have three unknown input bits in the mix (0, 6 and 7). As long as all 8 bits are pulled to a known state I guess it's OK but when you come to use them later for something else you will need to be masking out the active bits in the middle (0x3E or 0xC1)

Cliff

Please tell me how to connect external pull-ups, if i want to keep the code unchanged??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

unchanged

Eh? We are talking about the addition of one '~' character?!?

But if you want pullups then you just connect a resistor (10K..50K say) from the port pin to your Vcc rail but I hate to have to tell you that in:

   DDRB=0;         //all as input 
   PORTB=0xFF;     //pullup enabled 

th second line MUST be removed - you can't have both pull-ups and pull-downs at the same time or what you have got is a potential divider putting some mid-range voltage into the pin when it's not being driven hard.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok! Got the pull-ups disabled thing, what about the follwoing code, is it OK now??

#include 

#define _AND_OPERATION		0x02
#define _OR_OPERATION		0x04
#define _NAND_OPERATION		0x08
#define _NOR_OPERATION		0x10
#define _XOR_OPERATION		0x20


void MyDelay ( int iDelay );

int main()
{
	DDRC = 0xFF;    //all as output

	DDRD=0;         //all as input
	PORTD=0xFF;     //pullup enabled

	DDRB=0;         //all as input
	PORTB=0xFF;     //pullup enabled
	
	unsigned char a=0;
	unsigned char b=0;
	unsigned char c=0;
	unsigned char d=0;

    while(1)
    {
    	a = ~PIND & (1 << PIND0) ; // store 0th bit of PIND into 'a'
		
		b = ~PIND & (1 << PIND1) ; // store 1st bit of PIND into 'a'
		b >>= 1 ; // perform bitwise right-shift on contents of 'b' one time (align with 'a') 

		switch( ~PINB )
		{
			case _AND_OPERATION:
				c = a & b; 	// perform the AND operation
				break ;
			
			case _OR_OPERATION:
				 c = a | b;	// perform the OR  operation
				break ;

			case _NAND_OPERATION:
				d = (a & b);
     				c=~d;		// perform the NAND operation
				break ;
			case _NOR_OPERATION:
				d=(a|b); 	// perform the NORoperation
     				c=~d;
				break ;
			case _XOR_OPERATION:
				c= a ^ b;     // perform XOR operation
    				break ;
  
		}
				
		PORTC = c ; // output to 0th bit PORTC the contents of AND-ed result

    	MyDelay ( 50);
    }

	return 0;
}



void MyDelay ( int iDelay )
{
    int i;

    for ( i = 0; i < iDelay; i++ )
        ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

talhahs wrote:
Ok! Got the pull-ups disabled thing, what about the follwoing code, is it OK now??

does it work in the simulator? and if you have a real board: does it work when programming the device.

The ony real conclusion I can draw from this post is that you have learned absolutely nothing. and that is a pitty.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code has started to work, but it takes a lot of time before the output LED shows result....Is something wrong with the frequency set up in the project configuration in AVR studio?

I used the following code:

#include 

#define _AND_OPERATION		0x02
#define _OR_OPERATION		0x04
#define _NAND_OPERATION		0x08
#define _NOR_OPERATION		0x10
#define _XOR_OPERATION		0x20



int main()
{
	DDRC = 0xFF;    //all as output

	DDRD=0;         //all as input
	//PORTD=0xFF;     //pullup enabled

	DDRB=0;         //all as input
	//PORTB=0xFF;     //pullup enabled
	
	unsigned char a=0;
	unsigned char b=0;
	unsigned char c=0;
	unsigned char d=0;

    while(1)
    {
    	a = PIND & (1 << PIND0) ; // store 0th bit of PIND into 'a'
		
		b = PIND & (1 << PIND1) ; // store 1st bit of PIND into 'a'
		b >>= 1 ; // perform bitwise right-shift on contents of 'b' one time (align with 'a') 

		switch( PINB )
		{
			case _AND_OPERATION:
				c = a & b; 	// perform the AND operation
				break ;
			
			case _OR_OPERATION:
				 c = a | b;	// perform the OR  operation
				break ;

			case _NAND_OPERATION:
				d = (a & b);
     				c=~d;		// perform the NAND operation
				break ;
			case _NOR_OPERATION:
				d=(a|b); 	// perform the NORoperation
     				c=~d;
				break ;
			case _XOR_OPERATION:
				c= a ^ b;     // perform XOR operation
    				break ;
  
		}
				
		PORTC = c ; // output to 0th bit PORTC the contents of AND-ed result
    }

	return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The output should be instantaneous but it obviously relies on all the inputs and function selection bits being held in a steady state - I presume you use mini DIP switches or something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not using any DIP switches at first, just connected it directly to Vcc (+5V).... using jumper wire....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then if it took some time to show an output the chances are one of the wires is loose.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As the line is input without pull-up and you are using a wire that you do not have connected to ground or VCC( just let it float) it will take a while for the pin to change from a floating line to a low... it will even give un wanted results in your calculations.

add pull-downs to all the lines you use and the problem should disappear. or better enable the pull-ups in the chip and let a logical 1 be a low level on the pin...... then you can use a wire that is left open when it should be a 0. just as would be with using a dip switch.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Upon reflection, this assignment is pretty good for starting with microcontrollers. One learns about main loops, and port configuration, and port reading/writing. Maybe delays and timing. Also function selection, and can lead into things like debouncing, interrupts, and displays.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe so theusch, but the fact is this student has lashed together a page of poorly written code that he does not fully understand the meaning of.

The only realy way would have been to start with the basics, setting bits and reading bits. Then adding the rest in later.

It would have only taken an extra 2 hour tutorial to get to that stage..