๐ป 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.
/* 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, ®, 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.
/* 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.
/* 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.
/* 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.
# 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.
# 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.
/* 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; }