Advertisement
๐Ÿ“ข 728ร—90 Banner Ad

๐Ÿ’ป Microcontroller Code Examples

Ready-to-use code for STM32, Microchip PIC/AVR, Nuvoton, Arduino, Raspberry Pi, Jetson Nano โ€ข UART, SPI, I2C, ADC, DAC, BLDC, YOLO, OpenCV.

๐Ÿ’ป STM32 (STMicroelectronics)

ARM Cortex-M based MCUs โ€ข STM32F1, F4, G0, H7 series. Use STM32CubeIDE or Keil MDK.

HAL LibraryCubeMXFreeRTOSDMA
/* STM32 UART Transmit/Receive โ€ข HAL Library */
/* Configure UART in CubeMX: USART1, 115200 baud, 8N1 */

#include "main.h"
#include <string.h>
#include <stdio.h>

extern UART_HandleTypeDef huart1;
uint8_t rxBuf[64];
char txBuf[64];

/* Transmit string */
void UART_SendString(char *str) {
    HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), 1000);
}

/* Receive with timeout */
void UART_Receive(uint8_t *buf, uint16_t len) {
    HAL_UART_Receive(&huart1, buf, len, 1000);
}

/* Interrupt-based receive (non-blocking) */
void UART_StartReceiveIT() {
    HAL_UART_Receive_IT(&huart1, rxBuf, 1);
}

/* Callback โ€ข called when byte received */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART1) {
        // Process rxBuf[0] here
        HAL_UART_Receive_IT(&huart1, rxBuf, 1); // Re-arm
    }
}

/* printf redirect to UART */
int __io_putchar(int ch) {
    HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
    return ch;
}

/* In main loop */
void app_main() {
    UART_StartReceiveIT();
    sprintf(txBuf, "STM32 UART Ready\r\n");
    UART_SendString(txBuf);
    while(1) {
        printf("Tick: %lu\r\n", HAL_GetTick());
        HAL_Delay(1000);
    }
}
/* STM32 SPI Master โ€ข HAL Library */
/* CubeMX: SPI1, Mode=Full-Duplex Master, 8-bit, CPOL=0, CPHA=0 */

extern SPI_HandleTypeDef hspi1;

/* CS pin โ€ข configure as GPIO Output in CubeMX */
#define CS_LOW()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define CS_HIGH()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

/* Write single byte */
uint8_t SPI_WriteByte(uint8_t data) {
    uint8_t rx;
    CS_LOW();
    HAL_SPI_TransmitReceive(&hspi1, &data, &rx, 1, 100);
    CS_HIGH();
    return rx;
}

/* Write buffer */
void SPI_WriteBuffer(uint8_t *txData, uint8_t *rxData, uint16_t len) {
    CS_LOW();
    HAL_SPI_TransmitReceive(&hspi1, txData, rxData, len, 1000);
    CS_HIGH();
}

/* Write register (e.g. for sensors like MPU6050 via SPI) */
void SPI_WriteReg(uint8_t reg, uint8_t val) {
    uint8_t buf[2] = {reg & 0x7F, val}; // MSB=0 for write
    CS_LOW();
    HAL_SPI_Transmit(&hspi1, buf, 2, 100);
    CS_HIGH();
}

/* Read register */
uint8_t SPI_ReadReg(uint8_t reg) {
    uint8_t tx = reg | 0x80; // MSB=1 for read
    uint8_t rx = 0;
    CS_LOW();
    HAL_SPI_Transmit(&hspi1, &tx, 1, 100);
    HAL_SPI_Receive(&hspi1, &rx, 1, 100);
    CS_HIGH();
    return rx;
}

/* DMA-based SPI (non-blocking) */
void SPI_WriteDMA(uint8_t *data, uint16_t len) {
    CS_LOW();
    HAL_SPI_Transmit_DMA(&hspi1, data, len);
    // CS_HIGH() called in HAL_SPI_TxCpltCallback
}
/* STM32 I2C Master โ€ข HAL Library */
/* CubeMX: I2C1, 400kHz Fast Mode */

extern I2C_HandleTypeDef hi2c1;
#define SENSOR_ADDR  (0x68 << 1)  // 7-bit addr shifted left

/* Write register */
HAL_StatusTypeDef I2C_WriteReg(uint8_t reg, uint8_t val) {
    uint8_t buf[2] = {reg, val};
    return HAL_I2C_Master_Transmit(&hi2c1, SENSOR_ADDR, buf, 2, 100);
}

/* Read register */
uint8_t I2C_ReadReg(uint8_t reg) {
    uint8_t val;
    HAL_I2C_Master_Transmit(&hi2c1, SENSOR_ADDR, &reg, 1, 100);
    HAL_I2C_Master_Receive(&hi2c1, SENSOR_ADDR, &val, 1, 100);
    return val;
}

/* Read multiple bytes (burst read) */
void I2C_ReadBurst(uint8_t reg, uint8_t *buf, uint16_t len) {
    HAL_I2C_Mem_Read(&hi2c1, SENSOR_ADDR, reg,
                     I2C_MEMADD_SIZE_8BIT, buf, len, 200);
}

/* Example: Read MPU6050 accelerometer */
void MPU6050_Read(int16_t *ax, int16_t *ay, int16_t *az) {
    uint8_t raw[6];
    I2C_ReadBurst(0x3B, raw, 6);
    *ax = (raw[0] << 8) | raw[1];
    *ay = (raw[2] << 8) | raw[3];
    *az = (raw[4] << 8) | raw[5];
}

/* Scan I2C bus for devices */
void I2C_Scan() {
    for (uint8_t addr = 1; addr < 128; addr++) {
        if (HAL_I2C_IsDeviceReady(&hi2c1, addr << 1, 1, 10) == HAL_OK)
            printf("Found: 0x%02X\r\n", addr);
    }
}
/* STM32 ADC โ€ข 12-bit, Single Channel + DMA Multi-channel */
/* CubeMX: ADC1, Continuous mode, DMA enabled */

extern ADC_HandleTypeDef hadc1;
uint32_t adcVal;
uint32_t adcBuf[4]; // For 4-channel DMA

/* Single channel polling */
uint32_t ADC_Read() {
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    uint32_t val = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    return val;
}

/* Convert to voltage (3.3V reference, 12-bit) */
float ADC_ToVoltage(uint32_t raw) {
    return (raw * 3.3f) / 4095.0f;
}

/* Multi-channel DMA (start once, runs continuously) */
void ADC_StartDMA() {
    HAL_ADC_Start_DMA(&hadc1, adcBuf, 4);
}

/* DMA complete callback */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
    // adcBuf[0..3] now have fresh values
    float ch0 = ADC_ToVoltage(adcBuf[0]);
    float ch1 = ADC_ToVoltage(adcBuf[1]);
    printf("CH0=%.2fV CH1=%.2fV\r\n", ch0, ch1);
}

/* Internal temperature sensor (STM32F4) */
float ADC_ReadTemp() {
    uint32_t raw = ADC_Read();
    return (((float)raw * 3300 / 4095) - 760) / 2.5f + 25.0f;
}
/* STM32 Timer โ€ข PWM Output + Input Capture */
/* CubeMX: TIM2, PWM Generation CH1, 1kHz, 72MHz clock */

extern TIM_HandleTypeDef htim2;

/* Start PWM on TIM2 CH1 */
void PWM_Start() {
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}

/* Set duty cycle 0-100% */
void PWM_SetDuty(uint8_t duty) {
    uint32_t arr = htim2.Init.Period;
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (arr * duty) / 100);
}

/* Servo control (50Hz, 1-2ms pulse) */
/* CubeMX: TIM3, Period=19999, Prescaler=71 (1MHz tick) */
void Servo_SetAngle(uint8_t angle) { // 0-180 degrees
    uint32_t pulse = 1000 + (angle * 1000 / 180); // 1000-2000us
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pulse);
}

/* Timer interrupt (1ms tick) */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM6) {
        // 1ms periodic task here
    }
}

/* Input Capture โ€ข measure pulse width */
uint32_t ic_val1, ic_val2, pulse_width;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
        ic_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
        ic_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
        pulse_width = ic_val2 - ic_val1; // in timer ticks
    }
}
/* STM32 BLDC Motor Control โ€ข 6-step commutation via Hall sensors */
/* Uses TIM1 (Advanced Timer) for 3-phase PWM + Hall sensor input */

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim3; // Hall sensor timer

uint8_t hallState;
uint8_t motorSpeed = 50; // 0-100%

/* 6-step commutation table [hallState] = {AH,AL,BH,BL,CH,CL} */
/* 1=ON, 0=OFF for each phase high/low side */
const uint8_t commTable[8][6] = {
    {0,0,0,0,0,0}, // 0 - invalid
    {1,0,0,1,0,0}, // 1: A+B-
    {0,0,1,0,0,1}, // 2: B+C-
    {1,0,0,0,0,1}, // 3: A+C-
    {0,1,0,0,1,0}, // 4: C+A-
    {0,1,1,0,0,0}, // 5: B+A-
    {0,0,0,1,1,0}, // 6: C+B-
    {0,0,0,0,0,0}, // 7 - invalid
};

void BLDC_Commutate(uint8_t state) {
    uint32_t duty = (htim1.Init.Period * motorSpeed) / 100;
    // Set PWM/GPIO based on commutation table
    // AH=TIM1_CH1, AL=GPIO, BH=TIM1_CH2, BL=GPIO, CH=TIM1_CH3, CL=GPIO
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, commTable[state][0] โ€ข duty : 0);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, commTable[state][2] โ€ข duty : 0);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, commTable[state][4] โ€ข duty : 0);
}

/* Hall sensor interrupt callback */
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM3) {
        hallState = (HAL_GPIO_ReadPin(HALL_A_GPIO, HALL_A_PIN) << 2) |
                    (HAL_GPIO_ReadPin(HALL_B_GPIO, HALL_B_PIN) << 1) |
                     HAL_GPIO_ReadPin(HALL_C_GPIO, HALL_C_PIN);
        BLDC_Commutate(hallState);
    }
}
/* STM32 GSM Modem (SIM800L/SIM900) via UART */
/* Connect: SIM800L TX->STM32 RX, SIM800L RX->STM32 TX */

extern UART_HandleTypeDef huart2;
char gsmBuf[256];

void GSM_SendAT(char *cmd) {
    HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), 1000);
    HAL_Delay(500);
}

void GSM_Init() {
    GSM_SendAT("AT\r\n");           // Test
    GSM_SendAT("ATE0\r\n");         // Echo off
    GSM_SendAT("AT+CMGF=1\r\n");    // SMS text mode
    GSM_SendAT("AT+CNMI=1,2,0,0,0\r\n"); // SMS notify
}

void GSM_SendSMS(char *number, char *msg) {
    char cmd[64];
    sprintf(cmd, "AT+CMGS=\"%s\"\r\n", number);
    GSM_SendAT(cmd);
    HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 1000);
    uint8_t ctrlZ = 0x1A;
    HAL_UART_Transmit(&huart2, &ctrlZ, 1, 1000);
    HAL_Delay(3000);
}

void GSM_MakeCall(char *number) {
    char cmd[32];
    sprintf(cmd, "ATD%s;\r\n", number);
    GSM_SendAT(cmd);
}

/* HTTP GET (GPRS) */
void GSM_HTTP_GET(char *url) {
    GSM_SendAT("AT+SAPBR=3,1,\"Contype\",\"GPRS\"\r\n");
    GSM_SendAT("AT+SAPBR=3,1,\"APN\",\"airtelgprs.com\"\r\n");
    GSM_SendAT("AT+SAPBR=1,1\r\n");
    GSM_SendAT("AT+HTTPINIT\r\n");
    char cmd[128];
    sprintf(cmd, "AT+HTTPPARA=\"URL\",\"%s\"\r\n", url);
    GSM_SendAT(cmd);
    GSM_SendAT("AT+HTTPACTION=0\r\n");
    HAL_Delay(5000);
    GSM_SendAT("AT+HTTPREAD\r\n");
    GSM_SendAT("AT+HTTPTERM\r\n");
}

๐Ÿ’ป Microchip PIC & AVR

8-bit and 32-bit Microcontrollers โ€ข PIC16F, PIC18F, ATmega328P. Use MPLAB X IDE or Microchip Studio.

XC8 / XC32 CompilerAVR-GCCMCC MelodyRegisters
/* PIC16F877A UART Setup & Send */
#define _XTAL_FREQ 20000000
#include <xc.h>

void UART_Init(const long baudrate) {
    TXSTAbits.BRGH = 1;             // High speed baud rate
    SPBRG = (_XTAL_FREQ / (16 * baudrate)) - 1;
    TXSTAbits.TXEN = 1;             // Enable transmitter
    RCSTAbits.SPEN = 1;             // Enable serial port
}

void UART_Write(char data) {
    while(!TXSTAbits.TRMT);         // Wait for empty buffer
    TXREG = data;
}

void UART_Write_String(char *text) {
    for(int i = 0; text[i] != '\0'; i++) {
        UART_Write(text[i]);
    }
}
/* ATmega328P GPIO register manipulation (C) */
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void) {
    DDRB |= (1 << DDB5);            // Set PB5 (Digital pin 13) as Output
    while (1) {
        PORTB |= (1 << PORTB5);     // Set PB5 high
        _delay_ms(500);
        PORTB &= ~(1 << PORTB5);    // Set PB5 low
        _delay_ms(500);
    }
    return 0;
}

๐Ÿ’ป Nuvoton

High-reliability, low-cost Industrial MCUs โ€ข N76E003, MS51, M031 series. Perfect for consumer electronics.

8051 CoreCortex-M0Keil C51Low Cost
/* N76E003 (8-bit 8051) UART Initialization */
#include "N76E003.h"
#include "SFR_Macro.h"

void InitialUART0_Timer3(uint32_t u32Baudrate) {
    P06_Quasi_Mode;                 // TX pin configuration
    P07_Quasi_Mode;                 // RX pin configuration
    
    set_SMOD;                       // Double Baud Rate
    T3CON &= 0xF8;                  // Timer 3 clock source
    T3CON |= 0x07;                  // Pre-scale = 1/128
    
    RH3 = HIBYTE(65536 - (16000000/16/(T3CON&0x07))/u32Baudrate);
    RL3 = LOBYTE(65536 - (16000000/16/(T3CON&0x07))/u32Baudrate);
    set_TR3;                        // Start Timer 3
    set_REN;                        // Enable RX
}

๐Ÿ’ป Arduino

Open-source hardware ecosystem โ€ข Uno, Nano, Mega, ESP8266, ESP32. Simple, fast prototyping.

C++ WiringLibrariesESP32 BLEIDE 2.0
/* Arduino Serial Communication */
void setup() {
    Serial.begin(115200);
    Serial.println(F("Arduino Hardware Serial Initialized"));
}

void loop() {
    if (Serial.available() > 0) {
        String rxStr = Serial.readStringUntil('\n');
        Serial.print(F("Received: "));
        Serial.println(rxStr);
    }
}
/* I2C Address Scanner for Arduino */
#include <Wire.h>

void setup() {
    Wire.begin();
    Serial.begin(115200);
    Serial.println(F("\nI2C Scanner"));
}

void loop() {
    byte error, address;
    int nDevices = 0;
    for(address = 1; address < 127; address++) {
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
        if (error == 0) {
            Serial.print(F("I2C device found at address 0x"));
            if (address < 16) Serial.print("0");
            Serial.println(address, HEX);
            nDevices++;
        }
    }
    if (nDevices == 0) Serial.println(F("No I2C devices found\n"));
    delay(5000);
}
/* Read Analog Sensor & Calculate Average */
const int analogPin = A0;

void setup() {
    Serial.begin(9600);
}

void loop() {
    long sum = 0;
    for(int i = 0; i < 10; i++) {
        sum += analogRead(analogPin);
        delay(10);
    }
    float avg = sum / 10.0;
    float voltage = (avg * 5.0) / 1023.0;
    Serial.print(F("Average ADC: "));
    Serial.print(avg);
    Serial.print(F(" | Voltage: "));
    Serial.println(voltage);
    delay(1000);
}

๐Ÿ’ป Raspberry Pi

Single board Linux computers โ€ข RPi 4, RPi 5, Zero 2 W. Perfect for rich Python scripting & web servers.

PythonRPi.GPIOFlaskSPI/I2C
# Raspberry Pi Python GPIO Toggle
import RPi.GPIO as GPIO
import time

LED_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)

try:
    while True:
        GPIO.output(LED_PIN, GPIO.HIGH)
        time.sleep(0.5)
        GPIO.output(LED_PIN, GPIO.LOW)
        time.sleep(0.5)
except KeyboardInterrupt:
    GPIO.cleanup()
# Python Flask API to control GPIO remotely
from flask import Flask, jsonify
import RPi.GPIO as GPIO

app = Flask(__name__)
RELAY_PIN = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(RELAY_PIN, GPIO.OUT)

@app.route('/relay/<state>', methods=['GET'])
def control_relay(state):
    if state == 'on':
        GPIO.output(RELAY_PIN, GPIO.HIGH)
        status = 'Relay is ON'
    else:
        GPIO.output(RELAY_PIN, GPIO.LOW)
        status = 'Relay is OFF'
    return jsonify({'status': status, 'pin': RELAY_PIN})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

๐Ÿ’ป Jetson Nano

NVIDIA AI Embedded Systems โ€ข OpenCV image processing, YOLO neural networks. Powered by CUDA.

NVIDIA CUDAPyTorchTensorRTOpenCV Camera
# OpenCV CSI camera pipeline for Jetson Nano
import cv2

def gstreamer_pipeline(sensor_id=0, capture_width=1280, capture_height=720, display_width=960, display_height=540, framerate=30, flip_method=0):
    return (
        "nvarguscamerasrc sensor-id=%d ! "
        "video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, framerate=(fraction)%d/1 ! "
        "nvvidconv flip-method=%d ! "
        "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
        "videoconvert ! "
        "video/x-raw, format=(string)BGR ! appsink"
        % (sensor_id, capture_width, capture_height, framerate, flip_method, display_width, display_height)
    )

cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)
while cap.isOpened():
    ret, frame = cap.read()
    if not ret: break
    cv2.imshow("Jetson CSI Camera", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release()
cv2.destroyAllWindows()
# Ultralytics YOLO Real-time Object Detection
from ultralytics import YOLO
import cv2

model = YOLO('yolov8n.pt')        // Load small model
cap = cv2.VideoCapture(0)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret: break
    results = model(frame, device='0') // GPU Device 0 (CUDA)
    annotated_frame = results[0].plot()
    cv2.imshow("YOLO Object Detection (GPU)", annotated_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'): break
cap.release()
cv2.destroyAllWindows()

๐Ÿ’ป Analog Devices

High-fidelity data converters & sensors โ€ข AD7124, AD5689. Precise ADC/DAC SPI configurations.

24-bit Sigma-Delta16-bit DACSPI ProtocolUltra Precision
/* AD7124 24-bit Sigma-Delta ADC SPI Read Example */
#include <SPI.h>
const int chipSelectPin = 10;

uint32_t AD7124_ReadRegister(uint8_t regAddr, uint8_t bytesCount) {
    uint32_t regData = 0;
    digitalWrite(chipSelectPin, LOW);
    SPI.transfer(0x40 | regAddr);   // Communications register write command
    for(int i = 0; i < bytesCount; i++) {
        regData = (regData << 8) | SPI.transfer(0x00);
    }
    digitalWrite(chipSelectPin, HIGH);
    return regData;
}