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.

'sbit' in avr?

Status
Not open for further replies.

Ajax12

New Member
hello all :)
I have worked with 8051 microcontroller and this is my first time with avr. I am simply trying to run a dc motor using switches and an atmega32.
With 8051, i could set the specific bits to what i want so i could use only the bits for what i need.
sbit motor_front=P0^0;

now how do i do this in AVR? i.e I dont want to use the whole port. I just want to check if the first bit in portx is high or low.. using the whole port is not helping. I am not able to control a simple dc motor..
any help will be useful.
thank you
 
There are 2 possible ways to do that.
First the command to clear and set single Bits in Registers:
sbr r16,0b01000001 ;Sets bit 0 and 6 in Register r16
cbr r17,0b00000011 ;Clear bit 0 and 1 in Register r17

Then to set and clear Bits in I/O's:
sbi portd,0 ;Sets bit 0 of PortD
cbi portd,1 ;Clear bit 1 in PortD

Not all of the I/O registers can be manipulated with bit operations.
Sometimes it is necessary to load an I/O register value into a multi use register, manipulate the values and then write it back to source.

To make a branch instruction appending from a single bit, you could store it into the t-bit of the SREG.
bst r16,3 ; stores bit 3 of r16 into the t-bit of SREG
brts jump ; If t is set a jump to label jump would be processed
nop ;other code will be processed
nop
nop

jump:
;Your Code

Another possible way is to make an AND with the according bit:
and r16,0b00100000 ;AND operation with bit 5 of r16 the zero flag would be manipulated
breq jump ;Bit 5 is 0 jump to label jump
nop ;Do other code
nop
nop

jump:
;your code
 
Last edited:
well thanks but not exactly what i was looking for. i want to check if the particular bit is high or low..
if(PORTB.0==1) //if the 0th bit of port b is 0 ...
PORTA=0x01;

is this syntax correct?
must i do anything else before i can use this syntax?
 
My Code Example was in Assembler and do that.

In "C" i would use the Syntax
if((PINB&0b00000001)>0) // AND with the according bit, Compare with 0
{
PORTA=0x01 // Bit is 1 routine
}
else
{
// Bit is 0 routine
}
that should work with any "C" Compiler.

Im not shure whether your code will work. It append from the used Compiler too.
When you'll get information about an input, you should use the PINx Command.
The PORTx command can be used for setting the Output, or to activate the internal Pullups in an AVR Controller and stays at the last set value in spite of changes at the input.
The information about the actual state of an input, ist taken in the PINx register!
 
PINB shows you the state of the I/O Port.
PORTB set or clear the Port when DDRB is switched to Output.
PORTB switch on the internal Pull Up Resistor when DDRB ist switched to input.
That is possible for every single bit of the port.

Most Ports of the AVR Controller Family has internal Pull Up Resistor funktion, but not all AVRs at all Ports.
Refer the according Datasheet to get more Information.

The Value of that internal Resistor is not specified exactly. The Value is about 47 kOhm.
 
I think your description of pin vs port and ddr needs to be fleshed out a little more wkrug, it can cause massive headaches for people that don't understand it.

The PINB register is directly fed from the port driver, it will always show you the actual voltage state of an I/O line, of it's 0 the line is low, if it's 1 it's high, the exact voltage where this transition occurs is listed in the PDF for your particular AVR chip. One neat trick on all but the oldest AVR lines is that writing a logic 1 to the PINB register will cause the corresponding PORTB bit to invert using a single instruction. (Ordinarily you would have to read the portb logically invert the value and then write it back) it allows extremely fast bit twiddling.

DDRB is the direction register, if a bit here is set to 1 then the corresponding I/O line is driven as an output. If it's 0 it's driven as an input.

PORTB is the register that determines the desired port state of the I/O line, when DDRB is 1 the I/O line is set to output, when the PORTB bits are set to 1 that I/O line will try source current, when it's set to 0 it will try to sink current. When DDRB bits are set to 0 (input) the corresponding portB pins will turn on or off the internal pullups on that I/O line. This is very important to know because if you're using an I/O line as an output that's set to high and then decide to switch it to input you may have problems if you don't account for the fact that portB was still set to 1 so the pullups are enabled on that I/O line.

Another thing to note about the pullup resistance is that there isn't infact a pullup resistor it's a cmos junction so it acts more like a current source, the resistance value given is an approximation of equivalent resistance.

One neat thing to note about all this information is that if you're using PORTB as an output you can use PINB to determine the ACTUAL state of the pin (not the logical state) this is a commonly used trick to measure capacitance via a fixed resistance, what you do is measure the number of cycles after you change the portB register until the corresponding PINB register actually changes state. If you have the time to discharge and know the resistance you can calculate the capacitance.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top