August 06, 2009 by amco After I have finished project Bitwise arithmetics from Nerdkits guide where is pointed that state of the PIN is high when it is NOT connected to the ground and that is OK. After that I tryed project from AVR an Introductory course (Pushbutton LED) where you must push the button to turn LED on. When button is pushed pin is connected to the ground but here is code in assembly where I get confused: ldi Temp, 0b00010000 out PortC, Temp //pull-up PC4 Start: sbis PinC,4 //When pushbutton is pressed PC4 is connected to the ground and LED is ON (this works) rjmp Ledoff sbi PortC,5 // LED On rjmp Start When you look example from Nerdkits guide PinC should be in high state when you connect power supply and LED should be ON and after you push the button PinC should be in low state. But in example from this book it is opposite: when you connect power PinC is low and when you connect PinC to the ground it is in high state. Please explain somebody this low and high states of pins. Hi amco! You noticed correctly, indeed the pin is treated differently in those two cases, but that's not a mistake. An I/O pin can be configured in a number of ways. ATmega8 datasheet will tell you much more and I'll write just the gist of it. The state of an I/O pin p on port x is controlled using bit p in the DDRx and PORTx registers. DDRx means "data direction" of the pin: when the bit 1, port is configured as output port; 0 means it's used for input. Now, let's leave aside "input" state of the pin and focus only on the "output" mode, as it is relevant for your question. When a port is configured for output (its DDRx bit is 1), then the level of the pin can be driven by writing to the corresponding bit in the PORTx register. Write a 1 to drive the pin high, close to voltage supply level; write a 0 to drive it low, or close to ground. To wit: ``````/* I/O pin 2 on port B: PB2 data direction register is DDRB */ DDRB |= (1 << DDB2); /* sets the proper data direction bit ON */ /* analogous ASM code: sbi DDRB, DDB2 */ PORTB |= (1 << PB2); /* drives the I/O port PB2 high: connect it to the anode of an LED and it will light up, provided that the cathode is grounded */ /* analogous ASM code: sbi PORTB, PB2 */ PORTB &= ~(1 << PB2); /* drives the I/O port PB2 low: connect it to the cathode of an LED and it will light up, provided that the anode is connected to +V */ /* analogous ASM code: cbi PORTB, PB2 */ `````` If you're planning to use the pins to control any considerable amount of current, say in excess of 30-40mA, you'd better not use the pins directly to sink or source that current, because the absolute maximum DC current rating for ATmega's I/O pins is 40mA. Go beyond that and the entire chip would likely begin to heat noticeably, eventually giving up its tiny electronic soul in the form of pale blue smoke. Get the datasheet for ATmega168 and hop to chapter 13, "I/O Ports", for a thorough discussion, including input states, pull-ups and Tri-stateā¢, er, HI-Z modes of operation. There's been some discussion about those on here already, especially regarding pull-ups, so feel free to search and do ask if anything is unclear! Best, Zoran Thanks Zoran for reply, I will try to read more about this subject. But just to clear more about my question: I'm clear about setting pins to be Input or Output and pulling resistors up and down (very good explanation with changing LED anode & cathode connection with MCU pin). But here is my source of confusion: Bitwise arithmetics from Nerdkits guide and my assembly example are similar but please explain this: Bitwise arithmetics example reads (1) from input pins when that pin is Not grounded (for example if you just pullup DIP switch from the board result will be 7+7=14 - all 1's on PINx) Assembly example: scenario when input PINx is NOT connected to the ground - LED is OFF. I mean when testing this on MCU LED is OFF until you push the button and connect that PINx to the ground then LED is ON. So look this part of assembly program: Start: sbis PinC,4 <--- explain this rjmp Ledoff sbi PortC,5 rjmp Start sbis PinC,4 - this instruction execute Ledoff instruction only when PC4 is 0, right? QUESTION is why SBIS instruction in assembly program reads 0 from PINC4 when PINC4 is not grounded (pushbutton is not pressed) but in Bitwise arithmetics C program reads 1 from PINCx when DIP switch is not grounded? Thank you! Best, Amir Hi amco, That is a bit odd. I am pretty sure that in both situations pushing the button will result in the pin being low. After all, you are grounding pin, it should be reading 0! But you are right, that is not what the code seems to suggest is happening. Can you give us a bit more information about how you are wiring this example up, and maybe provide the complete code of the example. I'm sure between all of us we can make sense of this conundrum. Humberto Sorry everybody I found what is wrong. There is mistake in book "AVR an Introductory course" from John Morton in Program B example and in book (page 33) where is stated that pin is high when it is grounded. That is source of my confusion. This is example program from the book little bit changed for atmega168 pins: =========================================== .nolist .include "m168def.inc" .list ;================ ; Declarations .def Temp = r16 rjmp Init Init: ldi Temp, 0b00100000 out DDRC, Temp ldi Temp, 0b00010000 out PortC, Temp Start: sbis PinC,4 rjmp Ledoff sbi PortC,5 // here is led off because on both pin is +V rjmp Start Ledoff: //here is mistake, actually this should be LedON because in authors scheme LED anode cbi PortC,5 // is connected to the +V rjmp Start Guess I have learned to check examples from books and to double check everything I read :) My mistake... Everything is correct in your explanation here at forum and in Nerdkits guide. Thank you Zoran and Humberto again for help. Best regards, Amir