A microcontroller is fundamentally controlled by storing certain values to certain specific memory addresses. For example, an ARM micontroller, memory address 0x4000AA00 might be an 8-bit wide address that toggles a digital output pin mapped to a specific bit when 1 is written to it. So to toggle all 8 pins, you would write:
*((uint8_t *) 0x4000AA00) = 255;
This casts the address as a pointer, derefences it, and then stores 255 to it, which is 0b11111111
.
These memory addresses aren't really memory, they're used to control peripherals.
You read the "Technical Reference Manual" for the device and it has a reference for each memory address and what it does, divided into function units (timers, inputs, outputs, whatever).
You should find the "memory map" and read that section, usually in an intro.
You should also skim the clock and power sections, since those are essential and might fuck you up if you don't read them.
Other than that, you read the section for the device you're using.
Most vendors supply increasingly high-level layers for their devices:
-
HAL (hardware abstraction layer- creates a #define for each important address 0xNNNNNNNN with a better name)
-
Device Drivers- creates basic functions (write_bit, write_spi, read_spi)
-
OS-Layer- creates basic utitilies to manage asynchronous IO and stuff- maybe a file system, maybe a message queue