Looking for a tutorial - what is this code format/language called?

I frequently see code for AVR’s written in the format/language below, and I have no idea what its proper name is. And because I don’t know what its called, I can’t very well educate myself on its usage. There have been a few occasions where I’ve been able to gleam enough about its format to make some minor changes, but its always a very tricky process with lots of hiccups.

I would like to demystify it for myself so I can actually utilize it effectively. If anyone can point me at a good resource to learn more about it, that would be awesome.

The code below was taken from a page on programming an ATTiny10. It takes an input from the ADC and converts it to a PWM frequency, but I can’t follow it well enough to actually understand what’s happening on each line.

#include <avr/io.h>
#include <stdint.h>

int main (void) {
  DDRB = 1;                       // PB0 as an output

  // Set up ADC on PB2
  ADMUX = 1<<MUX0;                // ADC1 (PB1)
  ADCSRA = 1<<ADEN | 3<<ADPS0;    // Enable ADC, 125kHz clock

  // Set up waveform on PB0
  TCCR0A = 1<<COM0A0 | 3<<WGM00;  // Toggle OC0A, Fast PWM
  TCCR0B = 3<<WGM02 | 4<<CS00;    // Fast PWM with OCR0A as TOP; /256

  // Main loop
  for (;;) {
    ADCSRA = ADCSRA | 1<<ADSC;    // Start
    while (ADCSRA & 1<<ADSC);     // Wait while conversion in progress
    OCR0A = ADCL;                 // Copy result to frequency output
  }
}

And because I don't know what its called,

It is C.

To understand it properly, you'll have to refer to the processor's datasheet.

Arduino provides a simpler, more portable wrapper for this stuff.

That's just C. Those are all direct register reads and writes to all the different control registers on the chip.

The first line sets pin 8 to OUTPUT and 9 through 13 to INPUT. Arduino - PortManipulation

The rest sets up the analog input to free-run and sets up a PWM waveform on one of the pins and then sits back and reads the analog input when it is available and copies it into a register on the timer to control the frequency of the PWM.

Maybe this will help:

In the code in the Original Post the words DDRB, ADMUX and ADCSRA are the names of registers in the Attiny microprocessor.

And the words MUX0. ADEN and ADPSO are the names of bit positions within the registers.

All of these will be described in the Attiny10 datasheet.

...R

Sometimes called “bare metal c programming”, or “low level c programming” because it uses the c language to directly manipulate the microcroller hardware, with using one of the “higher level” libraries like those that come with arduino.

Robin2:
And the words MUX0. ADEN and ADPSO are the names of bit positions within the registers.

Are they not symbolic names for the values of the respective bits? The bit positions are usually named as registername.x; where, x has the range 0 to 7 indicating bit position. For example:

GolamMostafa:
The bit positions are usually named as registername.x; where, x has the range 0 to 7 indicating bit position. For example:

Extensions to some C compilers use that notation. GCC does not. The dot format is typically a member of a struct or class (C++) and the member standard naming convention doesn't allow identifiers to begin with a number.

silly_cone:
I would like to demystify it for myself so I can actually utilize it effectively. If anyone can point me at a good resource to learn more about it, that would be awesome.

1. Physical Pin Diagram of ATtint10 MCU


Figure-1: Physical pin diagram

(1) By default, Pin-1, 3, 4, and 6 are digital IO pins of Port-B Register. From the following digram (Fig-2), we can view the 1-bit (Bit-2) structure of the 4-bit wide Port-B Register of ATtiny10 MCU.
portb.png
Figure-2: 1-bit structure of Port-B Register of ATtiny10 MCU

(2) The PB0-PB3 IO lines of Port-B Register can be configured to work as analog channels (ADC0 - ADC3) for the internal 8-bit ADC (analog-to-digital converter) Module. Figure-3 depicts the internal structure of the ADC Module.
adcattiny.png
Figure-3: ADC Module of ATtiny10 MCU

2. Programming Procedure for the ADC Module
(1) Turn PB1-pin into ADC1 channel with the help of ADMUX Register


Figure-4: ADMUX Register of ATtiny10 MCU

To select ADC1 channel, MUX0-bit should be LH (1) and MUX1-bit should be LL (0). MUX1-bit is already at LL-state by default; so, it is enough to put LH at MUX0-bit position. We can execute one of the following instructions to select ADC1 channel.

ADMUX = 0b00000001;  //pult LH at MUX0-bit and LL at MUX1-bit
ADMUX = 1<<MUX0;  //this line puts LH(1) only at MUX0-bit without disturbing other bits of ADMUX Register
OR
bitWrite(ADMUX, 0, 1);   //RegisreName. bitPosition, bitValue
OR
bitSet(ADMUX, 0);   //RegisterName, bitPosition

(2) Enable the ADC Module and select conversion frequency with the help of ADCSRA Register


Figure-5: ADCSRA Register of ATtiny10 MCU

ADC Module becomes active (enabled) when LH is stored at ADEN (bit-7) of the ADCSRA Register. Conversion frequency is set at the standard 125 kHz with the help of ADPS[2:0] bits of ADCSRA Register. A value of ADPS[2:0] = {1, 1, 0} = {1, 1, 0} (ADC Clock Prescaler division factor is 64) will set the
conversion frequency at 125 kHz. We may execute one of the following instruction fo these purposes:

byte x = ADCSRA;
ADCSRA = x | 0b1000 0110; // ADEN(1) .(unaffected) . . . ADPS2(1), ADPS1(1), ADPS(0);
OR
//ADCSRA = 1<<ADEN | 3<<ADPS0;   //

I really don't understand this part (3<<ADPS0) of the last instruction; somebody may explain it.

(3) Issue 'Start Conversion' command to the ADC by putting LH at the ADSC-bit of the ADCSRA Register of Fig-5. The following instruction stores LH at the ADSC-bit without affecting other bits of the ADCSRA Register.

ADCSRA = ADCSRA | 1<<ADSC;    // Start conversion

(4) Wait until conversion is done. The ADCSC-bit remains at LH-state as long as the conversion is going ON; at the end of conversion, the ADSC-bit assumes LL-state. So, keep polling this bit for LL-state. We can execute one of the following instructions.

while(bitRead(ADCSRA, 6) != LOW)
{
   ;
}
OR
while (ADCSRA & 1<<ADSC);     // Wait while conversion in progress

(5) At the end of conversion, read the ADC value and use it.
At the end of conversion, the digital value is stored in the ADCL Register (Fig-6) of the ADC Module. We can assign the value of the ADCL Register to any valid 8-bit variable by executing the following instruction:


Figure-6: ADCL Register of ADC Module of ATtiny10 MCU

byte x = ADCL;

portb.png

adcattiny.png

Thank you very much for the information, everyone! It is much appreciated. :slight_smile:

I'll digest what's been provided here and see where that takes me.