I am working on a project translating some Arduino code of a RFM Hopper Transmissor to C, but there are few concepts that I don't fully understand like the DDRB and DDRD.
For example, I call these two methods:
InputSDIO();
OutputSDIO();
which are declared in another file with these lines:
#define InputSDIO() (DDRB &= (~_SDIO))
#define OutputSDIO() (DDRB |= (_SDIO))
and it gives me the following error
error: expression is not assignable
Furthermore, I also get the same error from this call,
RX_ANTOut();
which is defined in another file with the following line:
#define RX_ANTOut() (DDRD |= (RX_ANT))
As I said, the code comes from an Arduino project of a transmissor. If you need any more info or if my question could be more detailed feel free to ask.
In DDRB and DDRD the DDR is data direction register and it determines if a pin is an input or output (the uC is an Atmel AVR), DDRB is the DDR of port B, DDRD of port D. SDIO is a port configuration that is usually implemented as a bitmask. The operators &= and |= have the same meaning as +=, -=,... so i.e. a &= b means a = a & b and so DDRB &= (~SDIO) is equivalent to DDRB = DDRB & (~SDIO) what is a common way of bitmasking the ~ is logical negation & is logical AND, | is logical OR.
SDIO is an 8 bit (? what AVR model exactly is this ? ) binary number something like 0b01110010 that masks the pins of the port, i.e. port D
https://blog.podkalicki.com/bit-level-operations-bit-flags-and-bit-masks/,
What is Bit Masking?
In the datasheet of the ATmega128RFA1 (https://cdn.sparkfun.com/datasheets/Dev/AVR/ATmega128RFA1_Datasheeta.pdf) the function of the DDRs is on page 191 in chapter 14.2.2 Configuring the Pin
Related
I have experiences in AVR programming with CodeVisionAVR. Recently I switched to using Atmel Studio and found a minor but annoying problem: I can't control each PIN/PORT as easy as I did in CodeVisionAVR.
Firstly, let's initialize one certain port:
// Initialzing one port, for example PORT D:
// Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out
DDRD=0x01;
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=1
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (1<<PORTD0);
// After initializing, Port D bit 0 should be the only pin set to out.
In CodeVisionAVR, I can do this:
PORTD.0 = 0; // Set Port D bit 0 to low
PORTD.0 = 1; // Or to high
But in Atmel Studio, addressing Port D bit 0 as PORTD.0 gives me an error. I have to do this instead:
PORTD = (1<<PORTD0); // Set Port D bit 0 to high
PORTD = (0<<PORTD0); // and low
As you can see, addressing by shifting bits is much less clean and harder to read / write. I thought CVAVR used something like a struct to imitate the dot (.) addressing method (in C we don't have classes), or some overloaded operators, or some macros, but after digging the included header files in CVAVR, I could only find this:
sfrb PORTD=0x12;
// ... other ports ...
sfrb PIND=0x10;
My question is, can I imitate the bit addressing method of CVAVR in Atmel Studio? If yes, how? Or was that some IDE-exclusive feature?
What you are saying about CodeVisionAVR
PORTD.0 = 0; // Set Port D bit 0 to low
PORTD.0 = 1; // Or to high
is not a valid C semantic, so if you didn't make a mistake on your predicate it must be a codevision compiler extension.
That kind of assignment in C represent an struct access, but you can not declare a struct member (or any other identifier) starting with a number, so PORTD.0 will produce an error.
Also when you do this:
PORTD = (1<<PORTD0); // Set Port D bit 0 to low
PORTD = (0<<PORTD0); // and high
you are not doing what you comment, you are assigning (assuming PORTD0==1) 0x1 to PORTD in the first expression and 0x0 in the second. If your intention is to manipulate only one bit, this is what you should do:
PORTD |= (1<<PORTD0); //sets bit PORTD0 high in PORTD
PORTD &= ~(1<<PORTD0); //sets bit PORTD0 low in PORTD
PORTD ^= (1<<PORTD0); //toggles PORTD0 in PORTD
You should read about bit manipulation in C, here is a post with more examples
Sometimes those actions are encapsulated in a macro, this an example of how you could do it:
#define BitSet(Port,Bit) (Port|=(1<<Bit))
#define BitClear(Port,Bit) (Port&=~(1<<Bit))
#define BitToggle(Port,Bit) (Port^=(1<<Bit))
#define SetBits(Port,BitMask) (Port|=BitMask)
#define ClearBits(Port,BitMask) (Port&=~BitMask)
#define ToggleBits(Port,BitMask) (Port^=BitMask)
//then you can use it
BitSet(PORTD,0) ; //Sets the bit0
BitSet(PORTD,1) ; //Sets the bit1
BitSet(PORTD,2) ; //Sets the bit2
// or
BitSet(PORTD,PORTD0) ; //Sets the bit0
BitSet(PORTD,PORTD1) ; //Sets the bit1
BitSet(PORTD,PORTD2) ; //Sets the bit2
...
SetBits(PORTD,0x55) ; //Sets the bits 0,2,4, and 6. Leaves the other unchanged
ClearBits(PORTD,0x55) ; //Clear the bits 0,2,4, and 6. Leaves the other unchanged
I'm using an Atmega328. I have output pins that are "randomly" distributed along the pinout, i.e. they don't belong to the same ports. For example, my output pins could be PB0, PB4, PC1, PC3 and PD1.
I have always used Assembly to program microcontrollers, so this would be my first time using C. What I want to know is if there is a way to avoid using DDRx and Px for each pin to set them or clear them.
For example, I would like to use something like this to set the first bit of Port B:
#define NAME_1 DDRB,0
sbi NAME_1;
Is this possible?
EDIT:
Maybe I didn't express myself clearly. What I want is to be able to refer to certain I/O port pins with some meaningful names. For example, name PD3 "blue_LED", so that the code is more readable and, if the blue LED's position is changed later, the code can be easily modified. Stated another way, I want to be able to turn on and off certain pins with their names not being hard-coded. Is there a way?
The sbi instruction is special in that it directly manipulates a bit in an I/O Port on the AVR platform. The normal course with I/O ports is that you have to use other instructions (like out) to copy whole words between the I/O port and a register.
That said, there's no sbi in C. C just doesn't know about these special features of one particular platform. For the assembly you give as an example, you would write in C:
DDRB |= 1<<0;
I personally think this looks quite concise, but of course you COULD define a macro
#define sbi(x,b) (x) |= 1<<(b)
sbi(DDRB, 0);
(where b is the "bit number") and maybe the other way around
#define cbi(x,b) (x) &= ~(1<<(b))
cbi(DDRB, 0)
This would work, but I recommend not to use it. While the first notation DDRB |= 1<<0; is obvious to any C programmer, using macros like this probably isn't.
As a final note, if you are concerned about performance: I haven't verified this, but I'm pretty sure avr-gcc is smart enough to emit sbi and cbi instructions when a bit mask operation on an I/O port effectively just changes a single bit. edit: see JLH's answer for an experimental result that gcc-avr indeed is smart enough to emit these sbi/cbi instructions.
I use avg-gcc on to program Atmel AVRs and the support packages most definitely know about cbi, sbi, and all instructions for that matter. So there's no need to resort to assembly unless you want to. Here's some disassembled C to prove it.
PORTD |= (1 << PD0);
d8: 58 9a sbi 0x0b, 0 ; 11
Now I'll show you how. You can set each bit of each port to do either input or output very easily.
DDRA |= (1<<PA0);
has the effect of making pin 0 on port A an output as shown:
bit76543210
00000001 // or-ing the 1 adds 1 leaving the other bits alone.
To also make pin A3 an output, do this:
DDRA |= (1<<PA3);
bit76543210
00001001 // now the DDRA register looks like this, pins 0 and 3 set as outputs
Tedious, right? Well, these right-side expressions evaluate to constants so you can combine these into one statement:
DDRA |= (1<<PA0) | (1<<PA3);
and the compiler will fold the right hand side into one constant and |= it into the register. So, you really need only one statement like this per port, and the compiler makes it very efficient.
That takes care of direction -- input or output. The next is to set and clear outputs.
To set an output:
PORTD |= (1<<PD); // turns pin 0 on port D on (high) as an output.
PORTD &= ~(1<<PD); // turns pin 0 on port D off (low) as an output.
PORTD ^= (1<<PD); // toggles it (high-> low) or (low->high as an output.
EDIT:
To the extra requirements you named about using meaningful names, of course you can do that. I routinely do this to avoid having to remember what's connected to what. For example, from that same project:
#define LED_INDICATOR_PIN PA0
#define LED_INDICATOR_PORT PORTA
#define LED_INDICATOR_DDR DDRA
I refer to the 'friendly' names in my code:
void initialize(void)
{
// Set up an output pin to blink an LED to show sign of life.
LED_INDICATOR_DDR |= (1 << LED_INDICATOR_PIN);
// Set up TTY port.
init_uart();
}
void toggleLED(void)
{
LED_INDICATOR_PORT ^= (1 << LED_INDICATOR_PIN);
}
Much easier to read. Is that what you're after? I know it's what I do every time.
With C++ I wrote something like this:
//IO = I/O Subsystem
inline void Io_LEDred_Configure() {DDRB |= 1<<0; } //Port B0
inline void Io_LEDred_On() {PORTB |= 1<<0; }
inline void Io_LEDred_Off() {PORTB &= ~(1<<0);}
inline void Io_LEDgreen_Configure() {DDRD |= 1<<3; } //Port D3
inline void Io_LEDgreen_On() {PORTD |= 1<<3; }
inline void Io_LEDgreen_Off() {PORTD &= ~(1<<3);}
If you have to switch an IO to a different port you have to change only those three lines and you're done.
In C++ the compiler emits exactly that code what you as an assembler coder would write. In C you have to use a regular function. But the calls coming with some overhead. If you want to avoid this you have to use macros:
#define IO_LEDRED_CONFIGURE DDRB |= 1<<0
#define IO_LEDRED_ON PORTB |= 1<<0
...
I am currently programming raspberry pi.
I wanted to get clear out some doubts, please can anybody help.
Here is the code snippet.
#define GPIO_BASE 0x20200000UL
gpio = (unsigned int*)GPIO_BASE; gpio[GPIO_GPFSEL1] |= (1 << 18);
This code is from http://www.valvers.com/embedded-linux/raspberry-pi/step01-bare-metal-programming-in-cpt1
I do understand the functionality of the code to switch on and switch off the LED .
I have problem understand the these statements
gpio = (unsigned int*)GPIO_BASE; gpio[GPIO_GPFSEL1] |= (1 << 18);
First you have some address in memory.
define GPIO_BASE 0x20200000UL
Under this address exists a control structure for GPIO. In your case it's just an array of ints. Writing a value to a certain field of that structure makes GPIO set its pins.
gpio = (unsigned int*)GPIO_BASE;
You select some register in your structure (the address (unsigned int*)GPIO_BASE + GPIO_GPFSEL1) and you set the 18th bit on.
gpio[GPIO_GPFSEL1] |= (1 < < 18);
The GPIO will likely respond with setting one of its pins to high state. The LED attached to that pin will start glowing.
Well ...
The first statement:
gpio = (unsigned int*)GPIO_BASE;
sets the pointer variable gpio equal to the value of GPIO_BASE, and also casts the latter to a pointer type.
The second
gpio[GPIO_GPFSEL1] |= (1 << 18);
does a bitwise OR of the value in gpio[GPIO_GPFSEL1] with the constant value 1 << 18. This "turns on" bit 18 (counting from 0) in the register GPIO_GPFSEL1.
Remember that in C, array indexing a[b] is the same as *(a + b), i.e. it's a pointer addition and dereferencing.
After
gpio = (unsigned int*)GPIO_BASE;
gpio points to 0x20200000 memory address. This is "The base address of the GPIO peripheral (ARM Physical Address)".
Article that you've linked says that:
Back to the processor manual and we see that the first thing we need
to do is set the GPIO pin to an output. This is done by setting the
function of GPIO16 to an output. Bits 18 to 20 in the ‘GPIO Function
Select 1′ register control the GPIO16 pin.
Statement
#define GPIO_GPFSEL1 1
gpio[GPIO_GPFSEL1] |= (1 << 18);
breaks down to:
gpio[1] = gpio[1] | (1 << 18);
So, address (0x20200000 + sizeof(unsigned int)) is dereferenced and OR operator sets the bit 18 to 1.
I am currently working on setting up a framework in C for usage between several microcontrollers.
The framework has to carry all device specific code, so the application only contains the abstract usage of peripherals (like SerialPort_Read, write, SetBaudRate, etc etc.)
One of the things I am struggling with to find a solution for in C are the I/O pin map. I've seen projects (like the very very popular Arduino) where the pin map is putten in a LUT (look up table) which is used during runtime. However, this LUT will never be modified during runtime, so there is no use to have this in the memory.
For example, this function resolves some bit indexes and registers from some 'const uint' tables, and either sets or clears a bit:
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
Because this is actual C code running on the controller it's draining effiency and speed. I'd rather define some sort of macro that does the same thing, but is already resolved during compilation to a 'one-liner' that can be compiled much more efficiently:
GPIO_Write(PORTA, 5, 1); // Write '1' to pin 5 on PORTA
> LATA |= 1<<5; // Sets bit 5 high
GPIO_Tris(PORTA, 4, OUTPUT); // Set pin 4 on PORTA to output
> PORTA &= ~(1<<4); // sets pin 4 as output I/O type
Does anyone know if it's possible (and how) to define and use a look-up table with a macro in C?
At this moment I am using the MicroChip C30 compiler, which I believe is based in GCC. It's supposed to be portable between different compilers, including MicroChip C18, C32 and in further also ARM and AVR.
For your specific example, something along these lines will work:
#define WRITE_PORTA LATA
#define GPIO_Write(port, pin, value) \
(value ? WRITE_##port |= (1U << (pin)) \
: WRITE_##port &= ~(1U << (pin)))
#define INPUT 0
#define OUTPUT 1
#define GPIO_Tris(port, pin, direction) \
((direction) == INPUT ? port |= (1U << (pin)) \
: port &= ~(1U << (pin)))
You'll have to make sure to define LATA and PORTA in a way the system will understand - in particular trying to overload its meaning the way it seems to be in your example might be hard to resolve.
Which processor or microcontroller are you targeting?
You might be underestimating the usefulness of the LUT.
For many processors, the LUT does more than map a 'logical' pin number to a single value, the 'physical' pin number. The LUT maps the 'logical' pin number to several pieces of information.
In general, the 'logical' pin is mapped to the port address of the appropriate read/input or write/output register, and the bit offset within the read or write register. So the pin value, on many MCU's, is really mapped to a struct. It might also include a mapping to the data direction register and fields within it, as well as registers which set the state of pull-up or pull-down resistors.
For example, I have code to multiplex a 8x8 display. At run-time, I need to use pinMode to turn a pin from an output to a high impedance input, and so that information needs to be encoded somehow.
It is possible to do this sort of thing, with some ingenuity, on some MCU's.
ARM MCU's (and I believe 8051, though I've never used one) using 'bit band addressing' http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html
This assigns a unique memory address for each port pin, and fixed offsets can derive the address of the pin for the other data register, and other functions. This is not magic, the code encodes the information that is often stored in the LUT.
For other MCU's, they really do need both port and bit position, so it is two values for each pin number.
If you are willing to ditch the idea of using integers for pins, and instead use names, like P0, P1, then you could initialise a lot of const struct's, one per pin name, and your functions would take the const struct values. The struct would contain the initialised port and bit offset or bit mask values. The compiler may be able to optimise for speed. This would avoid having a LUT, but would still use similar amounts of space for pins that are used. You might be able to arrange it so that unused pins would not need to be included in the code, and hence saving space.
Edit: If you are willing to use C++, I'd suggest C++ templates which can give a much better solution than macros. They can be type safe, and are often easier to debug (if you have hardware debugging, e.g. JTAG and gdb)
Consider the following macro:
#define write(port, pin, value) do { \
if (value) \
LAT##port |= 1 << pin; \
else \
LAT##port &= ~(1 << pin); \
} while (0)
Usage:
write(A, 3, 1); // compiles to LATA |= 1 << 3;
write(B, 2, 0); // compiles to LATB &= ~(1 << 2);
Is that the kind of thing you were after?
I've seen it done (https://github.com/triffid/Teacup_Firmware/blob/Gen7/arduino.h) with a couple macros:
/// Read a pin
#define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN))
/// write to a pin
#define _WRITE(IO, v) do { if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }; } while (0)
/// set pin as input
#define _SET_INPUT(IO) do { IO ## _DDR &= ~MASK(IO ## _PIN); } while (0)
/// set pin as output
#define _SET_OUTPUT(IO) do { IO ## _DDR |= MASK(IO ## _PIN); } while (0)
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
/// Read a pin wrapper
#define READ(IO) _READ(IO)
/// Write to a pin wrapper
#define WRITE(IO, v) _WRITE(IO, v)
/// set pin as input wrapper
#define SET_INPUT(IO) _SET_INPUT(IO)
/// set pin as output wrapper
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
with:
#define DIO0_PIN PIND0
#define DIO0_RPORT PIND
#define DIO0_WPORT PORTD
#define DIO0_PWM &OCR0B
#define DIO0_DDR DDRD
#define DIO1_PIN PIND1
#define DIO1_RPORT PIND
#define DIO1_WPORT PORTD
#define DIO1_PWM &OCR2B
#define DIO1_DDR DDRD
...
You could modify the macros to take straight integers rather than DIOn
I'm writing a new and special library whith new algorithms and abilities for KS0108 GLCD Driver. I'm using ATMega16. My dot matrix GLCD dimension is 128x64.
How can I use #define code to define different port pins?
for example: #define GLCD_CTRL_RESTART PORTC.0
IDE: AVR Studio 5
Language: C
Module: 128x64 dot matrix GLCD
Driver: KS0108
Microcontroller: ATMega16
Please explain which headers I should use? and also write a full and very simple code for ATMEga16.
In ATmega, pin values are assembled in PORT registers. A pin value is the value of a bit in a PORT. ATmega doesn't have a bit addressable IO memory like some other processors have, so you cannot refer to a pin for reading and writing with a single #define like you suggest.
What you can do instead, if it helps you, is to define macros to read or write the pin value. You can change the name of the macros to suit your needs.
#include <avr/io.h>
#define PORTC_BIT0_READ() ((PORTC & _BV(PC0)) >> PC0)
#define WRITE_PORTC_BIT0(x) (PORTC = (PORTC & ~_BV(PC0)) | ((x) << PC0))
uint8_t a = 1, b;
/* Change bit 0 of PORTC to 1 */
WRITE_PORTC_BIT0(a);
/* Read bit 0 of PORTC in b */
b = PORTC_BIT0_READ();
thanks a lot, but i found this answer in AVR Freaks at here:
BV=Bit Value.
If you want to change the state of bit 6 in a byte you can use _BV(6) which is is equivalent to 0x40. But a lot us prefer the completely STANDARD method and simply write (1<<6) for the same thing or more specifically (1<<<some_bit_name_in_position_6)
For example if I want to set bit 6 in PORTB I'd use:
Code:
PORTB |= (1 << PB6);
though I guess I could use:
Code:
PORTB |= _BV(6);
or
Code:
PORTB |= _BV(PB6);
But, like I say, personally I'd steer clear of _BV() as it is non standard and non portable. After all it is simply:
Code:
#define _BV(n) (1 << n)
anyway.
Cliff