第一部分:嵌入式C语言基础与核心概念
第1章 嵌入式系统概述
1.1 嵌入式系统特点
嵌入式系统是以应用为中心,以计算机技术为基础,软硬件可裁剪,适用于对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
主要特征:
-
专用性强
-
实时性要求高
-
资源受限
-
可靠性要求高
-
功耗敏感
-
成本敏感
1.2 嵌入式C语言与标准C的区别
c
/* 嵌入式C语言特性示例 */
#include <stdint.h> // 标准整数类型
#include <stdbool.h> // 布尔类型
#include <stddef.h> // 标准定义
// 1. 使用精确宽度整数类型
typedef struct {
uint8_t hour; // 0-23
uint8_t minute; // 0-59
uint8_t second; // 0-59
uint32_t ticks; // 系统滴答计数
} system_time_t;
// 2. volatile关键字的使用
volatile uint32_t * const TIMER_REG = (volatile uint32_t *)0x40000000;
// 3. 寄存器位操作宏
#define BIT(n) (1U << (n))
#define SET_BIT(reg, bit) ((reg) |= BIT(bit))
#define CLR_BIT(reg, bit) ((reg) &= ~BIT(bit))
#define TOGGLE_BIT(reg, bit) ((reg) ^= BIT(bit))
#define GET_BIT(reg, bit) (((reg) >> (bit)) & 1U)
1.3 嵌入式开发环境搭建
c
/* 开发环境配置示例 */
// 编译器特定扩展
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#define WEAK __attribute__((weak))
#define ALIGN(n) __attribute__((aligned(n)))
#elif defined(__ICCARM__)
#define PACKED __packed
#define WEAK __weak
#define ALIGN(n) _Pragma(pack(n))
#else
#define PACKED
#define WEAK
#define ALIGN(n)
#endif
// 内存屏障
#define MEMORY_BARRIER() do { \
__asm volatile("" ::: "memory"); \
} while(0)
// 内联汇编宏
#define ENABLE_INTERRUPTS() __asm volatile("cpsie i")
#define DISABLE_INTERRUPTS() __asm volatile("cpsid i")
第2章 C语言在嵌入式中的关键特性
2.1 位操作技术
c
/* 位操作完整实现 */
#include <stdint.h>
#include <stdbool.h>
// 位域结构体
typedef struct {
union {
struct {
uint8_t flag1 : 1; // 位0
uint8_t flag2 : 1; // 位1
uint8_t flag3 : 1; // 位2
uint8_t flag4 : 1; // 位3
uint8_t reserved : 4; // 位4-7
} bits;
uint8_t byte;
};
} flag_register_t;
// 位图管理
typedef struct {
uint32_t bitmap[8]; // 256位位图
} bitmap_t;
// 位图操作函数
void bitmap_set(bitmap_t *bitmap, uint8_t pos) {
if (pos < 256) {
bitmap->bitmap[pos / 32] |= (1U << (pos % 32));
}
}
void bitmap_clear(bitmap_t *bitmap, uint8_t pos) {
if (pos < 256) {
bitmap->bitmap[pos / 32] &= ~(1U << (pos % 32));
}
}
bool bitmap_test(const bitmap_t *bitmap, uint8_t pos) {
if (pos < 256) {
return (bitmap->bitmap[pos / 32] & (1U << (pos % 32))) != 0;
}
return false;
}
// 位查找算法
int8_t find_first_set_bit(uint32_t value) {
static const int8_t table[32] = {
0, 1, 28, 2, 29, 14, 24, 3,
30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7,
26, 12, 18, 6, 11, 5, 10, 9
};
if (value == 0) return -1;
// 使用De Bruijn序列算法
return table[((uint32_t)((value & -value) * 0x077CB531U)) >> 27];
}
// 位反转函数
uint32_t reverse_bits(uint32_t x) {
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8);
x = (x >> 16) | (x << 16);
return x;
}
2.2 内存管理
c
/* 嵌入式内存管理实现 */
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// 内存池块结构
typedef struct mem_block {
struct mem_block *next; // 下一个空闲块
size_t size; // 块大小(包括头部)
} mem_block_t;
// 内存池结构
typedef struct {
void *start; // 内存池起始地址
void *end; // 内存池结束地址
size_t block_size; // 每个块的大小
uint16_t total_blocks; // 总块数
uint16_t free_blocks; // 空闲块数
mem_block_t *free_list;// 空闲链表
} mem_pool_t;
// 对齐宏
#define ALIGN_UP(addr, align) (((addr) + (align) - 1) & ~((align) - 1))
#define ALIGN_DOWN(addr, align) ((addr) & ~((align) - 1))
// 内存池初始化
bool mem_pool_init(mem_pool_t *pool, void *mem_start,
size_t mem_size, size_t block_size) {
if (pool == NULL || mem_start == NULL ||
block_size < sizeof(mem_block_t) || mem_size < block_size) {
return false;
}
// 对齐处理
block_size = ALIGN_UP(block_size, sizeof(void *));
mem_start = (void *)ALIGN_UP((uintptr_t)mem_start, sizeof(void *));
pool->start = mem_start;
pool->block_size = block_size;
pool->total_blocks = mem_size / block_size;
pool->free_blocks = pool->total_blocks;
// 初始化空闲链表
pool->free_list = NULL;
void *current = mem_start;
for (uint16_t i = 0; i < pool->total_blocks; i++) {
mem_block_t *block = (mem_block_t *)current;
block->next = pool->free_list;
pool->free_list = block;
current = (void *)((uint8_t *)current + block_size);
}
pool->end = current;
return true;
}
// 从内存池分配
void *mem_pool_alloc(mem_pool_t *pool) {
if (pool == NULL || pool->free_list == NULL) {
return NULL;
}
mem_block_t *block = pool->free_list;
pool->free_list = block->next;
pool->free_blocks--;
// 清除分配的内存
memset(block, 0, pool->block_size - sizeof(mem_block_t));
return (void *)((uint8_t *)block + sizeof(mem_block_t));
}
// 释放到内存池
void mem_pool_free(mem_pool_t *pool, void *ptr) {
if (pool == NULL || ptr == NULL) {
return;
}
// 计算块起始地址
mem_block_t *block = (mem_block_t *)((uint8_t *)ptr - sizeof(mem_block_t));
// 检查指针有效性
if (block < pool->start || block >= pool->end) {
return;
}
// 添加到空闲链表
block->next = pool->free_list;
pool->free_list = block;
pool->free_blocks++;
}
// 内存池统计信息
void mem_pool_stats(const mem_pool_t *pool,
uint16_t *total, uint16_t *free,
uint16_t *used, uint8_t *usage_percent) {
if (pool) {
if (total) *total = pool->total_blocks;
if (free) *free = pool->free_blocks;
if (used) *used = pool->total_blocks - pool->free_blocks;
if (usage_percent) {
*usage_percent = (uint8_t)((pool->total_blocks - pool->free_blocks) *
100 / pool->total_blocks);
}
}
}
// 固定大小内存分配器
typedef struct {
uint8_t *memory; // 内存区域
size_t block_size; // 块大小
size_t total_blocks; // 总块数
uint8_t *bitmap; // 位图
uint16_t free_count; // 空闲块计数
} fixed_allocator_t;
// 固定大小分配器初始化
bool fixed_allocator_init(fixed_allocator_t *alloc,
void *memory, size_t memory_size,
size_t block_size) {
if (alloc == NULL || memory == NULL ||
block_size == 0 || memory_size < block_size) {
return false;
}
// 对齐处理
block_size = ALIGN_UP(block_size, sizeof(void *));
memory = (void *)ALIGN_UP((uintptr_t)memory, sizeof(void *));
// 计算块数
size_t total_blocks = memory_size / block_size;
size_t bitmap_size = (total_blocks + 7) / 8;
// 检查内存是否足够容纳位图
if (memory_size < (block_size * total_blocks + bitmap_size)) {
return false;
}
alloc->memory = (uint8_t *)memory;
alloc->block_size = block_size;
alloc->total_blocks = total_blocks;
alloc->bitmap = alloc->memory + block_size * total_blocks;
alloc->free_count = total_blocks;
// 初始化位图为全0(全部空闲)
memset(alloc->bitmap, 0, bitmap_size);
return true;
}
// 分配内存
void *fixed_allocator_alloc(fixed_allocator_t *alloc) {
if (alloc == NULL || alloc->free_count == 0) {
return NULL;
}
size_t bitmap_bytes = (alloc->total_blocks + 7) / 8;
// 查找第一个空闲块
for (size_t i = 0; i < bitmap_bytes; i++) {
if (alloc->bitmap[i] != 0xFF) { // 有空闲位
for (int j = 0; j < 8; j++) {
size_t bit_pos = i * 8 + j;
if (bit_pos < alloc->total_blocks &&
!(alloc->bitmap[i] & (1 << j))) {
// 标记为已分配
alloc->bitmap[i] |= (1 << j);
alloc->free_count--;
// 返回块地址
return alloc->memory + bit_pos * alloc->block_size;
}
}
}
}
return NULL;
}
// 释放内存
void fixed_allocator_free(fixed_allocator_t *alloc, void *ptr) {
if (alloc == NULL || ptr == NULL) {
return;
}
// 计算块索引
ptrdiff_t offset = (uint8_t *)ptr - alloc->memory;
if (offset < 0 || offset % alloc->block_size != 0) {
return; // 无效指针
}
size_t block_index = offset / alloc->block_size;
if (block_index >= alloc->total_blocks) {
return; // 索引越界
}
// 计算位图位置
size_t byte_index = block_index / 8;
uint8_t bit_mask = 1 << (block_index % 8);
// 检查是否已分配
if (alloc->bitmap[byte_index] & bit_mask) {
// 标记为空闲
alloc->bitmap[byte_index] &= ~bit_mask;
alloc->free_count++;
// 清空内存
memset(ptr, 0, alloc->block_size);
}
}
2.3 中断服务程序
c
/* 中断管理完整实现 */
#include <stdint.h>
#include <stdbool.h>
// 中断向量表类型
typedef void (*isr_func_t)(void);
// 中断向量表
typedef struct {
isr_func_t reset_handler;
isr_func_t nmi_handler;
isr_func_t hardfault_handler;
isr_func_t memmanage_handler;
isr_func_t busfault_handler;
isr_func_t usagefault_handler;
isr_func_t svcall_handler;
isr_func_t debugmon_handler;
isr_func_t pendsv_handler;
isr_func_t systick_handler;
// 外设中断
isr_func_t exti0_handler;
isr_func_t exti1_handler;
isr_func_t exti2_handler;
isr_func_t exti3_handler;
isr_func_t exti4_handler;
// ... 更多中断向量
} vector_table_t;
// 中断优先级
typedef enum {
IRQ_PRIORITY_0 = 0,
IRQ_PRIORITY_1 = 1,
IRQ_PRIORITY_2 = 2,
IRQ_PRIORITY_3 = 3,
IRQ_PRIORITY_4 = 4,
IRQ_PRIORITY_5 = 5,
IRQ_PRIORITY_6 = 6,
IRQ_PRIORITY_7 = 7,
IRQ_PRIORITY_HIGHEST = 0,
IRQ_PRIORITY_LOWEST = 7
} irq_priority_t;
// 中断控制器结构
typedef struct {
volatile uint32_t ISER[8]; // 中断使能寄存器
volatile uint32_t ICER[8]; // 中断清除寄存器
volatile uint32_t ISPR[8]; // 中断挂起设置寄存器
volatile uint32_t ICPR[8]; // 中断挂起清除寄存器
volatile uint32_t IABR[8]; // 中断活动位寄存器
volatile uint32_t IPR[240]; // 中断优先级寄存器
} NVIC_Type;
// NVIC基地址
#define NVIC_BASE 0xE000E100UL
#define NVIC ((NVIC_Type *)NVIC_BASE)
// 中断管理器
typedef struct {
uint32_t irq_count;
uint32_t max_irq;
isr_func_t *vector_table;
void **context_table;
} interrupt_manager_t;
// 中断上下文
typedef struct {
uint32_t r0, r1, r2, r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t psr;
} interrupt_context_t;
// 中断初始化
bool interrupt_manager_init(interrupt_manager_t *manager,
uint32_t max_interrupts) {
if (manager == NULL || max_interrupts == 0) {
return false;
}
// 分配向量表内存
manager->vector_table = (isr_func_t *)calloc(max_interrupts,
sizeof(isr_func_t));
manager->context_table = (void **)calloc(max_interrupts,
sizeof(void *));
if (manager->vector_table == NULL || manager->context_table == NULL) {
free(manager->vector_table);
free(manager->context_table);
return false;
}
manager->max_irq = max_interrupts;
manager->irq_count = 0;
return true;
}
// 注册中断处理函数
bool register_interrupt_handler(interrupt_manager_t *manager,
uint32_t irq_number,
isr_func_t handler,
void *context,
irq_priority_t priority) {
if (manager == NULL || irq_number >= manager->max_irq) {
return false;
}
DISABLE_INTERRUPTS();
manager->vector_table[irq_number] = handler;
manager->context_table[irq_number] = context;
// 设置优先级
if (irq_number >= 0) {
uint32_t reg = irq_number / 4;
uint32_t offset = (irq_number % 4) * 8;
NVIC->IPR[reg] = (NVIC->IPR[reg] & ~(0xFF << offset)) |
(priority << (offset + 4));
}
ENABLE_INTERRUPTS();
return true;
}
// 通用中断处理框架
__attribute__((naked)) void generic_isr_handler(void) {
__asm volatile(
"tst lr, #4 \n" // 检查EXC_RETURN的位2
"ite eq \n"
"mrseq r0, msp \n" // 使用MSP
"mrsne r0, psp \n" // 使用PSP
"b process_interrupt \n" // 跳转到C函数
);
}
// 中断处理函数
void process_interrupt(interrupt_context_t *context) {
uint32_t ipsr;
__asm volatile("mrs %0, ipsr" : "=r"(ipsr));
uint32_t irq_number = ipsr & 0x1FF;
if (irq_number < 16) {
// 处理内核异常
handle_core_exception(irq_number, context);
} else {
// 处理外设中断
handle_peripheral_irq(irq_number - 16, context);
}
}
// 嵌套中断处理
typedef struct {
uint32_t nest_count;
uint32_t max_nesting;
uint32_t *stack_usage;
} nested_isr_t;
// 嵌套中断管理器
nested_isr_t g_nested_isr;
void nested_isr_enter(void) {
uint32_t ipsr;
__asm volatile("mrs %0, ipsr" : "=r"(ipsr));
uint32_t irq_number = ipsr & 0x1FF;
if (irq_number >= 16) { // 外设中断
g_nested_isr.nest_count++;
if (g_nested_isr.nest_count > g_nested_isr.max_nesting) {
g_nested_isr.max_nesting = g_nested_isr.nest_count;
}
}
}
void nested_isr_exit(void) {
uint32_t ipsr;
__asm volatile("mrs %0, ipsr" : "=r"(ipsr));
uint32_t irq_number = ipsr & 0x1FF;
if (irq_number >= 16) { // 外设中断
if (g_nested_isr.nest_count > 0) {
g_nested_isr.nest_count--;
}
}
}
// 中断安全的环形缓冲区
typedef struct {
uint8_t *buffer;
size_t size;
volatile size_t head;
volatile size_t tail;
volatile bool overflow;
} irq_safe_buffer_t;
bool irq_buffer_init(irq_safe_buffer_t *buf, size_t size) {
if (buf == NULL || size == 0) {
return false;
}
buf->buffer = (uint8_t *)malloc(size);
if (buf->buffer == NULL) {
return false;
}
buf->size = size;
buf->head = 0;
buf->tail = 0;
buf->overflow = false;
return true;
}
bool irq_buffer_write(irq_safe_buffer_t *buf, const uint8_t *data, size_t len) {
if (buf == NULL || data == NULL || len == 0) {
return false;
}
DISABLE_INTERRUPTS();
size_t free_space;
if (buf->head >= buf->tail) {
free_space = buf->size - (buf->head - buf->tail);
} else {
free_space = buf->tail - buf->head - 1;
}
if (len > free_space) {
buf->overflow = true;
ENABLE_INTERRUPTS();
return false;
}
for (size_t i = 0; i < len; i++) {
buf->buffer[buf->head] = data[i];
buf->head = (buf->head + 1) % buf->size;
}
ENABLE_INTERRUPTS();
return true;
}
bool irq_buffer_read(irq_safe_buffer_t *buf, uint8_t *data, size_t len) {
if (buf == NULL || data == NULL || len == 0) {
return false;
}
DISABLE_INTERRUPTS();
size_t available;
if (buf->tail <= buf->head) {
available = buf->head - buf->tail;
} else {
available = buf->size - buf->tail + buf->head;
}
if (len > available) {
ENABLE_INTERRUPTS();
return false;
}
for (size_t i = 0; i < len; i++) {
data[i] = buf->buffer[buf->tail];
buf->tail = (buf->tail + 1) % buf->size;
}
ENABLE_INTERRUPTS();
return true;
}
2.4 硬件寄存器访问
c
/* 硬件寄存器访问模式 */
#include <stdint.h>
#include <stdbool.h>
// 内存映射寄存器类型
typedef volatile uint32_t reg32_t;
typedef volatile uint16_t reg16_t;
typedef volatile uint8_t reg8_t;
// 位域定义宏
#define REG32(addr) (*(reg32_t *)(addr))
#define REG16(addr) (*(reg16_t *)(addr))
#define REG8(addr) (*(reg8_t *)(addr))
// 寄存器位操作
#define REG_SET_BIT(reg, bit) ((reg) |= (1U << (bit)))
#define REG_CLR_BIT(reg, bit) ((reg) &= ~(1U << (bit)))
#define REG_TOGGLE_BIT(reg, bit) ((reg) ^= (1U << (bit)))
#define REG_GET_BIT(reg, bit) (((reg) >> (bit)) & 1U)
// 寄存器位域操作
#define REG_SET_FIELD(reg, mask, shift, value) \
((reg) = ((reg) & ~((mask) << (shift))) | (((value) & (mask)) << (shift)))
#define REG_GET_FIELD(reg, mask, shift) \
(((reg) >> (shift)) & (mask))
// GPIO寄存器结构
typedef struct {
reg32_t MODER; // 模式寄存器
reg32_t OTYPER; // 输出类型寄存器
reg32_t OSPEEDR; // 输出速度寄存器
reg32_t PUPDR; // 上拉/下拉寄存器
reg32_t IDR; // 输入数据寄存器
reg32_t ODR; // 输出数据寄存器
reg32_t BSRR; // 置位/复位寄存器
reg32_t LCKR; // 锁定寄存器
reg32_t AFR[2]; // 复用功能寄存器
} GPIO_TypeDef;
// GPIO基地址
#define GPIOA_BASE 0x40020000UL
#define GPIOB_BASE 0x40020400UL
#define GPIOC_BASE 0x40020800UL
#define GPIOD_BASE 0x40020C00UL
// GPIO实例
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE)
// GPIO配置枚举
typedef enum {
GPIO_MODE_INPUT = 0,
GPIO_MODE_OUTPUT = 1,
GPIO_MODE_ALT = 2,
GPIO_MODE_ANALOG = 3
} gpio_mode_t;
typedef enum {
GPIO_OTYPE_PP = 0, // 推挽输出
GPIO_OTYPE_OD = 1 // 开漏输出
} gpio_otype_t;
typedef enum {
GPIO_SPEED_LOW = 0,
GPIO_SPEED_MEDIUM = 1,
GPIO_SPEED_HIGH = 2,
GPIO_SPEED_VERY_HIGH = 3
} gpio_speed_t;
typedef enum {
GPIO_PUPD_NONE = 0,
GPIO_PUPD_PU = 1, // 上拉
GPIO_PUPD_PD = 2 // 下拉
} gpio_pupd_t;
// GPIO配置函数
void gpio_configure(GPIO_TypeDef *gpio, uint8_t pin,
gpio_mode_t mode, gpio_otype_t otype,
gpio_speed_t speed, gpio_pupd_t pupd) {
if (gpio == NULL || pin > 15) return;
// 配置模式
REG_SET_FIELD(gpio->MODER, 0x3, pin * 2, mode);
// 配置输出类型
if (mode == GPIO_MODE_OUTPUT) {
if (otype == GPIO_OTYPE_OD) {
gpio->OTYPER |= (1U << pin);
} else {
gpio->OTYPER &= ~(1U << pin);
}
}
// 配置速度
REG_SET_FIELD(gpio->OSPEEDR, 0x3, pin * 2, speed);
// 配置上拉/下拉
REG_SET_FIELD(gpio->PUPDR, 0x3, pin * 2, pupd);
}
// 原子操作GPIO
void gpio_set_atomic(GPIO_TypeDef *gpio, uint8_t pin, bool state) {
if (gpio == NULL || pin > 15) return;
if (state) {
gpio->BSRR = (1U << pin); // 置位
} else {
gpio->BSRR = (1U << (pin + 16)); // 复位
}
}
// 批量操作GPIO
void gpio_write_bulk(GPIO_TypeDef *gpio, uint16_t mask, uint16_t value) {
if (gpio == NULL) return;
// 使用ODR寄存器原子写入
uint32_t odr = gpio->ODR;
odr = (odr & ~mask) | (value & mask);
gpio->ODR = odr;
}
// 硬件寄存器抽象层
typedef struct {
uintptr_t base_address;
size_t register_count;
const char *name;
} hardware_device_t;
// 设备管理器
typedef struct {
hardware_device_t *devices;
size_t device_count;
size_t max_devices;
} device_manager_t;
// 设备注册
bool register_device(device_manager_t *manager,
const char *name,
uintptr_t base_address,
size_t register_size) {
if (manager == NULL || name == NULL ||
manager->device_count >= manager->max_devices) {
return false;
}
hardware_device_t *dev = &manager->devices[manager->device_count];
dev->name = name;
dev->base_address = base_address;
dev->register_count = register_size;
manager->device_count++;
return true;
}
// 寄存器访问跟踪
typedef struct {
uintptr_t address;
uint32_t value;
uint32_t timestamp;
uint8_t operation; // 0=读,1=写
} register_access_t;
typedef struct {
register_access_t *log;
size_t log_size;
size_t log_index;
volatile bool enabled;
} register_logger_t;
// 带跟踪的寄存器访问
uint32_t reg_read_traced(register_logger_t *logger, uintptr_t addr) {
uint32_t value = REG32(addr);
if (logger && logger->enabled) {
DISABLE_INTERRUPTS();
logger->log[logger->log_index].address = addr;
logger->log[logger->log_index].value = value;
logger->log[logger->log_index].timestamp = get_system_ticks();
logger->log[logger->log_index].operation = 0;
logger->log_index = (logger->log_index + 1) % logger->log_size;
ENABLE_INTERRUPTS();
}
return value;
}
void reg_write_traced(register_logger_t *logger, uintptr_t addr, uint32_t value) {
if (logger && logger->enabled) {
DISABLE_INTERRUPTS();
logger->log[logger->log_index].address = addr;
logger->log[logger->log_index].value = value;
logger->log[logger->log_index].timestamp = get_system_ticks();
logger->log[logger->log_index].operation = 1;
logger->log_index = (logger->log_index + 1) % logger->log_size;
ENABLE_INTERRUPTS();
}
REG32(addr) = value;
}
第二部分:嵌入式系统组件开发
第3章 任务调度器实现
3.1 协作式调度器
c
/* 协作式任务调度器完整实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
// 任务状态
typedef enum {
TASK_READY = 0,
TASK_RUNNING = 1,
TASK_WAITING = 2,
TASK_SUSPENDED = 3,
TASK_TERMINATED = 4
} task_state_t;
// 任务控制块
typedef struct task_control_block {
uint32_t id; // 任务ID
char name[16]; // 任务名称
void (*entry)(void *); // 任务入口函数
void *arg; // 任务参数
uint32_t *stack_ptr; // 当前栈指针
uint32_t *stack_base; // 栈基地址
uint32_t stack_size; // 栈大小
task_state_t state; // 任务状态
uint32_t wakeup_time; // 唤醒时间
uint32_t run_time; // 运行时间计数
uint32_t total_run_time; // 总运行时间
struct task_control_block *next; // 下一个任务
uint32_t priority; // 任务优先级
uint32_t wait_event; // 等待的事件
} tcb_t;
// 调度器结构
typedef struct {
tcb_t *task_list; // 任务链表
tcb_t *current_task; // 当前运行任务
tcb_t *idle_task; // 空闲任务
uint32_t task_count; // 任务数量
uint32_t ticks; // 系统滴答计数
bool scheduler_running; // 调度器运行标志
uint32_t max_tasks; // 最大任务数
} co_scheduler_t;
// 调度器初始化
bool co_scheduler_init(co_scheduler_t *sched, uint32_t max_tasks) {
if (sched == NULL || max_tasks == 0) {
return false;
}
memset(sched, 0, sizeof(co_scheduler_t));
sched->max_tasks = max_tasks;
sched->ticks = 0;
sched->scheduler_running = false;
// 创建空闲任务
sched->idle_task = co_task_create(sched, idle_task_func, NULL,
"Idle", 128, 0);
if (sched->idle_task == NULL) {
return false;
}
sched->current_task = sched->idle_task;
return true;
}
// 任务创建
tcb_t *co_task_create(co_scheduler_t *sched,
void (*entry)(void *),
void *arg,
const char *name,
uint32_t stack_size,
uint32_t priority) {
if (sched == NULL || entry == NULL || name == NULL ||
stack_size == 0 || sched->task_count >= sched->max_tasks) {
return NULL;
}
// 分配TCB
tcb_t *task = (tcb_t *)malloc(sizeof(tcb_t));
if (task == NULL) {
return NULL;
}
// 分配任务栈
uint32_t *stack = (uint32_t *)malloc(stack_size);
if (stack == NULL) {
free(task);
return NULL;
}
// 初始化TCB
memset(task, 0, sizeof(tcb_t));
task->id = sched->task_count + 1;
strncpy(task->name, name, sizeof(task->name) - 1);
task->entry = entry;
task->arg = arg;
task->stack_base = stack;
task->stack_size = stack_size;
task->state = TASK_READY;
task->priority = priority;
// 初始化任务栈
uint32_t *stack_top = stack + (stack_size / sizeof(uint32_t));
// 模拟异常返回帧
*(--stack_top) = 0x01000000; // xPSR
*(--stack_top) = (uint32_t)entry; // PC
*(--stack_top) = 0xFFFFFFFD; // LR (EXC_RETURN)
*(--stack_top) = 0; // R12
*(--stack_top) = 0; // R3
*(--stack_top) = 0; // R2
*(--stack_top) = 0; // R1
*(--stack_top) = (uint32_t)arg; // R0
// 其他寄存器
for (int i = 0; i < 8; i++) {
*(--stack_top) = 0; // R4-R11
}
task->stack_ptr = stack_top;
// 添加到任务链表
task->next = sched->task_list;
sched->task_list = task;
sched->task_count++;
return task;
}
// 任务切换
__attribute__((naked)) void co_task_switch(tcb_t *from, tcb_t *to) {
__asm volatile(
// 保存当前任务上下文
"push {r4-r11, lr} \n"
"str sp, [r0] \n"
// 恢复新任务上下文
"ldr sp, [r1] \n"
"pop {r4-r11, lr} \n"
"bx lr \n"
);
}
// 调度函数
void co_scheduler_run(co_scheduler_t *sched) {
if (sched == NULL || sched->scheduler_running) {
return;
}
sched->scheduler_running = true;
while (sched->scheduler_running) {
// 查找下一个就绪任务
tcb_t *next_task = sched->idle_task;
tcb_t *task = sched->task_list;
// 基于优先级的简单轮询
while (task != NULL) {
if (task->state == TASK_READY &&
task->priority > next_task->priority) {
next_task = task;
}
task = task->next;
}
// 检查是否需要切换任务
if (next_task != sched->current_task &&
next_task->state == TASK_READY) {
tcb_t *prev_task = sched->current_task;
sched->current_task = next_task;
next_task->state = TASK_RUNNING;
// 任务切换
co_task_switch(prev_task, next_task);
// 更新任务状态
if (prev_task->state == TASK_RUNNING) {
prev_task->state = TASK_READY;
}
}
// 处理定时唤醒
co_scheduler_handle_timeouts(sched);
// 系统滴答计数
sched->ticks++;
}
}
// 任务延时
void co_task_delay(co_scheduler_t *sched, uint32_t ticks) {
if (sched == NULL || sched->current_task == NULL) {
return;
}
sched->current_task->state = TASK_WAITING;
sched->current_task->wakeup_time = sched->ticks + ticks;
// 立即调度
co_task_yield(sched);
}
// 任务主动让出CPU
void co_task_yield(co_scheduler_t *sched) {
if (sched == NULL) {
return;
}
// 切换到空闲任务
tcb_t *prev_task = sched->current_task;
sched->current_task = sched->idle_task;
sched->idle_task->state = TASK_RUNNING;
co_task_switch(prev_task, sched->idle_task);
if (prev_task->state == TASK_RUNNING) {
prev_task->state = TASK_READY;
}
}
// 空闲任务
void idle_task_func(void *arg) {
while (1) {
// 低功耗模式
__asm volatile("wfi");
}
}
// 超时处理
void co_scheduler_handle_timeouts(co_scheduler_t *sched) {
if (sched == NULL) {
return;
}
tcb_t *task = sched->task_list;
while (task != NULL) {
if (task->state == TASK_WAITING &&
sched->ticks >= task->wakeup_time) {
task->state = TASK_READY;
}
task = task->next;
}
}
3.2 抢占式调度器
c
/* 抢占式实时调度器实现 */
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
// 就绪队列
typedef struct {
tcb_t **tasks;
uint32_t capacity;
uint32_t size;
} ready_queue_t;
// 优先级队列实现
ready_queue_t *ready_queue_create(uint32_t capacity) {
ready_queue_t *queue = (ready_queue_t *)malloc(sizeof(ready_queue_t));
if (queue == NULL) {
return NULL;
}
queue->tasks = (tcb_t **)calloc(capacity, sizeof(tcb_t *));
if (queue->tasks == NULL) {
free(queue);
return NULL;
}
queue->capacity = capacity;
queue->size = 0;
return queue;
}
void ready_queue_insert(ready_queue_t *queue, tcb_t *task) {
if (queue == NULL || task == NULL || queue->size >= queue->capacity) {
return;
}
// 按优先级插入排序
uint32_t i = queue->size;
while (i > 0 && queue->tasks[i-1]->priority < task->priority) {
queue->tasks[i] = queue->tasks[i-1];
i--;
}
queue->tasks[i] = task;
queue->size++;
}
tcb_t *ready_queue_remove_highest(ready_queue_t *queue) {
if (queue == NULL || queue->size == 0) {
return NULL;
}
tcb_t *task = queue->tasks[0];
// 移动后续任务
for (uint32_t i = 1; i < queue->size; i++) {
queue->tasks[i-1] = queue->tasks[i];
}
queue->size--;
return task;
}
// 抢占式调度器
typedef struct {
ready_queue_t *ready_queue; // 就绪队列
tcb_t *current_task; // 当前运行任务
tcb_t *idle_task; // 空闲任务
uint32_t tick_count; // 系统滴答
uint32_t time_slice; // 时间片长度
uint32_t max_tasks; // 最大任务数
volatile bool scheduler_lock; // 调度锁
uint32_t context_switch_count; // 上下文切换计数
} preemptive_scheduler_t;
// SysTick中断处理
void SysTick_Handler(void) {
// 保存当前任务上下文
// 触发任务调度
}
// PendSV中断处理(上下文切换)
__attribute__((naked)) void PendSV_Handler(void) {
__asm volatile(
"cpsid i \n" // 禁用中断
"mrs r0, psp \n" // 获取PSP
"cbz r0, PendSV_Handler_skip_save \n"
// 保存当前任务上下文
"stmdb r0!, {r4-r11} \n"
"str r0, [%0] \n" // 保存栈指针到current_task->stack_ptr
"PendSV_Handler_skip_save: \n"
// 切换到新任务
"ldr r0, [%1] \n" // 加载新任务TCB地址
"ldr r1, [r0] \n" // 加载新任务栈指针
"mov sp, r1 \n"
"ldmia sp!, {r4-r11} \n"
"msr psp, sp \n"
"cpsie i \n" // 启用中断
"bx lr \n"
:
: "r" (&g_scheduler.current_task->stack_ptr),
"r" (&g_scheduler.current_task)
);
}
// 启动调度器
void scheduler_start(preemptive_scheduler_t *sched) {
if (sched == NULL) {
return;
}
// 配置SysTick定时器
SysTick_Config(SystemCoreClock / 1000); // 1ms定时
// 设置PendSV为最低优先级
NVIC_SetPriority(PendSV_IRQn, 0xFF);
// 启用中断
__enable_irq();
// 触发第一次调度
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
}
// 任务创建
tcb_t *preemptive_task_create(preemptive_scheduler_t *sched,
void (*entry)(void *),
void *arg,
const char *name,
uint32_t stack_size,
uint32_t priority) {
if (sched == NULL || entry == NULL || name == NULL) {
return NULL;
}
// 分配TCB和栈
tcb_t *task = (tcb_t *)malloc(sizeof(tcb_t));
if (task == NULL) {
return NULL;
}
uint32_t *stack = (uint32_t *)malloc(stack_size);
if (stack == NULL) {
free(task);
return NULL;
}
// 初始化TCB
memset(task, 0, sizeof(tcb_t));
task->entry = entry;
task->arg = arg;
strncpy(task->name, name, sizeof(task->name) - 1);
task->stack_base = stack;
task->stack_size = stack_size;
task->priority = priority;
task->state = TASK_READY;
// 初始化任务栈
uint32_t *stack_top = stack + (stack_size / sizeof(uint32_t));
// 初始上下文
*(--stack_top) = 0x01000000; // xPSR
*(--stack_top) = (uint32_t)entry; // PC
*(--stack_top) = (uint32_t)task_exit; // LR
*(--stack_top) = 0; // R12
*(--stack_top) = 0; // R3
*(--stack_top) = 0; // R2
*(--stack_top) = 0; // R1
*(--stack_top) = (uint32_t)arg; // R0
*(--stack_top) = 0; // R11
*(--stack_top) = 0; // R10
*(--stack_top) = 0; // R9
*(--stack_top) = 0; // R8
*(--stack_top) = 0; // R7
*(--stack_top) = 0; // R6
*(--stack_top) = 0; // R5
*(--stack_top) = 0; // R4
task->stack_ptr = stack_top;
// 添加到就绪队列
DISABLE_INTERRUPTS();
ready_queue_insert(sched->ready_queue, task);
ENABLE_INTERRUPTS();
return task;
}
// 任务退出处理
void task_exit(void) {
// 标记任务为终止
g_scheduler.current_task->state = TASK_TERMINATED;
// 切换到空闲任务
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
// 等待调度器清理
while(1);
}
// 调度函数
void scheduler_tick(preemptive_scheduler_t *sched) {
if (sched == NULL || sched->scheduler_lock) {
return;
}
DISABLE_INTERRUPTS();
// 更新当前任务运行时间
if (sched->current_task != NULL) {
sched->current_task->run_time++;
sched->current_task->total_run_time++;
// 检查时间片
if (sched->current_task->run_time >= sched->time_slice) {
sched->current_task->run_time = 0;
// 将当前任务放回就绪队列
if (sched->current_task->state == TASK_RUNNING) {
sched->current_task->state = TASK_READY;
ready_queue_insert(sched->ready_queue, sched->current_task);
}
}
}
// 检查就绪队列
tcb_t *next_task = ready_queue_remove_highest(sched->ready_queue);
if (next_task != NULL) {
if (sched->current_task != next_task) {
// 保存当前任务
if (sched->current_task != NULL &&
sched->current_task->state == TASK_RUNNING) {
sched->current_task->state = TASK_READY;
ready_queue_insert(sched->ready_queue, sched->current_task);
}
// 切换到新任务
sched->current_task = next_task;
sched->current_task->state = TASK_RUNNING;
sched->context_switch_count++;
// 触发上下文切换
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
} else {
// 继续运行当前任务
ready_queue_insert(sched->ready_queue, next_task);
}
}
ENABLE_INTERRUPTS();
}
// 互斥锁实现
typedef struct {
volatile uint32_t lock;
tcb_t *owner;
uint32_t recursion_count;
} mutex_t;
bool mutex_lock(mutex_t *mutex, uint32_t timeout) {
if (mutex == NULL) {
return false;
}
uint32_t start_time = get_system_ticks();
while (1) {
DISABLE_INTERRUPTS();
if (mutex->lock == 0) {
// 获取锁
mutex->lock = 1;
mutex->owner = g_scheduler.current_task;
mutex->recursion_count = 1;
ENABLE_INTERRUPTS();
return true;
} else if (mutex->owner == g_scheduler.current_task) {
// 递归锁
mutex->recursion_count++;
ENABLE_INTERRUPTS();
return true;
}
ENABLE_INTERRUPTS();
// 检查超时
if (timeout != 0 &&
(get_system_ticks() - start_time) >= timeout) {
return false;
}
// 让出CPU
task_yield();
}
}
void mutex_unlock(mutex_t *mutex) {
if (mutex == NULL || mutex->owner != g_scheduler.current_task) {
return;
}
DISABLE_INTERRUPTS();
mutex->recursion_count--;
if (mutex->recursion_count == 0) {
mutex->lock = 0;
mutex->owner = NULL;
}
ENABLE_INTERRUPTS();
}
// 信号量实现
typedef struct {
volatile uint32_t count;
uint32_t max_count;
tcb_t *waiting_list;
} semaphore_t;
bool semaphore_init(semaphore_t *sem, uint32_t initial_count, uint32_t max_count) {
if (sem == NULL) {
return false;
}
sem->count = initial_count;
sem->max_count = max_count;
sem->waiting_list = NULL;
return true;
}
bool semaphore_take(semaphore_t *sem, uint32_t timeout) {
if (sem == NULL) {
return false;
}
DISABLE_INTERRUPTS();
if (sem->count > 0) {
sem->count--;
ENABLE_INTERRUPTS();
return true;
}
// 将任务添加到等待队列
g_scheduler.current_task->state = TASK_WAITING;
g_scheduler.current_task->wait_event = (uint32_t)sem;
g_scheduler.current_task->next = sem->waiting_list;
sem->waiting_list = g_scheduler.current_task;
ENABLE_INTERRUPTS();
// 等待信号量
uint32_t start_time = get_system_ticks();
while (g_scheduler.current_task->state == TASK_WAITING) {
if (timeout != 0 &&
(get_system_ticks() - start_time) >= timeout) {
// 超时,从等待队列移除
DISABLE_INTERRUPTS();
// 从等待队列移除任务
ENABLE_INTERRUPTS();
return false;
}
task_yield();
}
return true;
}
void semaphore_give(semaphore_t *sem) {
if (sem == NULL) {
return;
}
DISABLE_INTERRUPTS();
if (sem->waiting_list != NULL) {
// 唤醒等待队列中的第一个任务
tcb_t *task = sem->waiting_list;
sem->waiting_list = task->next;
task->state = TASK_READY;
ready_queue_insert(g_scheduler.ready_queue, task);
} else {
if (sem->count < sem->max_count) {
sem->count++;
}
}
ENABLE_INTERRUPTS();
}
第4章 通信协议栈实现
4.1 UART通信协议
c
/* UART驱动及协议栈实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
// UART配置结构
typedef struct {
uint32_t baudrate;
uint8_t data_bits; // 5-9
uint8_t stop_bits; // 1, 1.5, 2
uint8_t parity; // 0=无, 1=奇, 2=偶
bool hardware_flow_control;
uint32_t timeout_ms;
} uart_config_t;
// UART硬件寄存器结构
typedef struct {
volatile uint32_t SR; // 状态寄存器
volatile uint32_t DR; // 数据寄存器
volatile uint32_t BRR; // 波特率寄存器
volatile uint32_t CR1; // 控制寄存器1
volatile uint32_t CR2; // 控制寄存器2
volatile uint32_t CR3; // 控制寄存器3
volatile uint32_t GTPR; // 保护时间寄存器
} UART_TypeDef;
// UART实例
#define USART1_BASE 0x40011000UL
#define USART2_BASE 0x40004400UL
#define USART3_BASE 0x40004800UL
#define USART1 ((UART_TypeDef *)USART1_BASE)
#define USART2 ((UART_TypeDef *)USART2_BASE)
#define USART3 ((UART_TypeDef *)USART3_BASE)
// UART驱动结构
typedef struct {
UART_TypeDef *instance;
uart_config_t config;
uint8_t *rx_buffer;
uint32_t rx_buffer_size;
volatile uint32_t rx_head;
volatile uint32_t rx_tail;
uint8_t *tx_buffer;
uint32_t tx_buffer_size;
volatile uint32_t tx_head;
volatile uint32_t tx_tail;
volatile bool tx_busy;
void (*rx_callback)(uint8_t data);
void (*tx_complete_callback)(void);
void (*error_callback)(uint32_t error);
} uart_driver_t;
// UART初始化
bool uart_init(uart_driver_t *uart, UART_TypeDef *instance,
const uart_config_t *config,
uint8_t *rx_buffer, uint32_t rx_buffer_size,
uint8_t *tx_buffer, uint32_t tx_buffer_size) {
if (uart == NULL || instance == NULL || config == NULL ||
rx_buffer == NULL || rx_buffer_size == 0 ||
tx_buffer == NULL || tx_buffer_size == 0) {
return false;
}
// 初始化驱动结构
uart->instance = instance;
uart->config = *config;
uart->rx_buffer = rx_buffer;
uart->rx_buffer_size = rx_buffer_size;
uart->rx_head = 0;
uart->rx_tail = 0;
uart->tx_buffer = tx_buffer;
uart->tx_buffer_size = tx_buffer_size;
uart->tx_head = 0;
uart->tx_tail = 0;
uart->tx_busy = false;
uart->rx_callback = NULL;
uart->tx_complete_callback = NULL;
uart->error_callback = NULL;
// 配置波特率
uint32_t apb_clock = 8000000; // 假设APB时钟为8MHz
uint32_t div = (apb_clock + (config->baudrate / 2)) / config->baudrate;
instance->BRR = div;
// 配置数据位、停止位、校验位
uint32_t cr1 = 0;
uint32_t cr2 = 0;
uint32_t cr3 = 0;
// 数据位
switch (config->data_bits) {
case 8: cr1 |= 0x0000; break;
case 9: cr1 |= 0x1000; break;
default: return false;
}
// 停止位
switch (config->stop_bits) {
case 1: cr2 |= 0x0000; break;
case 2: cr2 |= 0x2000; break;
default: return false;
}
// 校验位
switch (config->parity) {
case 0: break; // 无校验
case 1: cr1 |= 0x0400; break; // 奇校验
case 2: cr1 |= 0x0600; break; // 偶校验
default: return false;
}
// 硬件流控制
if (config->hardware_flow_control) {
cr3 |= 0x0300; // 启用RTS和CTS
}
// 启用UART
cr1 |= 0x2000; // 启用UART
cr1 |= 0x0004; // 启用接收
cr1 |= 0x0008; // 启用发送
instance->CR1 = cr1;
instance->CR2 = cr2;
instance->CR3 = cr3;
// 启用接收中断
instance->CR1 |= 0x0020;
return true;
}
// 接收中断处理
void uart_rx_isr(uart_driver_t *uart) {
if (uart == NULL || uart->instance == NULL) {
return;
}
// 读取状态寄存器
uint32_t sr = uart->instance->SR;
// 检查接收数据就绪
if (sr & 0x0020) { // RXNE位
// 读取数据
uint8_t data = (uint8_t)(uart->instance->DR & 0xFF);
// 存储到接收缓冲区
uint32_t next_head = (uart->rx_head + 1) % uart->rx_buffer_size;
if (next_head != uart->rx_tail) { // 缓冲区未满
uart->rx_buffer[uart->rx_head] = data;
uart->rx_head = next_head;
}
// 调用回调函数
if (uart->rx_callback != NULL) {
uart->rx_callback(data);
}
}
// 检查错误
if (sr & 0x0008) { // 帧错误
uart->instance->SR &= ~0x0008;
if (uart->error_callback != NULL) {
uart->error_callback(0x01);
}
}
if (sr & 0x0010) { // 噪声错误
uart->instance->SR &= ~0x0010;
if (uart->error_callback != NULL) {
uart->error_callback(0x02);
}
}
if (sr & 0x0080) { // 溢出错误
uart->instance->SR &= ~0x0080;
if (uart->error_callback != NULL) {
uart->error_callback(0x04);
}
}
}
// 发送中断处理
void uart_tx_isr(uart_driver_t *uart) {
if (uart == NULL || uart->instance == NULL) {
return;
}
if (uart->tx_head != uart->tx_tail) {
// 发送下一个字节
uint8_t data = uart->tx_buffer[uart->tx_tail];
uart->instance->DR = data;
uart->tx_tail = (uart->tx_tail + 1) % uart->tx_buffer_size;
} else {
// 发送完成,禁用发送空中断
uart->instance->CR1 &= ~0x0080; // 禁用TXE中断
uart->tx_busy = false;
// 调用发送完成回调
if (uart->tx_complete_callback != NULL) {
uart->tx_complete_callback();
}
}
}
// 发送数据
bool uart_send(uart_driver_t *uart, const uint8_t *data, uint32_t length) {
if (uart == NULL || data == NULL || length == 0) {
return false;
}
DISABLE_INTERRUPTS();
// 检查发送缓冲区是否有足够空间
uint32_t free_space;
if (uart->tx_head >= uart->tx_tail) {
free_space = uart->tx_buffer_size - (uart->tx_head - uart->tx_tail) - 1;
} else {
free_space = uart->tx_tail - uart->tx_head - 1;
}
if (length > free_space) {
ENABLE_INTERRUPTS();
return false;
}
// 复制数据到发送缓冲区
for (uint32_t i = 0; i < length; i++) {
uart->tx_buffer[uart->tx_head] = data[i];
uart->tx_head = (uart->tx_head + 1) % uart->tx_buffer_size;
}
// 如果UART空闲,启动发送
if (!uart->tx_busy) {
uart->tx_busy = true;
uart->instance->CR1 |= 0x0080; // 启用TXE中断
}
ENABLE_INTERRUPTS();
return true;
}
// 接收数据
uint32_t uart_receive(uart_driver_t *uart, uint8_t *buffer, uint32_t max_length) {
if (uart == NULL || buffer == NULL || max_length == 0) {
return 0;
}
DISABLE_INTERRUPTS();
uint32_t received = 0;
while (uart->rx_tail != uart->rx_head && received < max_length) {
buffer[received++] = uart->rx_buffer[uart->rx_tail];
uart->rx_tail = (uart->rx_tail + 1) % uart->rx_buffer_size;
}
ENABLE_INTERRUPTS();
return received;
}
// Modbus RTU协议实现
typedef struct {
uint8_t address; // 设备地址
uint8_t function; // 功能码
uint16_t start_addr; // 起始地址
uint16_t quantity; // 寄存器数量
uint8_t *data; // 数据指针
uint16_t data_length; // 数据长度
uint16_t crc; // CRC校验
} modbus_pdu_t;
// Modbus上下文
typedef struct {
uint8_t device_address;
uart_driver_t *uart;
uint32_t baudrate;
uint32_t char_timeout; // 字符超时(3.5个字符时间)
uint32_t frame_timeout; // 帧超时
void (*coil_read_callback)(uint16_t addr, uint16_t quantity, uint8_t *coils);
void (*coil_write_callback)(uint16_t addr, uint16_t quantity, const uint8_t *coils);
void (*register_read_callback)(uint16_t addr, uint16_t quantity, uint16_t *registers);
void (*register_write_callback)(uint16_t addr, uint16_t quantity, const uint16_t *registers);
} modbus_context_t;
// CRC16计算
uint16_t modbus_crc16(const uint8_t *data, uint16_t length) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
// Modbus帧解析
bool modbus_parse_frame(const uint8_t *frame, uint16_t length, modbus_pdu_t *pdu) {
if (frame == NULL || length < 4 || pdu == NULL) {
return false;
}
// 检查CRC
uint16_t crc = modbus_crc16(frame, length - 2);
uint16_t frame_crc = (frame[length - 1] << 8) | frame[length - 2];
if (crc != frame_crc) {
return false;
}
// 解析PDU
pdu->address = frame[0];
pdu->function = frame[1];
switch (pdu->function) {
case 0x01: // 读线圈
case 0x02: // 读离散输入
case 0x03: // 读保持寄存器
case 0x04: // 读输入寄存器
if (length == 8) {
pdu->start_addr = (frame[2] << 8) | frame[3];
pdu->quantity = (frame[4] << 8) | frame[5];
pdu->data_length = 0;
}
break;
case 0x05: // 写单个线圈
if (length == 8) {
pdu->start_addr = (frame[2] << 8) | frame[3];
pdu->quantity = 1;
pdu->data = NULL;
pdu->data_length = 0;
}
break;
case 0x06: // 写单个寄存器
if (length == 8) {
pdu->start_addr = (frame[2] << 8) | frame[3];
pdu->quantity = 1;
pdu->data = NULL;
pdu->data_length = 0;
}
break;
case 0x0F: // 写多个线圈
case 0x10: // 写多个寄存器
if (length >= 9) {
pdu->start_addr = (frame[2] << 8) | frame[3];
pdu->quantity = (frame[4] << 8) | frame[5];
uint8_t byte_count = frame[6];
pdu->data = (uint8_t *)&frame[7];
pdu->data_length = byte_count;
// 检查长度
if (7 + byte_count + 2 != length) {
return false;
}
}
break;
default:
return false;
}
return true;
}
// Modbus响应生成
bool modbus_build_response(const modbus_pdu_t *pdu, uint8_t *response, uint16_t *length) {
if (pdu == NULL || response == NULL || length == NULL) {
return false;
}
uint16_t index = 0;
// 地址
response[index++] = pdu->address;
// 功能码
response[index++] = pdu->function;
switch (pdu->function) {
case 0x01: // 读线圈响应
case 0x02: // 读离散输入响应
// 字节数
response[index++] = (pdu->quantity + 7) / 8;
// 数据
if (pdu->data != NULL) {
memcpy(&response[index], pdu->data, response[index-1]);
index += response[index-1];
}
break;
case 0x03: // 读保持寄存器响应
case 0x04: // 读输入寄存器响应
// 字节数
response[index++] = pdu->quantity * 2;
// 数据
if (pdu->data != NULL) {
memcpy(&response[index], pdu->data, response[index-1]);
index += response[index-1];
}
break;
case 0x05: // 写单个线圈响应
case 0x06: // 写单个寄存器响应
// 地址
response[index++] = (pdu->start_addr >> 8) & 0xFF;
response[index++] = pdu->start_addr & 0xFF;
// 值
if (pdu->data != NULL) {
memcpy(&response[index], pdu->data, 2);
index += 2;
}
break;
case 0x0F: // 写多个线圈响应
case 0x10: // 写多个寄存器响应
// 地址
response[index++] = (pdu->start_addr >> 8) & 0xFF;
response[index++] = pdu->start_addr & 0xFF;
// 数量
response[index++] = (pdu->quantity >> 8) & 0xFF;
response[index++] = pdu->quantity & 0xFF;
break;
default:
return false;
}
// 计算CRC
uint16_t crc = modbus_crc16(response, index);
response[index++] = crc & 0xFF;
response[index++] = (crc >> 8) & 0xFF;
*length = index;
return true;
}
// Modbus错误响应
bool modbus_build_error_response(uint8_t address, uint8_t function, uint8_t error_code,
uint8_t *response, uint16_t *length) {
if (response == NULL || length == NULL) {
return false;
}
uint16_t index = 0;
response[index++] = address;
response[index++] = function | 0x80; // 设置错误标志
response[index++] = error_code;
uint16_t crc = modbus_crc16(response, index);
response[index++] = crc & 0xFF;
response[index++] = (crc >> 8) & 0xFF;
*length = index;
return true;
}
// Modbus从站处理
void modbus_slave_process(modbus_context_t *ctx) {
static uint8_t rx_buffer[256];
static uint8_t tx_buffer[256];
static uint32_t last_char_time = 0;
static uint16_t rx_index = 0;
uint32_t current_time = get_system_ticks();
// 接收数据
uint8_t data;
if (uart_receive(ctx->uart, &data, 1) > 0) {
// 检查帧间隔
if (current_time - last_char_time > ctx->char_timeout) {
// 新帧开始
rx_index = 0;
}
last_char_time = current_time;
// 存储数据
if (rx_index < sizeof(rx_buffer)) {
rx_buffer[rx_index++] = data;
}
}
// 检查是否收到完整帧
if (rx_index >= 4 && current_time - last_char_time > ctx->frame_timeout) {
// 解析帧
modbus_pdu_t pdu;
if (modbus_parse_frame(rx_buffer, rx_index, &pdu)) {
// 检查地址
if (pdu.address == 0 || pdu.address == ctx->device_address) {
// 处理请求
modbus_pdu_t response_pdu;
memset(&response_pdu, 0, sizeof(response_pdu));
response_pdu.address = pdu.address;
response_pdu.function = pdu.function;
switch (pdu.function) {
case 0x01: // 读线圈
if (ctx->coil_read_callback != NULL) {
uint8_t coils[256];
uint16_t byte_count = (pdu.quantity + 7) / 8;
ctx->coil_read_callback(pdu.start_addr, pdu.quantity, coils);
response_pdu.data = coils;
response_pdu.data_length = byte_count;
}
break;
case 0x03: // 读保持寄存器
if (ctx->register_read_callback != NULL) {
uint16_t registers[125];
ctx->register_read_callback(pdu.start_addr, pdu.quantity, registers);
response_pdu.data = (uint8_t *)registers;
response_pdu.data_length = pdu.quantity * 2;
}
break;
case 0x06: // 写单个寄存器
if (ctx->register_write_callback != NULL) {
uint16_t value = (rx_buffer[4] << 8) | rx_buffer[5];
ctx->register_write_callback(pdu.start_addr, 1, &value);
}
break;
default:
// 生成错误响应
modbus_build_error_response(pdu.address, pdu.function, 0x01,
tx_buffer, &tx_length);
uart_send(ctx->uart, tx_buffer, tx_length);
rx_index = 0;
return;
}
// 生成响应
uint16_t tx_length;
if (modbus_build_response(&response_pdu, tx_buffer, &tx_length)) {
uart_send(ctx->uart, tx_buffer, tx_length);
}
}
}
// 准备接收下一帧
rx_index = 0;
}
}
4.2 SPI通信协议
c
/* SPI驱动及协议实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
// SPI配置
typedef struct {
uint32_t clock_speed; // 时钟频率
uint8_t data_size; // 数据大小(8或16位)
uint8_t clock_polarity; // 时钟极性(0或1)
uint8_t clock_phase; // 时钟相位(0或1)
uint8_t bit_order; // 位顺序(0=MSB first,1=LSB first)
uint8_t mode; // 主从模式
} spi_config_t;
// SPI硬件寄存器
typedef struct {
volatile uint32_t CR1; // 控制寄存器1
volatile uint32_t CR2; // 控制寄存器2
volatile uint32_t SR; // 状态寄存器
volatile uint32_t DR; // 数据寄存器
volatile uint32_t CRCPR; // CRC多项式寄存器
volatile uint32_t RXCRCR; // 接收CRC寄存器
volatile uint32_t TXCRCR; // 发送CRC寄存器
} SPI_TypeDef;
// SPI实例
#define SPI1_BASE 0x40013000UL
#define SPI2_BASE 0x40003800UL
#define SPI3_BASE 0x40003C00UL
#define SPI1 ((SPI_TypeDef *)SPI1_BASE)
#define SPI2 ((SPI_TypeDef *)SPI2_BASE)
#define SPI3 ((SPI_TypeDef *)SPI3_BASE)
// SPI驱动结构
typedef struct {
SPI_TypeDef *instance;
spi_config_t config;
void (*complete_callback)(void);
void (*error_callback)(uint32_t error);
volatile bool transfer_busy;
volatile uint32_t tx_index;
volatile uint32_t rx_index;
volatile uint32_t transfer_size;
uint8_t *tx_buffer;
uint8_t *rx_buffer;
} spi_driver_t;
// SPI初始化
bool spi_init(spi_driver_t *spi, SPI_TypeDef *instance, const spi_config_t *config) {
if (spi == NULL || instance == NULL || config == NULL) {
return false;
}
// 初始化驱动结构
spi->instance = instance;
spi->config = *config;
spi->complete_callback = NULL;
spi->error_callback = NULL;
spi->transfer_busy = false;
spi->tx_index = 0;
spi->rx_index = 0;
spi->transfer_size = 0;
spi->tx_buffer = NULL;
spi->rx_buffer = NULL;
// 配置SPI
uint32_t cr1 = 0;
uint32_t cr2 = 0;
// 时钟极性
if (config->clock_polarity == 1) {
cr1 |= 0x0002;
}
// 时钟相位
if (config->clock_phase == 1) {
cr1 |= 0x0001;
}
// 主从模式
if (config->mode == 1) { // 主机模式
cr1 |= 0x0004;
}
// 数据大小
if (config->data_size == 16) {
cr1 |= 0x0800;
}
// 位顺序
if (config->bit_order == 1) { // LSB first
cr1 |= 0x0080;
}
// 计算分频系数
uint32_t pclk = 8000000; // 假设PCLK为8MHz
uint32_t div = 0;
uint32_t speed = config->clock_speed;
if (speed <= pclk / 2) div = 0; // fPCLK/2
else if (speed <= pclk / 4) div = 1; // fPCLK/4
else if (speed <= pclk / 8) div = 2; // fPCLK/8
else if (speed <= pclk / 16) div = 3; // fPCLK/16
else if (speed <= pclk / 32) div = 4; // fPCLK/32
else if (speed <= pclk / 64) div = 5; // fPCLK/64
else if (speed <= pclk / 128) div = 6; // fPCLK/128
else div = 7; // fPCLK/256
cr1 |= (div << 3);
// 启用SPI
cr1 |= 0x0040;
// 配置中断
cr2 |= 0x0002; // 接收缓冲区非空中断
instance->CR1 = cr1;
instance->CR2 = cr2;
return true;
}
// SPI中断处理
void spi_isr(spi_driver_t *spi) {
if (spi == NULL || spi->instance == NULL) {
return;
}
uint32_t sr = spi->instance->SR;
// 检查接收缓冲区非空
if (sr & 0x0001) { // RXNE
// 读取数据
uint16_t data;
if (spi->config.data_size == 16) {
data = spi->instance->DR;
} else {
data = (uint8_t)spi->instance->DR;
}
// 存储到接收缓冲区
if (spi->rx_buffer != NULL && spi->rx_index < spi->transfer_size) {
if (spi->config.data_size == 16) {
((uint16_t *)spi->rx_buffer)[spi->rx_index++] = data;
} else {
spi->rx_buffer[spi->rx_index++] = (uint8_t)data;
}
}
}
// 检查发送缓冲区空
if (sr & 0x0002) { // TXE
if (spi->tx_index < spi->transfer_size) {
// 发送下一个数据
uint16_t data;
if (spi->config.data_size == 16) {
data = ((uint16_t *)spi->tx_buffer)[spi->tx_index];
} else {
data = spi->tx_buffer[spi->tx_index];
}
spi->instance->DR = data;
spi->tx_index++;
} else {
// 发送完成,禁用TXE中断
spi->instance->CR2 &= ~0x0002;
}
}
// 检查传输完成
if (sr & 0x0080) { // BSY位清除表示传输完成
if (!(spi->instance->SR & 0x0080)) {
spi->transfer_busy = false;
if (spi->complete_callback != NULL) {
spi->complete_callback();
}
}
}
// 检查错误
if (sr & 0x0004) { // CRC错误
spi->instance->SR &= ~0x0004;
if (spi->error_callback != NULL) {
spi->error_callback(0x01);
}
}
if (sr & 0x0010) { // 模式错误
spi->instance->SR &= ~0x0010;
if (spi->error_callback != NULL) {
spi->error_callback(0x02);
}
}
if (sr & 0x0020) { // 溢出错误
spi->instance->SR &= ~0x0020;
if (spi->error_callback != NULL) {
spi->error_callback(0x04);
}
}
}
// SPI传输
bool spi_transfer(spi_driver_t *spi, const void *tx_data, void *rx_data, uint32_t size) {
if (spi == NULL || size == 0 || spi->transfer_busy) {
return false;
}
// 检查数据对齐
if ((spi->config.data_size == 16) && (size % 2 != 0)) {
return false;
}
DISABLE_INTERRUPTS();
spi->transfer_busy = true;
spi->tx_index = 0;
spi->rx_index = 0;
spi->transfer_size = size;
spi->tx_buffer = (uint8_t *)tx_data;
spi->rx_buffer = (uint8_t *)rx_data;
// 启用中断
spi->instance->CR2 |= 0x0002; // TXE中断
// 如果tx_data为NULL,发送哑元数据
if (tx_data == NULL) {
static uint8_t dummy_data[256] = {0};
if (size > sizeof(dummy_data)) {
ENABLE_INTERRUPTS();
return false;
}
spi->tx_buffer = dummy_data;
}
ENABLE_INTERRUPTS();
return true;
}
// SPI DMA传输
bool spi_transfer_dma(spi_driver_t *spi, const void *tx_data, void *rx_data, uint32_t size) {
// DMA配置代码
// ...
return true;
}
// SPI Flash设备驱动
typedef struct {
spi_driver_t *spi;
uint8_t cs_pin;
GPIO_TypeDef *cs_port;
uint32_t capacity; // 容量(字节)
uint32_t page_size; // 页大小
uint32_t sector_size; // 扇区大小
uint32_t block_size; // 块大小
} spi_flash_t;
// SPI Flash命令
#define FLASH_CMD_WRITE_ENABLE 0x06
#define FLASH_CMD_WRITE_DISABLE 0x04
#define FLASH_CMD_READ_STATUS 0x05
#define FLASH_CMD_WRITE_STATUS 0x01
#define FLASH_CMD_READ_DATA 0x03
#define FLASH_CMD_FAST_READ 0x0B
#define FLASH_CMD_PAGE_PROGRAM 0x02
#define FLASH_CMD_SECTOR_ERASE 0x20
#define FLASH_CMD_BLOCK_ERASE 0xD8
#define FLASH_CMD_CHIP_ERASE 0xC7
#define FLASH_CMD_POWER_DOWN 0xB9
#define FLASH_CMD_RELEASE_POWER_DOWN 0xAB
#define FLASH_CMD_READ_ID 0x9F
// 选择芯片
static void flash_select(spi_flash_t *flash) {
if (flash && flash->cs_port) {
gpio_set_atomic(flash->cs_port, flash->cs_pin, false);
delay_us(1);
}
}
// 取消选择芯片
static void flash_deselect(spi_flash_t *flash) {
if (flash && flash->cs_port) {
delay_us(1);
gpio_set_atomic(flash->cs_port, flash->cs_pin, true);
delay_us(1);
}
}
// 读取Flash ID
bool flash_read_id(spi_flash_t *flash, uint8_t *manufacturer_id, uint16_t *device_id) {
if (flash == NULL || flash->spi == NULL) {
return false;
}
uint8_t cmd = FLASH_CMD_READ_ID;
uint8_t response[3];
flash_select(flash);
// 发送命令
if (!spi_transfer(flash->spi, &cmd, NULL, 1)) {
flash_deselect(flash);
return false;
}
// 读取响应
if (!spi_transfer(flash->spi, NULL, response, 3)) {
flash_deselect(flash);
return false;
}
flash_deselect(flash);
if (manufacturer_id) *manufacturer_id = response[0];
if (device_id) *device_id = (response[1] << 8) | response[2];
return true;
}
// 读取状态寄存器
uint8_t flash_read_status(spi_flash_t *flash) {
if (flash == NULL || flash->spi == NULL) {
return 0xFF;
}
uint8_t cmd = FLASH_CMD_READ_STATUS;
uint8_t status;
flash_select(flash);
spi_transfer(flash->spi, &cmd, NULL, 1);
spi_transfer(flash->spi, NULL, &status, 1);
flash_deselect(flash);
return status;
}
// 等待Flash就绪
bool flash_wait_ready(spi_flash_t *flash, uint32_t timeout_ms) {
if (flash == NULL) {
return false;
}
uint32_t start_time = get_system_ticks();
while (1) {
uint8_t status = flash_read_status(flash);
if (!(status & 0x01)) { // WIP位为0表示就绪
return true;
}
if (timeout_ms > 0 && (get_system_ticks() - start_time) >= timeout_ms) {
return false;
}
delay_ms(1);
}
}
// 使能写操作
bool flash_write_enable(spi_flash_t *flash) {
if (flash == NULL || flash->spi == NULL) {
return false;
}
uint8_t cmd = FLASH_CMD_WRITE_ENABLE;
flash_select(flash);
bool result = spi_transfer(flash->spi, &cmd, NULL, 1);
flash_deselect(flash);
return result;
}
// 读取数据
bool flash_read(spi_flash_t *flash, uint32_t address, void *buffer, uint32_t size) {
if (flash == NULL || flash->spi == NULL || buffer == NULL || size == 0) {
return false;
}
if (address + size > flash->capacity) {
return false;
}
// 等待Flash就绪
if (!flash_wait_ready(flash, 100)) {
return false;
}
uint8_t cmd[4];
cmd[0] = FLASH_CMD_READ_DATA;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_select(flash);
// 发送读命令和地址
if (!spi_transfer(flash->spi, cmd, NULL, 4)) {
flash_deselect(flash);
return false;
}
// 读取数据
if (!spi_transfer(flash->spi, NULL, buffer, size)) {
flash_deselect(flash);
return false;
}
flash_deselect(flash);
return true;
}
// 页编程
bool flash_page_program(spi_flash_t *flash, uint32_t address, const void *data, uint32_t size) {
if (flash == NULL || flash->spi == NULL || data == NULL || size == 0) {
return false;
}
if (address % flash->page_size != 0) {
return false; // 地址必须页对齐
}
if (size > flash->page_size) {
return false; // 不能跨页编程
}
// 等待Flash就绪
if (!flash_wait_ready(flash, 100)) {
return false;
}
// 使能写操作
if (!flash_write_enable(flash)) {
return false;
}
uint8_t cmd[4];
cmd[0] = FLASH_CMD_PAGE_PROGRAM;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_select(flash);
// 发送写命令和地址
if (!spi_transfer(flash->spi, cmd, NULL, 4)) {
flash_deselect(flash);
return false;
}
// 发送数据
if (!spi_transfer(flash->spi, data, NULL, size)) {
flash_deselect(flash);
return false;
}
flash_deselect(flash);
// 等待编程完成
return flash_wait_ready(flash, 100);
}
// 扇区擦除
bool flash_sector_erase(spi_flash_t *flash, uint32_t address) {
if (flash == NULL || flash->spi == NULL) {
return false;
}
if (address % flash->sector_size != 0) {
return false; // 地址必须扇区对齐
}
// 等待Flash就绪
if (!flash_wait_ready(flash, 100)) {
return false;
}
// 使能写操作
if (!flash_write_enable(flash)) {
return false;
}
uint8_t cmd[4];
cmd[0] = FLASH_CMD_SECTOR_ERASE;
cmd[1] = (address >> 16) & 0xFF;
cmd[2] = (address >> 8) & 0xFF;
cmd[3] = address & 0xFF;
flash_select(flash);
// 发送擦除命令
bool result = spi_transfer(flash->spi, cmd, NULL, 4);
flash_deselect(flash);
if (!result) {
return false;
}
// 等待擦除完成
return flash_wait_ready(flash, 1000); // 扇区擦除时间较长
}
// 块擦除
bool flash_block_erase(spi_flash_t *flash, uint32_t address) {
// 类似扇区擦除,使用BLOCK_ERASE命令
// ...
return true;
}
// 全片擦除
bool flash_chip_erase(spi_flash_t *flash) {
if (flash == NULL || flash->spi == NULL) {
return false;
}
// 等待Flash就绪
if (!flash_wait_ready(flash, 100)) {
return false;
}
// 使能写操作
if (!flash_write_enable(flash)) {
return false;
}
uint8_t cmd = FLASH_CMD_CHIP_ERASE;
flash_select(flash);
bool result = spi_transfer(flash->spi, &cmd, NULL, 1);
flash_deselect(flash);
if (!result) {
return false;
}
// 等待擦除完成(全片擦除时间很长)
return flash_wait_ready(flash, 30000); // 30秒超时
}
4.3 I2C通信协议
c
/* I2C驱动及协议实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
// I2C配置
typedef struct {
uint32_t clock_speed; // 时钟频率(Hz)
uint8_t addressing_mode; // 寻址模式(7位或10位)
bool general_call; // 是否响应广播呼叫
uint32_t rise_time; // 上升时间(ns)
uint32_t fall_time; // 下降时间(ns)
} i2c_config_t;
// I2C硬件寄存器
typedef struct {
volatile uint32_t CR1; // 控制寄存器1
volatile uint32_t CR2; // 控制寄存器2
volatile uint32_t OAR1; // 自身地址寄存器1
volatile uint32_t OAR2; // 自身地址寄存器2
volatile uint32_t DR; // 数据寄存器
volatile uint32_t SR1; // 状态寄存器1
volatile uint32_t SR2; // 状态寄存器2
volatile uint32_t CCR; // 时钟控制寄存器
volatile uint32_t TRISE; // 上升时间寄存器
} I2C_TypeDef;
// I2C实例
#define I2C1_BASE 0x40005400UL
#define I2C2_BASE 0x40005800UL
#define I2C1 ((I2C_TypeDef *)I2C1_BASE)
#define I2C2 ((I2C_TypeDef *)I2C2_BASE)
// I2C事件标志
#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001)
#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082)
#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084)
#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002)
#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040)
// I2C驱动结构
typedef struct {
I2C_TypeDef *instance;
i2c_config_t config;
uint8_t slave_address;
volatile bool transfer_busy;
volatile uint32_t tx_index;
volatile uint32_t rx_index;
volatile uint32_t transfer_size;
uint8_t *tx_buffer;
uint8_t *rx_buffer;
void (*complete_callback)(void);
void (*error_callback)(uint32_t error);
} i2c_driver_t;
// I2C初始化
bool i2c_init(i2c_driver_t *i2c, I2C_TypeDef *instance, const i2c_config_t *config) {
if (i2c == NULL || instance == NULL || config == NULL) {
return false;
}
// 初始化驱动结构
i2c->instance = instance;
i2c->config = *config;
i2c->slave_address = 0;
i2c->transfer_busy = false;
i2c->tx_index = 0;
i2c->rx_index = 0;
i2c->transfer_size = 0;
i2c->tx_buffer = NULL;
i2c->rx_buffer = NULL;
i2c->complete_callback = NULL;
i2c->error_callback = NULL;
// 计算时钟分频
uint32_t pclk = 8000000; // 假设PCLK为8MHz
uint32_t freq_range = 0;
if (pclk < 2000000) {
freq_range = 0x00;
} else if (pclk < 4000000) {
freq_range = 0x01;
} else if (pclk < 8000000) {
freq_range = 0x02;
} else {
freq_range = 0x03;
}
// 配置时钟
uint32_t ccr = 0;
if (config->clock_speed <= 100000) {
// 标准模式
ccr = pclk / (config->clock_speed * 2);
if (ccr < 0x04) ccr = 0x04;
} else {
// 快速模式
ccr = pclk / (config->clock_speed * 3);
ccr |= 0x8000; // 快速模式标志
}
// 配置上升时间
uint32_t trise = 0;
if (config->clock_speed <= 100000) {
trise = config->rise_time / 1000 + 1;
} else {
trise = config->rise_time / 300 + 1;
}
// 应用配置
instance->CR2 = (freq_range << 0);
instance->CCR = ccr;
instance->TRISE = trise;
// 启用I2C
instance->CR1 |= 0x0001;
return true;
}
// I2C中断处理
void i2c_isr(i2c_driver_t *i2c) {
if (i2c == NULL || i2c->instance == NULL) {
return;
}
uint32_t sr1 = i2c->instance->SR1;
uint32_t sr2 = i2c->instance->SR2;
// 检查事件
if (sr1 & 0x0001) { // SB - 起始位已发送
// 发送从机地址
uint8_t address = i2c->slave_address << 1;
if (i2c->tx_buffer != NULL) {
address |= 0x00; // 写操作
} else {
address |= 0x01; // 读操作
}
i2c->instance->DR = address;
}
if (sr1 & 0x0002) { // ADDR - 地址已发送
// 读取SR2清除标志
volatile uint32_t temp = sr2;
(void)temp;
if (i2c->tx_buffer == NULL) {
// 接收模式
if (i2c->transfer_size == 1) {
// 单个字节接收,禁用ACK
i2c->instance->CR1 &= ~0x0400;
} else {
// 启用ACK
i2c->instance->CR1 |= 0x0400;
}
}
}
if (sr1 & 0x0040) { // RXNE - 接收缓冲区非空
if (i2c->rx_buffer != NULL && i2c->rx_index < i2c->transfer_size) {
i2c->rx_buffer[i2c->rx_index++] = i2c->instance->DR;
if (i2c->rx_index == i2c->transfer_size - 1) {
// 最后一个字节,禁用ACK
i2c->instance->CR1 &= ~0x0400;
}
}
}
if (sr1 & 0x0080) { // TXE - 发送缓冲区空
if (i2c->tx_buffer != NULL && i2c->tx_index < i2c->transfer_size) {
i2c->instance->DR = i2c->tx_buffer[i2c->tx_index++];
} else {
// 发送完成
i2c->transfer_busy = false;
i2c->instance->CR1 |= 0x0200; // 发送停止条件
if (i2c->complete_callback != NULL) {
i2c->complete_callback();
}
}
}
if (sr1 & 0x0100) { // BTF - 字节传输完成
// 处理字节传输完成
}
// 检查错误
if (sr1 & 0x0004) { // BERR - 总线错误
i2c->instance->SR1 &= ~0x0004;
if (i2c->error_callback != NULL) {
i2c->error_callback(0x01);
}
}
if (sr1 & 0x0008) { // ARLO - 仲裁丢失
i2c->instance->SR1 &= ~0x0008;
if (i2c->error_callback != NULL) {
i2c->error_callback(0x02);
}
}
if (sr1 & 0x0010) { // AF - 应答失败
i2c->instance->SR1 &= ~0x0010;
if (i2c->error_callback != NULL) {
i2c->error_callback(0x04);
}
}
if (sr1 & 0x0020) { // OVR - 溢出/欠载
i2c->instance->SR1 &= ~0x0020;
if (i2c->error_callback != NULL) {
i2c->error_callback(0x08);
}
}
if (sr1 & 0x0200) { // TIMEOUT - 超时
i2c->instance->SR1 &= ~0x0200;
if (i2c->error_callback != NULL) {
i2c->error_callback(0x10);
}
}
}
// I2C主模式传输
bool i2c_master_transmit(i2c_driver_t *i2c, uint8_t slave_addr,
const uint8_t *data, uint32_t size,
uint32_t timeout) {
if (i2c == NULL || data == NULL || size == 0 || i2c->transfer_busy) {
return false;
}
DISABLE_INTERRUPTS();
i2c->transfer_busy = true;
i2c->slave_address = slave_addr;
i2c->tx_buffer = (uint8_t *)data;
i2c->rx_buffer = NULL;
i2c->tx_index = 0;
i2c->transfer_size = size;
// 生成起始条件
i2c->instance->CR1 |= 0x0100;
// 启用中断
i2c->instance->CR2 |= 0x0001;
ENABLE_INTERRUPTS();
// 等待传输完成
uint32_t start_time = get_system_ticks();
while (i2c->transfer_busy) {
if (timeout > 0 && (get_system_ticks() - start_time) >= timeout) {
// 超时,中止传输
i2c->instance->CR1 |= 0x0200; // 停止条件
i2c->transfer_busy = false;
return false;
}
}
return true;
}
// I2C主模式接收
bool i2c_master_receive(i2c_driver_t *i2c, uint8_t slave_addr,
uint8_t *buffer, uint32_t size,
uint32_t timeout) {
if (i2c == NULL || buffer == NULL || size == 0 || i2c->transfer_busy) {
return false;
}
DISABLE_INTERRUPTS();
i2c->transfer_busy = true;
i2c->slave_address = slave_addr;
i2c->tx_buffer = NULL;
i2c->rx_buffer = buffer;
i2c->rx_index = 0;
i2c->transfer_size = size;
// 生成起始条件
i2c->instance->CR1 |= 0x0100;
// 启用中断
i2c->instance->CR2 |= 0x0001;
ENABLE_INTERRUPTS();
// 等待传输完成
uint32_t start_time = get_system_ticks();
while (i2c->transfer_busy) {
if (timeout > 0 && (get_system_ticks() - start_time) >= timeout) {
// 超时,中止传输
i2c->instance->CR1 |= 0x0200; // 停止条件
i2c->transfer_busy = false;
return false;
}
}
return true;
}
// I2C存储器设备(如EEPROM)驱动
typedef struct {
i2c_driver_t *i2c;
uint8_t device_address;
uint32_t capacity;
uint32_t page_size;
uint32_t write_time_ms;
} i2c_eeprom_t;
// EEPROM读取
bool eeprom_read(i2c_eeprom_t *eeprom, uint32_t address,
void *buffer, uint32_t size) {
if (eeprom == NULL || eeprom->i2c == NULL ||
buffer == NULL || size == 0) {
return false;
}
if (address + size > eeprom->capacity) {
return false;
}
// 发送地址
uint8_t addr_buf[2];
addr_buf[0] = (address >> 8) & 0xFF;
addr_buf[1] = address & 0xFF;
if (!i2c_master_transmit(eeprom->i2c, eeprom->device_address,
addr_buf, 2, 100)) {
return false;
}
// 读取数据
return i2c_master_receive(eeprom->i2c, eeprom->device_address,
buffer, size, 100);
}
// EEPROM写入
bool eeprom_write(i2c_eeprom_t *eeprom, uint32_t address,
const void *data, uint32_t size) {
if (eeprom == NULL || eeprom->i2c == NULL ||
data == NULL || size == 0) {
return false;
}
if (address + size > eeprom->capacity) {
return false;
}
uint32_t bytes_written = 0;
const uint8_t *data_ptr = (const uint8_t *)data;
while (bytes_written < size) {
// 计算当前页剩余空间
uint32_t page_offset = address % eeprom->page_size;
uint32_t bytes_in_page = eeprom->page_size - page_offset;
uint32_t bytes_to_write = size - bytes_written;
if (bytes_to_write > bytes_in_page) {
bytes_to_write = bytes_in_page;
}
// 准备写入缓冲区
uint8_t write_buf[2 + eeprom->page_size];
write_buf[0] = (address >> 8) & 0xFF;
write_buf[1] = address & 0xFF;
memcpy(&write_buf[2], data_ptr, bytes_to_write);
// 写入数据
if (!i2c_master_transmit(eeprom->i2c, eeprom->device_address,
write_buf, 2 + bytes_to_write, 100)) {
return false;
}
// 等待写入完成
delay_ms(eeprom->write_time_ms);
// 更新指针和地址
data_ptr += bytes_to_write;
address += bytes_to_write;
bytes_written += bytes_to_write;
}
return true;
}
// I2C温度传感器驱动(示例:LM75)
typedef struct {
i2c_driver_t *i2c;
uint8_t device_address;
int16_t temperature;
uint8_t config;
} lm75_sensor_t;
// LM75寄存器地址
#define LM75_REG_TEMP 0x00 // 温度寄存器
#define LM75_REG_CONFIG 0x01 // 配置寄存器
#define LM75_REG_THYST 0x02 // 温度下限
#define LM75_REG_TOS 0x03 // 温度上限
// 读取温度
bool lm75_read_temperature(lm75_sensor_t *sensor) {
if (sensor == NULL || sensor->i2c == NULL) {
return false;
}
// 发送温度寄存器地址
uint8_t reg_addr = LM75_REG_TEMP;
if (!i2c_master_transmit(sensor->i2c, sensor->device_address,
®_addr, 1, 10)) {
return false;
}
// 读取温度数据(2字节)
uint8_t temp_data[2];
if (!i2c_master_receive(sensor->i2c, sensor->device_address,
temp_data, 2, 10)) {
return false;
}
// 转换温度值
int16_t raw_temp = (temp_data[0] << 8) | temp_data[1];
sensor->temperature = raw_temp >> 7; // 11位数据,右移7位得到摄氏度
return true;
}
// 配置传感器
bool lm75_configure(lm75_sensor_t *sensor, uint8_t config) {
if (sensor == NULL || sensor->i2c == NULL) {
return false;
}
uint8_t data[2];
data[0] = LM75_REG_CONFIG;
data[1] = config;
if (!i2c_master_transmit(sensor->i2c, sensor->device_address,
data, 2, 10)) {
return false;
}
sensor->config = config;
return true;
}
// I2C扫描函数
void i2c_scan(i2c_driver_t *i2c, uint8_t *device_list, uint8_t *device_count) {
if (i2c == NULL || device_list == NULL || device_count == NULL) {
return;
}
*device_count = 0;
for (uint8_t addr = 1; addr < 127; addr++) {
// 尝试发送地址(写操作)
if (i2c_master_transmit(i2c, addr, NULL, 0, 10)) {
device_list[(*device_count)++] = addr;
}
delay_ms(1);
}
}
第5章 文件系统实现
5.1 FAT文件系统
c
/* FAT文件系统实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
// 磁盘操作接口
typedef struct {
bool (*init)(void);
bool (*read_sector)(uint32_t sector, uint8_t *buffer, uint32_t count);
bool (*write_sector)(uint32_t sector, const uint8_t *buffer, uint32_t count);
bool (*ioctl)(uint32_t cmd, void *arg);
uint32_t sector_size;
uint32_t sector_count;
} disk_interface_t;
// FAT类型
typedef enum {
FAT_TYPE_FAT12 = 12,
FAT_TYPE_FAT16 = 16,
FAT_TYPE_FAT32 = 32
} fat_type_t;
// FAT引导扇区
typedef struct {
uint8_t jump_code[3];
char oem_name[8];
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t fat_count;
uint16_t root_entries;
uint16_t total_sectors_16;
uint8_t media_type;
uint16_t sectors_per_fat_16;
uint16_t sectors_per_track;
uint16_t head_count;
uint32_t hidden_sectors;
uint32_t total_sectors_32;
// FAT32扩展部分
uint32_t sectors_per_fat_32;
uint16_t flags;
uint16_t fat_version;
uint32_t root_cluster;
uint16_t fs_info_sector;
uint16_t backup_boot_sector;
uint8_t reserved[12];
uint8_t drive_number;
uint8_t reserved1;
uint8_t boot_signature;
uint32_t volume_id;
char volume_label[11];
char fs_type[8];
uint8_t boot_code[420];
uint16_t boot_signature_end;
} PACKED fat_boot_sector_t;
// 目录项
typedef struct {
char name[8];
char ext[3];
uint8_t attr;
uint8_t reserved;
uint8_t create_time_tenth;
uint16_t create_time;
uint16_t create_date;
uint16_t access_date;
uint16_t cluster_high;
uint16_t modify_time;
uint16_t modify_date;
uint16_t cluster_low;
uint32_t file_size;
} PACKED fat_dir_entry_t;
// 长文件名目录项
typedef struct {
uint8_t sequence;
uint16_t name1[5];
uint8_t attr;
uint8_t type;
uint8_t checksum;
uint16_t name2[6];
uint16_t cluster;
uint16_t name3[2];
} PACKED fat_lfn_entry_t;
// 文件属性
#define ATTR_READ_ONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUME_ID 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
// 文件句柄
typedef struct {
uint32_t first_cluster;
uint32_t current_cluster;
uint32_t current_sector;
uint32_t sector_offset;
uint32_t file_size;
uint32_t file_offset;
bool is_directory;
uint8_t attr;
char name[256];
} file_handle_t;
// 文件系统上下文
typedef struct {
disk_interface_t *disk;
fat_type_t fat_type;
// BPB参数
uint32_t bytes_per_sector;
uint32_t sectors_per_cluster;
uint32_t reserved_sectors;
uint32_t fat_count;
uint32_t sectors_per_fat;
uint32_t root_entries;
uint32_t total_sectors;
uint32_t root_cluster;
// 计算值
uint32_t fat_start_sector;
uint32_t root_start_sector;
uint32_t data_start_sector;
uint32_t cluster_count;
uint32_t cluster_size;
// FAT表缓存
uint8_t *fat_cache;
uint32_t fat_cache_sector;
bool fat_cache_dirty;
// 当前目录
uint32_t current_dir_cluster;
} fatfs_context_t;
// 文件系统初始化
bool fatfs_init(fatfs_context_t *fs, disk_interface_t *disk) {
if (fs == NULL || disk == NULL) {
return false;
}
memset(fs, 0, sizeof(fatfs_context_t));
fs->disk = disk;
// 初始化磁盘
if (!disk->init()) {
return false;
}
// 读取引导扇区
fat_boot_sector_t bpb;
if (!disk->read_sector(0, (uint8_t *)&bpb, 1)) {
return false;
}
// 验证引导签名
if (bpb.boot_signature_end != 0xAA55) {
return false;
}
// 提取BPB参数
fs->bytes_per_sector = bpb.bytes_per_sector;
fs->sectors_per_cluster = bpb.sectors_per_cluster;
fs->reserved_sectors = bpb.reserved_sectors;
fs->fat_count = bpb.fat_count;
fs->root_entries = bpb.root_entries;
if (bpb.total_sectors_16 != 0) {
fs->total_sectors = bpb.total_sectors_16;
} else {
fs->total_sectors = bpb.total_sectors_32;
}
// 确定FAT类型
uint32_t data_sectors = fs->total_sectors -
(fs->reserved_sectors +
fs->fat_count * bpb.sectors_per_fat_16 +
(fs->root_entries * 32 + fs->bytes_per_sector - 1) / fs->bytes_per_sector);
uint32_t cluster_count = data_sectors / fs->sectors_per_cluster;
if (cluster_count < 4085) {
fs->fat_type = FAT_TYPE_FAT12;
fs->sectors_per_fat = bpb.sectors_per_fat_16;
} else if (cluster_count < 65525) {
fs->fat_type = FAT_TYPE_FAT16;
fs->sectors_per_fat = bpb.sectors_per_fat_16;
} else {
fs->fat_type = FAT_TYPE_FAT32;
fs->sectors_per_fat = bpb.sectors_per_fat_32;
fs->root_cluster = bpb.root_cluster;
}
// 计算关键位置
fs->fat_start_sector = fs->reserved_sectors;
fs->root_start_sector = fs->fat_start_sector + fs->fat_count * fs->sectors_per_fat;
if (fs->fat_type == FAT_TYPE_FAT32) {
fs->data_start_sector = fs->root_start_sector;
} else {
uint32_t root_sectors = ((fs->root_entries * 32) + (fs->bytes_per_sector - 1)) / fs->bytes_per_sector;
fs->data_start_sector = fs->root_start_sector + root_sectors;
}
fs->cluster_count = cluster_count;
fs->cluster_size = fs->sectors_per_cluster * fs->bytes_per_sector;
// 初始化FAT缓存
fs->fat_cache = (uint8_t *)malloc(fs->bytes_per_sector);
if (fs->fat_cache == NULL) {
return false;
}
fs->fat_cache_sector = 0xFFFFFFFF;
fs->fat_cache_dirty = false;
// 设置当前目录为根目录
if (fs->fat_type == FAT_TYPE_FAT32) {
fs->current_dir_cluster = fs->root_cluster;
} else {
fs->current_dir_cluster = 0;
}
return true;
}
// 簇号转扇区号
uint32_t cluster_to_sector(fatfs_context_t *fs, uint32_t cluster) {
if (cluster < 2) {
return 0;
}
if (fs->fat_type == FAT_TYPE_FAT32) {
return fs->data_start_sector + (cluster - 2) * fs->sectors_per_cluster;
} else {
return fs->data_start_sector + (cluster - 2) * fs->sectors_per_cluster;
}
}
// 读取FAT表项
uint32_t read_fat_entry(fatfs_context_t *fs, uint32_t cluster) {
if (cluster < 2 || cluster >= fs->cluster_count + 2) {
return 0xFFFFFFFF;
}
uint32_t fat_offset;
uint32_t fat_sector;
uint32_t ent_offset;
switch (fs->fat_type) {
case FAT_TYPE_FAT12:
fat_offset = cluster + (cluster / 2);
break;
case FAT_TYPE_FAT16:
fat_offset = cluster * 2;
break;
case FAT_TYPE_FAT32:
fat_offset = cluster * 4;
break;
default:
return 0xFFFFFFFF;
}
fat_sector = fs->fat_start_sector + (fat_offset / fs->bytes_per_sector);
ent_offset = fat_offset % fs->bytes_per_sector;
// 检查是否需要更新缓存
if (fat_sector != fs->fat_cache_sector) {
// 如果缓存脏,先写回
if (fs->fat_cache_dirty) {
if (!fs->disk->write_sector(fs->fat_cache_sector, fs->fat_cache, 1)) {
return 0xFFFFFFFF;
}
fs->fat_cache_dirty = false;
}
// 读取新的FAT扇区
if (!fs->disk->read_sector(fat_sector, fs->fat_cache, 1)) {
return 0xFFFFFFFF;
}
fs->fat_cache_sector = fat_sector;
}
// 读取表项
uint32_t entry = 0;
switch (fs->fat_type) {
case FAT_TYPE_FAT12:
if (ent_offset == fs->bytes_per_sector - 1) {
// 跨扇区边界
uint8_t next_sector[512];
if (!fs->disk->read_sector(fat_sector + 1, next_sector, 1)) {
return 0xFFFFFFFF;
}
entry = (fs->fat_cache[ent_offset] << 8) | next_sector[0];
} else {
entry = *((uint16_t *)&fs->fat_cache[ent_offset]);
}
if (cluster & 0x01) {
entry >>= 4;
} else {
entry &= 0x0FFF;
}
break;
case FAT_TYPE_FAT16:
entry = *((uint16_t *)&fs->fat_cache[ent_offset]);
break;
case FAT_TYPE_FAT32:
entry = *((uint32_t *)&fs->fat_cache[ent_offset]) & 0x0FFFFFFF;
break;
}
return entry;
}
// 写入FAT表项
bool write_fat_entry(fatfs_context_t *fs, uint32_t cluster, uint32_t value) {
if (cluster < 2 || cluster >= fs->cluster_count + 2) {
return false;
}
uint32_t fat_offset;
uint32_t fat_sector;
uint32_t ent_offset;
switch (fs->fat_type) {
case FAT_TYPE_FAT12:
fat_offset = cluster + (cluster / 2);
break;
case FAT_TYPE_FAT16:
fat_offset = cluster * 2;
break;
case FAT_TYPE_FAT32:
fat_offset = cluster * 4;
break;
default:
return false;
}
fat_sector = fs->fat_start_sector + (fat_offset / fs->bytes_per_sector);
ent_offset = fat_offset % fs->bytes_per_sector;
// 确保缓存的是正确的扇区
if (fat_sector != fs->fat_cache_sector) {
// 如果缓存脏,先写回
if (fs->fat_cache_dirty) {
if (!fs->disk->write_sector(fs->fat_cache_sector, fs->fat_cache, 1)) {
return false;
}
fs->fat_cache_dirty = false;
}
// 读取新的FAT扇区
if (!fs->disk->read_sector(fat_sector, fs->fat_cache, 1)) {
return false;
}
fs->fat_cache_sector = fat_sector;
}
// 写入表项
switch (fs->fat_type) {
case FAT_TYPE_FAT12:
if (ent_offset == fs->bytes_per_sector - 1) {
// 跨扇区边界,需要特殊处理
return false;
} else {
uint16_t *entry = (uint16_t *)&fs->fat_cache[ent_offset];
if (cluster & 0x01) {
*entry = (*entry & 0x000F) | (value << 4);
} else {
*entry = (*entry & 0xF000) | (value & 0x0FFF);
}
}
break;
case FAT_TYPE_FAT16:
*((uint16_t *)&fs->fat_cache[ent_offset]) = (uint16_t)value;
break;
case FAT_TYPE_FAT32:
*((uint32_t *)&fs->fat_cache[ent_offset]) = value & 0x0FFFFFFF;
break;
}
fs->fat_cache_dirty = true;
// 如果是FAT32,可能需要更新备份FAT表
if (fs->fat_type == FAT_TYPE_FAT32 && fs->fat_count > 1) {
// 这里可以添加备份FAT表的更新
}
return true;
}
// 查找空闲簇
uint32_t find_free_cluster(fatfs_context_t *fs) {
uint32_t start_cluster = 2; // 簇号从2开始
uint32_t cluster_count = fs->cluster_count + 2;
for (uint32_t cluster = start_cluster; cluster < cluster_count; cluster++) {
uint32_t entry = read_fat_entry(fs, cluster);
if (entry == 0) {
return cluster;
}
}
return 0; // 没有空闲簇
}
// 分配新簇
uint32_t allocate_cluster(fatfs_context_t *fs, uint32_t prev_cluster) {
uint32_t new_cluster = find_free_cluster(fs);
if (new_cluster == 0) {
return 0;
}
// 标记新簇为已分配的最后一个簇
if (!write_fat_entry(fs, new_cluster, 0xFFFFFFFF)) {
return 0;
}
// 如果存在前一个簇,链接它们
if (prev_cluster >= 2) {
if (!write_fat_entry(fs, prev_cluster, new_cluster)) {
write_fat_entry(fs, new_cluster, 0); // 恢复空闲状态
return 0;
}
}
// 清空新簇
uint32_t sector = cluster_to_sector(fs, new_cluster);
uint8_t *zero_buffer = (uint8_t *)calloc(fs->bytes_per_sector, 1);
if (zero_buffer == NULL) {
return 0;
}
for (uint32_t i = 0; i < fs->sectors_per_cluster; i++) {
if (!fs->disk->write_sector(sector + i, zero_buffer, 1)) {
free(zero_buffer);
return 0;
}
}
free(zero_buffer);
return new_cluster;
}
// 打开文件
bool fatfs_open(fatfs_context_t *fs, const char *path, file_handle_t *file, bool create) {
if (fs == NULL || path == NULL || file == NULL) {
return false;
}
memset(file, 0, sizeof(file_handle_t));
// 解析路径
char *path_copy = strdup(path);
if (path_copy == NULL) {
return false;
}
// 路径解析和目录查找
// ...(简化实现)
free(path_copy);
// 如果文件不存在且需要创建
if (create) {
// 创建新文件
// ...
}
return true;
}
// 读取文件
uint32_t fatfs_read(fatfs_context_t *fs, file_handle_t *file,
void *buffer, uint32_t size) {
if (fs == NULL || file == NULL || buffer == NULL || size == 0) {
return 0;
}
if (file->file_offset >= file->file_size) {
return 0;
}
// 限制读取大小
uint32_t bytes_to_read = size;
if (file->file_offset + bytes_to_read > file->file_size) {
bytes_to_read = file->file_size - file->file_offset;
}
uint32_t bytes_read = 0;
uint8_t *buf_ptr = (uint8_t *)buffer;
while (bytes_read < bytes_to_read) {
// 如果需要,移动到下一个簇
if (file->current_sector == 0 ||
file->sector_offset >= fs->bytes_per_sector) {
// 计算当前簇中的扇区偏移
uint32_t sector_in_cluster = file->sector_offset / fs->bytes_per_sector;
if (sector_in_cluster >= fs->sectors_per_cluster) {
// 需要下一个簇
uint32_t next_cluster = read_fat_entry(fs, file->current_cluster);
if (next_cluster >= 0xFFFFFFF8) { // 最后一个簇
break;
}
file->current_cluster = next_cluster;
file->current_sector = cluster_to_sector(fs, file->current_cluster);
file->sector_offset = 0;
} else {
file->current_sector = cluster_to_sector(fs, file->current_cluster) + sector_in_cluster;
file->sector_offset = 0;
}
}
// 读取当前扇区
uint8_t sector_buffer[512];
if (!fs->disk->read_sector(file->current_sector, sector_buffer, 1)) {
break;
}
// 计算本次可以读取的字节数
uint32_t sector_bytes_remaining = fs->bytes_per_sector - file->sector_offset;
uint32_t bytes_needed = bytes_to_read - bytes_read;
uint32_t bytes_to_copy = (sector_bytes_remaining < bytes_needed) ?
sector_bytes_remaining : bytes_needed;
// 复制数据
memcpy(buf_ptr + bytes_read,
sector_buffer + file->sector_offset,
bytes_to_copy);
bytes_read += bytes_to_copy;
file->sector_offset += bytes_to_copy;
file->file_offset += bytes_to_copy;
}
return bytes_read;
}
// 写入文件
uint32_t fatfs_write(fatfs_context_t *fs, file_handle_t *file,
const void *buffer, uint32_t size) {
if (fs == NULL || file == NULL || buffer == NULL || size == 0) {
return 0;
}
uint32_t bytes_written = 0;
const uint8_t *buf_ptr = (const uint8_t *)buffer;
while (bytes_written < size) {
// 如果需要,分配新簇
if (file->current_cluster == 0) {
// 新文件,分配第一个簇
file->first_cluster = allocate_cluster(fs, 0);
if (file->first_cluster == 0) {
break;
}
file->current_cluster = file->first_cluster;
file->current_sector = cluster_to_sector(fs, file->current_cluster);
file->sector_offset = 0;
}
// 如果需要,移动到下一个簇
if (file->sector_offset >= fs->bytes_per_sector) {
uint32_t sector_in_cluster = file->sector_offset / fs->bytes_per_sector;
if (sector_in_cluster >= fs->sectors_per_cluster) {
// 需要下一个簇
uint32_t next_cluster = read_fat_entry(fs, file->current_cluster);
if (next_cluster >= 0xFFFFFFF8) { // 最后一个簇
// 分配新簇
next_cluster = allocate_cluster(fs, file->current_cluster);
if (next_cluster == 0) {
break;
}
}
file->current_cluster = next_cluster;
file->current_sector = cluster_to_sector(fs, file->current_cluster);
file->sector_offset = 0;
} else {
file->current_sector = cluster_to_sector(fs, file->current_cluster) + sector_in_cluster;
file->sector_offset = 0;
}
}
// 读取当前扇区(如果需要修改部分数据)
uint8_t sector_buffer[512];
if (!fs->disk->read_sector(file->current_sector, sector_buffer, 1)) {
break;
}
// 计算本次可以写入的字节数
uint32_t sector_bytes_remaining = fs->bytes_per_sector - file->sector_offset;
uint32_t bytes_remaining = size - bytes_written;
uint32_t bytes_to_copy = (sector_bytes_remaining < bytes_remaining) ?
sector_bytes_remaining : bytes_remaining;
// 修改数据
memcpy(sector_buffer + file->sector_offset,
buf_ptr + bytes_written,
bytes_to_copy);
// 写回扇区
if (!fs->disk->write_sector(file->current_sector, sector_buffer, 1)) {
break;
}
bytes_written += bytes_to_copy;
file->sector_offset += bytes_to_copy;
file->file_offset += bytes_to_copy;
// 更新文件大小
if (file->file_offset > file->file_size) {
file->file_size = file->file_offset;
}
}
return bytes_written;
}
// 关闭文件
bool fatfs_close(fatfs_context_t *fs, file_handle_t *file) {
if (fs == NULL || file == NULL) {
return false;
}
// 如果需要,更新目录项中的文件大小
if (file->first_cluster != 0) {
// 查找并更新目录项
// ...
}
// 刷新FAT缓存
if (fs->fat_cache_dirty) {
if (!fs->disk->write_sector(fs->fat_cache_sector, fs->fat_cache, 1)) {
return false;
}
fs->fat_cache_dirty = false;
}
return true;
}
// 列出目录
bool fatfs_list_dir(fatfs_context_t *fs, const char *path,
void (*callback)(const char *name, uint8_t attr, uint32_t size)) {
if (fs == NULL || callback == NULL) {
return false;
}
// 查找目录
file_handle_t dir;
if (!fatfs_open(fs, path, &dir, false)) {
return false;
}
if (!dir.is_directory) {
return false;
}
// 读取目录项
fat_dir_entry_t entry;
uint32_t bytes_read;
do {
bytes_read = fatfs_read(fs, &dir, &entry, sizeof(entry));
if (bytes_read == sizeof(entry) && entry.name[0] != 0x00) {
// 跳过空项和删除项
if (entry.name[0] == 0xE5) {
continue;
}
// 跳过卷标项
if (entry.attr == ATTR_VOLUME_ID) {
continue;
}
// 处理长文件名(简化实现,只处理短文件名)
char filename[13];
memset(filename, 0, sizeof(filename));
// 复制文件名
int i;
for (i = 0; i < 8 && entry.name[i] != ' '; i++) {
filename[i] = entry.name[i];
}
// 添加扩展名
if (entry.ext[0] != ' ') {
filename[i++] = '.';
for (int j = 0; j < 3 && entry.ext[j] != ' '; j++) {
filename[i++] = entry.ext[j];
}
}
// 调用回调函数
callback(filename, entry.attr, entry.file_size);
}
} while (bytes_read == sizeof(entry));
fatfs_close(fs, &dir);
return true;
}
// 删除文件
bool fatfs_delete(fatfs_context_t *fs, const char *path) {
if (fs == NULL || path == NULL) {
return false;
}
// 查找文件
file_handle_t file;
if (!fatfs_open(fs, path, &file, false)) {
return false;
}
// 释放簇链
uint32_t cluster = file.first_cluster;
while (cluster < 0xFFFFFFF8) {
uint32_t next_cluster = read_fat_entry(fs, cluster);
write_fat_entry(fs, cluster, 0); // 释放簇
cluster = next_cluster;
}
// 标记目录项为已删除
// ...
fatfs_close(fs, &file);
return true;
}
5.2 日志文件系统
c
/* 日志文件系统实现 */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
// 日志条目类型
typedef enum {
LOG_ENTRY_DATA = 1,
LOG_ENTRY_METADATA = 2,
LOG_ENTRY_COMMIT = 3,
LOG_ENTRY_CHECKPOINT = 4
} log_entry_type_t;
// 日志条目头部
typedef struct {
uint32_t sequence; // 序列号
uint32_t type; // 条目类型
uint32_t length; // 数据长度
uint32_t checksum; // CRC32校验和
uint64_t timestamp; // 时间戳
} log_entry_header_t;
// 日志文件系统上下文
typedef struct {
disk_interface_t *disk;
uint32_t log_start_sector;
uint32_t log_sector_count;
uint32_t data_start_sector;
uint32_t data_sector_count;
uint32_t current_sequence;
uint32_t log_head; // 日志头位置
uint32_t log_tail; // 日志尾位置
bool recovery_needed;
} journal_fs_context_t;
// 计算CRC32校验和
uint32_t crc32_calculate(const uint8_t *data, uint32_t length) {
static const uint32_t crc_table[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
// ... 完整的CRC32表
};
uint32_t crc = 0xFFFFFFFF;
for (uint32_t i = 0; i < length; i++) {
crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF];
}
return crc ^ 0xFFFFFFFF;
}
// 初始化日志文件系统
bool journal_fs_init(journal_fs_context_t *fs, disk_interface_t *disk,
uint32_t log_sectors, uint32_t data_sectors) {
if (fs == NULL || disk == NULL || log_sectors == 0 || data_sectors == 0) {
return false;
}
memset(fs, 0, sizeof(journal_fs_context_t));
fs->disk = disk;
fs->log_sector_count = log_sectors;
fs->data_sector_count = data_sectors;
fs->data_start_sector = log_sectors;
// 检查是否需要恢复
fs->recovery_needed = journal_fs_needs_recovery(fs);
if (fs->recovery_needed) {
if (!journal_fs_recover(fs)) {
return false;
}
}
return true;
}
// 检查是否需要恢复
bool journal_fs_needs_recovery(journal_fs_context_t *fs) {
// 读取日志尾部条目
uint8_t buffer[512];
uint32_t tail_sector = fs->log_start_sector + fs->log_sector_count - 1;
if (!fs->disk->read_sector(tail_sector, buffer, 1)) {
return true;
}
log_entry_header_t *header = (log_entry_header_t *)buffer;
// 检查是否有一个未完成的提交
if (header->type == LOG_ENTRY_COMMIT) {
return false; // 最后一个提交已完成
}
return true; // 需要恢复
}
// 日志恢复
bool journal_fs_recover(journal_fs_context_t *fs) {
if (fs == NULL) {
return false;
}
uint8_t buffer[512];
uint32_t sector = fs->log_start_sector;
uint32_t last_valid_sequence = 0;
uint32_t checkpoint_sequence = 0;
// 扫描日志
while (sector < fs->log_start_sector + fs->log_sector_count) {
if (!fs->disk->read_sector(sector, buffer, 1)) {
break;
}
log_entry_header_t *header = (log_entry_header_t *)buffer;
// 验证校验和
uint32_t calculated_crc = crc32_calculate(buffer + sizeof(log_entry_header_t),
header->length);
if (calculated_crc != header->checksum) {
break; // 校验和错误,停止扫描
}
// 处理条目
switch (header->type) {
case LOG_ENTRY_DATA:
// 在恢复过程中应用数据更新
journal_apply_data_update(fs, header, buffer + sizeof(log_entry_header_t));
break;
case LOG_ENTRY_METADATA:
// 应用元数据更新
journal_apply_metadata_update(fs, header, buffer + sizeof(log_entry_header_t));
break;
case LOG_ENTRY_CHECKPOINT:
checkpoint_sequence = header->sequence;
break;
case LOG_ENTRY_COMMIT:
last_valid_sequence = header->sequence;
break;
}
sector++;
}
// 如果找到一个检查点,从那里开始重放
if (checkpoint_sequence > 0) {
// 重放检查点之后的日志
journal_replay_from_checkpoint(fs, checkpoint_sequence);
}
fs->current_sequence = last_valid_sequence + 1;
fs->log_head = sector;
fs->log_tail = fs->log_start_sector;
return true;
}
// 开始事务
bool journal_begin_transaction(journal_fs_context_t *fs) {
if (fs == NULL) {
return false;
}
// 检查日志空间
uint32_t free_space = journal_get_free_space(fs);
if (free_space < sizeof(log_entry_header_t) + 4) { // 最小空间需求
// 执行检查点
journal_checkpoint(fs);
free_space = journal_get_free_space(fs);
if (free_space < sizeof(log_entry_header_t) + 4) {
return false;
}
}
return true;
}
// 写入数据到日志
bool journal_write_data(journal_fs_context_t *fs, uint32_t data_sector,
const uint8_t *data, uint32_t data_size) {
if (fs == NULL || data == NULL || data_size == 0) {
return false;
}
// 创建数据日志条目
uint32_t entry_size = sizeof(log_entry_header_t) + sizeof(uint32_t) + data_size;
uint8_t *entry_buffer = (uint8_t *)malloc(entry_size);
if (entry_buffer == NULL) {
return false;
}
log_entry_header_t *header = (log_entry_header_t *)entry_buffer;
header->sequence = fs->current_sequence++;
header->type = LOG_ENTRY_DATA;
header->length = sizeof(uint32_t) + data_size;
header->timestamp = get_system_time();
// 写入数据扇区信息
uint32_t *data_sector_ptr = (uint32_t *)(entry_buffer + sizeof(log_entry_header_t));
*data_sector_ptr = data_sector;
// 写入数据
uint8_t *data_ptr = entry_buffer + sizeof(log_entry_header_t) + sizeof(uint32_t);
memcpy(data_ptr, data, data_size);
// 计算校验和
header->checksum = crc32_calculate(entry_buffer + sizeof(log_entry_header_t),
header->length);
// 写入日志
bool success = journal_write_entry(fs, entry_buffer, entry_size);
free(entry_buffer);
return success;
}
// 提交事务
bool journal_commit_transaction(journal_fs_context_t *fs) {
if (fs == NULL) {
return false;
}
// 创建提交条目
log_entry_header_t header;
header.sequence = fs->current_sequence++;
header.type = LOG_ENTRY_COMMIT;
header.length = 0;
header.timestamp = get_system_time();
header.checksum = crc32_calculate(NULL, 0);
// 写入提交条目
return journal_write_entry(fs, (uint8_t *)&header, sizeof(header));
}
// 写入日志条目
bool journal_write_entry(journal_fs_context_t *fs, const uint8_t *entry,
uint32_t entry_size) {
if (fs == NULL || entry == NULL || entry_size == 0) {
return false;
}
uint32_t sectors_needed = (entry_size + fs->disk->sector_size - 1) /
fs->disk->sector_size;
// 检查空间
if (journal_get_free_space(fs) < sectors_needed) {
return false;
}
// 写入条目
uint32_t sector = fs->log_head;
uint32_t bytes_written = 0;
while (bytes_written < entry_size) {
uint8_t sector_buffer[512];
uint32_t bytes_in_sector = fs->disk->sector_size;
if (bytes_written + bytes_in_sector > entry_size) {
bytes_in_sector = entry_size - bytes_written;
}
// 复制数据到扇区缓冲区
memset(sector_buffer, 0, fs->disk->sector_size);
memcpy(sector_buffer, entry + bytes_written, bytes_in_sector);
// 写入扇区
if (!fs->disk->write_sector(sector, sector_buffer, 1)) {
return false;
}
bytes_written += bytes_in_sector;
sector++;
if (sector >= fs->log_start_sector + fs->log_sector_count) {
sector = fs->log_start_sector; // 回绕
}
}
fs->log_head = sector;
// 更新尾部指针(如果需要)
if (fs->log_head == fs->log_tail) {
fs->log_tail++;
if (fs->log_tail >= fs->log_start_sector + fs->log_sector_count) {
fs->log_tail = fs->log_start_sector;
}
}
return true;
}
// 获取空闲空间
uint32_t journal_get_free_space(journal_fs_context_t *fs) {
if (fs == NULL) {
return 0;
}
if (fs->log_head >= fs->log_tail) {
return fs->log_sector_count - (fs->log_head - fs->log_tail) - 1;
} else {
return fs->log_tail - fs->log_head - 1;
}
}
// 创建检查点
bool journal_checkpoint(journal_fs_context_t *fs) {
if (fs == NULL) {
return false;
}
// 创建检查点条目
log_entry_header_t header;
header.sequence = fs->current_sequence++;
header.type = LOG_ENTRY_CHECKPOINT;
header.length = 0;
header.timestamp = get_system_time();
header.checksum = crc32_calculate(NULL, 0);
// 写入检查点
if (!journal_write_entry(fs, (uint8_t *)&header, sizeof(header))) {
return false;
}
// 清空日志(在实际实现中,这里会将所有未提交的更改写入主数据区)
fs->log_tail = fs->log_head;
return true;
}
// 应用数据更新
void journal_apply_data_update(journal_fs_context_t *fs,
const log_entry_header_t *header,
const uint8_t *data) {
if (fs == NULL || header == NULL || data == NULL) {
return;
}
// 解析数据更新
uint32_t data_sector = *((uint32_t *)data);
const uint8_t *update_data = data + sizeof(uint32_t);
uint32_t data_size = header->length - sizeof(uint32_t);
// 写入数据扇区
fs->disk->write_sector(data_sector, update_data,
(data_size + fs->disk->sector_size - 1) /
fs->disk->sector_size);
}
第三部分:系统集成与优化
第6章 低功耗管理
6.1 电源管理单元
c
/* 低功耗电源管理实现 */
#include <stdint.h>
#include <stdbool.h>
// 电源模式
typedef enum {
POWER_MODE_RUN = 0, // 运行模式
POWER_MODE_SLEEP = 1, // 睡眠模式
POWER_MODE_STOP = 2, // 停止模式
POWER_MODE_STANDBY = 3, // 待机模式
POWER_MODE_SHUTDOWN = 4 // 关机模式
} power_mode_t;
// 功耗统计
typedef struct {
uint32_t total_energy; // 总能耗(微焦)
uint32_t run_time; // 运行时间(毫秒)
uint32_t sleep_time; // 睡眠时间(毫秒)
uint32_t stop_time; // 停止时间(毫秒)
uint32_t standby_time; // 待机时间(毫秒)
uint32_t wakeup_count; // 唤醒次数
uint32_t voltage_mv; // 当前电压(毫伏)
uint32_t current_ua; // 当前电流(微安)
} power_statistics_t;
// 电源管理配置
typedef struct {
uint32_t run_current_ua; // 运行模式电流
uint32_t sleep_current_ua; // 睡眠模式电流
uint32_t stop_current_ua; // 停止模式电流
uint32_t standby_current_ua;// 待机模式电流
uint32_t wakeup_latency_ms; // 唤醒延迟
bool enable_dynamic_voltage_scaling;
bool enable_clock_gating;
bool enable_peripheral_power_gating;
} power_config_t;
// 电源管理上下文
typedef struct {
power_mode_t current_mode;
power_mode_t requested_mode;
power_config_t config;
power_statistics_t stats;
uint32_t mode_enter_time;
void (*wakeup_callback)(void);
void (*sleep_callback)(void);
} power_manager_t;
// 电源管理初始化
bool power_manager_init(power_manager_t *pm, const power_config_t *config) {
if (pm == NULL || config == NULL) {
return false;
}
memset(pm, 0, sizeof(power_manager_t));
pm->config = *config;
pm->current_mode = POWER_MODE_RUN;
pm->requested_mode = POWER_MODE_RUN;
// 初始化功耗统计
pm->stats.voltage_mv = 3300; // 默认3.3V
pm->stats.current_ua = pm->config.run_current_ua;
return true;
}
// 进入低功耗模式
bool power_enter_low_power(power_manager_t *pm, power_mode_t mode) {
if (pm == NULL) {
return false;
}
// 验证模式转换是否允许
if (!power_validate_mode_transition(pm->current_mode, mode)) {
return false;
}
// 调用睡眠回调
if (pm->sleep_callback != NULL) {
pm->sleep_callback();
}
// 记录进入时间
pm->mode_enter_time = get_system_ticks();
// 执行模式切换
switch (mode) {
case POWER_MODE_SLEEP:
enter_sleep_mode();
break;
case POWER_MODE_STOP:
enter_stop_mode();
break;
case POWER_MODE_STANDBY:
enter_standby_mode();
break;
case POWER_MODE_SHUTDOWN:
enter_shutdown_mode();
break;
default:
return false;
}
// 更新统计
uint32_t time_in_mode = get_system_ticks() - pm->mode_enter_time;
power_update_statistics(pm, pm->current_mode, time_in_mode);
// 更新当前模式
pm->current_mode = mode;
pm->stats.wakeup_count++;
return true;
}
// 从低功耗模式唤醒
void power_wakeup(power_manager_t *pm) {
if (pm == NULL) {
return;
}
// 记录模式退出时间
uint32_t time_in_mode = get_system_ticks() - pm->mode_enter_time;
// 更新统计
power_update_statistics(pm, pm->current_mode, time_in_mode);
// 切换到运行模式
pm->current_mode = POWER_MODE_RUN;
// 调用唤醒回调
if (pm->wakeup_callback != NULL) {
pm->wakeup_callback();
}
}
// 更新功耗统计
void power_update_statistics(power_manager_t *pm, power_mode_t mode, uint32_t duration_ms) {
if (pm == NULL) {
return;
}
// 计算能耗:E = U * I * t
uint32_t current_ua = 0;
switch (mode) {
case POWER_MODE_RUN:
current_ua = pm->config.run_current_ua;
pm->stats.run_time += duration_ms;
break;
case POWER_MODE_SLEEP:
current_ua = pm->config.sleep_current_ua;
pm->stats.sleep_time += duration_ms;
break;
case POWER_MODE_STOP:
current_ua = pm->config.stop_current_ua;
pm->stats.stop_time += duration_ms;
break;
case POWER_MODE_STANDBY:
current_ua = pm->config.standby_current_ua;
pm->stats.standby_time += duration_ms;
break;
default:
break;
}
// 计算能耗(微焦)
uint32_t energy_uj = (pm->stats.voltage_mv * current_ua * duration_ms) / 1000;
pm->stats.total_energy += energy_uj;
pm->stats.current_ua = current_ua;
}
// 验证模式转换
bool power_validate_mode_transition(power_mode_t from, power_mode_t to) {
// 定义允许的模式转换
switch (from) {
case POWER_MODE_RUN:
return (to == POWER_MODE_SLEEP ||
to == POWER_MODE_STOP ||
to == POWER_MODE_STANDBY ||
to == POWER_MODE_SHUTDOWN);
case POWER_MODE_SLEEP:
return (to == POWER_MODE_RUN);
case POWER_MODE_STOP:
return (to == POWER_MODE_RUN);
case POWER_MODE_STANDBY:
return (to == POWER_MODE_RUN);
case POWER_MODE_SHUTDOWN:
return false; // 关机后无法直接切换到其他模式
default:
return false;
}
}
// 动态电压频率调整
typedef struct {
uint32_t frequency_hz;
uint32_t voltage_mv;
uint32_t power_mw;
} dvfs_point_t;
// DVFS表
static const dvfs_point_t dvfs_table[] = {
{8000000, 1200, 10}, // 8MHz @ 1.2V
{16000000, 1300, 25}, // 16MHz @ 1.3V
{32000000, 1400, 60}, // 32MHz @ 1.4V
{48000000, 1500, 120}, // 48MHz @ 1.5V
{72000000, 1600, 200}, // 72MHz @ 1.6V
};
// DVFS管理器
typedef struct {
uint32_t current_frequency;
uint32_t current_voltage;
uint32_t target_frequency;
bool dvfs_enabled;
uint32_t load_threshold_low; // 负载阈值下限
uint32_t load_threshold_high; // 负载阈值上限
uint32_t update_interval_ms;
uint32_t last_update_time;
} dvfs_manager_t;
// 调整频率和电压
bool dvfs_adjust(dvfs_manager_t *dvfs, uint32_t target_frequency) {
if (dvfs == NULL || target_frequency == 0) {
return false;
}
// 查找合适的DVFS点
const dvfs_point_t *point = NULL;
for (uint32_t i = 0; i < sizeof(dvfs_table)/sizeof(dvfs_table[0]); i++) {
if (dvfs_table[i].frequency_hz >= target_frequency) {
point = &dvfs_table[i];
break;
}
}
if (point == NULL) {
return false;
}
// 调整电压(如果支持)
if (dvfs->current_voltage != point->voltage_mv) {
if (!power_set_voltage(point->voltage_mv)) {
return false;
}
dvfs->current_voltage = point->voltage_mv;
delay_ms(1); // 等待电压稳定
}
// 调整频率
if (!clock_set_frequency(point->frequency_hz)) {
return false;
}
dvfs->current_frequency = point->frequency_hz;
return true;
}
// DVFS控制线程
void dvfs_control_thread(void *arg) {
dvfs_manager_t *dvfs = (dvfs_manager_t *)arg;
if (dvfs == NULL) {
return;
}
while (1) {
// 等待更新间隔
delay_ms(dvfs->update_interval_ms);
if (!dvfs->dvfs_enabled) {
continue;
}
// 计算系统负载
uint32_t cpu_load = get_cpu_load_percentage();
// 决定目标频率
uint32_t target_freq = dvfs->current_frequency;
if (cpu_load < dvfs->load_threshold_low) {
// 负载低,降频
target_freq = find_lower_frequency(dvfs->current_frequency);
} else if (cpu_load > dvfs->load_threshold_high) {
// 负载高,升频
target_freq = find_higher_frequency(dvfs->current_frequency);
}
// 如果需要调整
if (target_freq != dvfs->current_frequency) {
dvfs_adjust(dvfs, target_freq);
}
}
}
// 时钟门控管理
typedef struct {
uint32_t peripheral_mask; // 外设位掩码
uint32_t enabled_peripherals; // 已启用的外设
uint32_t clock_gates; // 时钟门控寄存器值
} clock_gating_manager_t;
// 启用外设时钟
void clock_enable_peripheral(clock_gating_manager_t *cg, uint32_t peripheral) {
if (cg == NULL || (peripheral & cg->peripheral_mask) == 0) {
return;
}
DISABLE_INTERRUPTS();
if ((cg->enabled_peripherals & peripheral) == 0) {
// 启用时钟
uint32_t gate_bit = peripheral_to_gate_bit(peripheral);
cg->clock_gates |= (1 << gate_bit);
write_clock_gate_register(cg->clock_gates);
cg->enabled_peripherals |= peripheral;
// 等待时钟稳定
delay_us(10);
}
ENABLE_INTERRUPTS();
}
// 禁用外设时钟
void clock_disable_peripheral(clock_gating_manager_t *cg, uint32_t peripheral) {
if (cg == NULL || (peripheral & cg->peripheral_mask) == 0) {
return;
}
DISABLE_INTERRUPTS();
if ((cg->enabled_peripherals & peripheral) != 0) {
// 禁用时钟
uint32_t gate_bit = peripheral_to_gate_bit(peripheral);
cg->clock_gates &= ~(1 << gate_bit);
write_clock_gate_register(cg->clock_gates);
cg->enabled_peripherals &= ~peripheral;
}
ENABLE_INTERRUPTS();
}
// 电源门控管理
typedef struct {
uint32_t power_domain_mask; // 电源域位掩码
uint32_t powered_domains; // 已上电的电源域
uint32_t retention_states; // 保持状态
} power_gating_manager_t;
// 电源域上电
bool power_domain_power_up(power_gating_manager_t *pg, uint32_t domain) {
if (pg == NULL || (domain & pg->power_domain_mask) == 0) {
return false;
}
if ((pg->powered_domains & domain) != 0) {
return true; // 已经上电
}
DISABLE_INTERRUPTS();
// 上电序列
if (!power_sequence_power_up(domain)) {
ENABLE_INTERRUPTS();
return false;
}
// 等待电源稳定
delay_ms(1);
// 恢复保持状态(如果存在)
if ((pg->retention_states & domain) != 0) {
if (!power_restore_retention(domain)) {
// 上电失败,掉电
power_sequence_power_down(domain);
ENABLE_INTERRUPTS();
return false;
}
}
pg->powered_domains |= domain;
pg->retention_states &= ~domain;
ENABLE_INTERRUPTS();
return true;
}
// 电源域掉电
bool power_domain_power_down(power_gating_manager_t *pg, uint32_t domain, bool retain_state) {
if (pg == NULL || (domain & pg->power_domain_mask) == 0) {
return false;
}
if ((pg->powered_domains & domain) == 0) {
return true; // 已经掉电
}
DISABLE_INTERRUPTS();
// 保存状态(如果需要)
if (retain_state) {
if (!power_save_retention(domain)) {
ENABLE_INTERRUPTS();
return false;
}
pg->retention_states |= domain;
}
// 掉电序列
if (!power_sequence_power_down(domain)) {
ENABLE_INTERRUPTS();
return false;
}
pg->powered_domains &= ~domain;
ENABLE_INTERRUPTS();
return true;
}
// 唤醒源管理
typedef struct {
uint32_t wakeup_source_mask;
uint32_t enabled_sources;
void (*wakeup_handler)(uint32_t source);
} wakeup_source_manager_t;
// 配置唤醒源
bool wakeup_source_configure(wakeup_source_manager_t *ws,
uint32_t source,
bool enable,
uint32_t polarity) {
if (ws == NULL || (source & ws->wakeup_source_mask) == 0) {
return false;
}
DISABLE_INTERRUPTS();
if (enable) {
// 配置唤醒源极性
if (!configure_wakeup_polarity(source, polarity)) {
ENABLE_INTERRUPTS();
return false;
}
// 启用唤醒源
if (!enable_wakeup_source(source)) {
ENABLE_INTERRUPTS();
return false;
}
ws->enabled_sources |= source;
} else {
// 禁用唤醒源
if (!disable_wakeup_source(source)) {
ENABLE_INTERRUPTS();
return false;
}
ws->enabled_sources &= ~source;
}
ENABLE_INTERRUPTS();
return true;
}
// 处理唤醒事件
void handle_wakeup_event(wakeup_source_manager_t *ws) {
if (ws == NULL) {
return;
}
uint32_t wakeup_source = read_wakeup_status();
// 清除唤醒标志
clear_wakeup_status(wakeup_source);
// 调用唤醒处理函数
if (ws->wakeup_handler != NULL) {
ws->wakeup_handler(wakeup_source);
}
}
// 功耗优化策略
typedef struct {
uint32_t idle_timeout_ms; // 进入空闲超时
uint32_t sleep_timeout_ms; // 进入睡眠超时
uint32_t stop_timeout_ms; // 进入停止超时
uint32_t check_interval_ms; // 检查间隔
bool aggressive_power_saving; // 积极节能模式
} power_policy_t;
// 电源策略管理器
typedef struct {
power_policy_t policy;
power_manager_t *power_mgr;
uint32_t last_activity_time;
uint32_t idle_start_time;
bool in_idle_state;
} power_policy_manager_t;
// 电源策略线程
void power_policy_thread(void *arg) {
power_policy_manager_t *ppm = (power_policy_manager_t *)arg;
if (ppm == NULL || ppm->power_mgr == NULL) {
return;
}
while (1) {
uint32_t current_time = get_system_ticks();
uint32_t idle_duration = current_time - ppm->last_activity_time;
// 检查是否需要进入低功耗模式
if (idle_duration >= ppm->policy.stop_timeout_ms) {
// 进入停止模式
if (ppm->power_mgr->current_mode != POWER_MODE_STOP) {
power_enter_low_power(ppm->power_mgr, POWER_MODE_STOP);
}
} else if (idle_duration >= ppm->policy.sleep_timeout_ms) {
// 进入睡眠模式
if (ppm->power_mgr->current_mode != POWER_MODE_SLEEP) {
power_enter_low_power(ppm->power_mgr, POWER_MODE_SLEEP);
}
} else if (idle_duration >= ppm->policy.idle_timeout_ms) {
// 进入空闲模式
if (!ppm->in_idle_state) {
ppm->in_idle_state = true;
ppm->idle_start_time = current_time;
enter_idle_mode();
}
} else {
// 活动状态
if (ppm->in_idle_state) {
ppm->in_idle_state = false;
exit_idle_mode();
}
}
delay_ms(ppm->policy.check_interval_ms);
}
}
// 记录活动
void power_record_activity(power_policy_manager_t *ppm) {
if (ppm == NULL) {
return;
}
ppm->last_activity_time = get_system_ticks();
// 如果当前在低功耗模式,唤醒系统
if (ppm->power_mgr->current_mode != POWER_MODE_RUN) {
power_wakeup(ppm->power_mgr);
}
}
// 电池管理
typedef struct {
uint32_t voltage_mv; // 当前电压
uint32_t capacity_mah; // 电池容量
uint32_t remaining_capacity_mah; // 剩余容量
uint32_t charge_state; // 充电状态
uint32_t health_percentage; // 电池健康度
uint32_t temperature_c; // 电池温度
uint32_t charge_current_ma; // 充电电流
uint32_t discharge_current_ma;// 放电电流
} battery_info_t;
// 电池管理器
typedef struct {
battery_info_t info;
uint32_t update_interval_ms;
uint32_t last_update_time;
void (*low_battery_callback)(uint32_t voltage);
void (*charging_callback)(bool charging);
void (*over_temperature_callback)(uint32_t temperature);
} battery_manager_t;
// 更新电池信息
bool battery_update_info(battery_manager_t *bm) {
if (bm == NULL) {
return false;
}
uint32_t current_time = get_system_ticks();
if (current_time - bm->last_update_time < bm->update_interval_ms) {
return true;
}
// 读取电池电压
uint32_t voltage = read_battery_voltage();
bm->info.voltage_mv = voltage;
// 读取充电状态
bm->info.charge_state = read_charge_state();
// 读取电池温度
bm->info.temperature_c = read_battery_temperature();
// 计算剩余容量(简化实现)
bm->info.remaining_capacity_mah = estimate_remaining_capacity(voltage);
// 计算电池健康度
bm->info.health_percentage = calculate_battery_health(bm->info.remaining_capacity_mah,
bm->info.capacity_mah);
// 检查低电量
if (voltage < LOW_BATTERY_THRESHOLD_MV) {
if (bm->low_battery_callback != NULL) {
bm->low_battery_callback(voltage);
}
}
// 检查过温
if (bm->info.temperature_c > OVER_TEMP_THRESHOLD_C) {
if (bm->over_temperature_callback != NULL) {
bm->over_temperature_callback(bm->info.temperature_c);
}
}
bm->last_update_time = current_time;
return true;
}
// 电源管理综合示例
typedef struct {
power_manager_t power_mgr;
dvfs_manager_t dvfs_mgr;
clock_gating_manager_t clock_gating_mgr;
power_gating_manager_t power_gating_mgr;
wakeup_source_manager_t wakeup_mgr;
power_policy_manager_t policy_mgr;
battery_manager_t battery_mgr;
uint32_t system_load;
uint32_t performance_level;
bool power_saving_enabled;
} system_power_manager_t;
// 系统电源管理初始化
bool system_power_manager_init(system_power_manager_t *spm) {
if (spm == NULL) {
return false;
}
memset(spm, 0, sizeof(system_power_manager_t));
// 初始化各组件
power_config_t power_cfg = {
.run_current_ua = 20000,
.sleep_current_ua = 5000,
.stop_current_ua = 1000,
.standby_current_ua = 100,
.wakeup_latency_ms = 10,
.enable_dynamic_voltage_scaling = true,
.enable_clock_gating = true,
.enable_peripheral_power_gating = true
};
if (!power_manager_init(&spm->power_mgr, &power_cfg)) {
return false;
}
// 初始化DVFS
spm->dvfs_mgr.current_frequency = 8000000;
spm->dvfs_mgr.current_voltage = 1200;
spm->dvfs_mgr.dvfs_enabled = true;
spm->dvfs_mgr.load_threshold_low = 30;
spm->dvfs_mgr.load_threshold_high = 70;
spm->dvfs_mgr.update_interval_ms = 100;
// 初始化电源策略
spm->policy_mgr.policy.idle_timeout_ms = 1000;
spm->policy_mgr.policy.sleep_timeout_ms = 5000;
spm->policy_mgr.policy.stop_timeout_ms = 30000;
spm->policy_mgr.policy.check_interval_ms = 100;
spm->policy_mgr.power_mgr = &spm->power_mgr;
spm->power_saving_enabled = true;
return true;
}
// 系统电源管理主循环
void system_power_manager_run(system_power_manager_t *spm) {
if (spm == NULL) {
return;
}
while (1) {
// 更新系统负载
spm->system_load = calculate_system_load();
// 根据负载调整性能等级
if (spm->power_saving_enabled) {
adjust_performance_level(spm);
}
// 更新电池信息
battery_update_info(&spm->battery_mgr);
// 处理电源事件
handle_power_events(spm);
delay_ms(100);
}
}
// 调整性能等级
void adjust_performance_level(system_power_manager_t *spm) {
if (spm == NULL) {
return;
}
uint32_t new_performance_level = spm->performance_level;
if (spm->system_load < 20) {
new_performance_level = 0; // 最低性能
} else if (spm->system_load < 50) {
new_performance_level = 1; // 低性能
} else if (spm->system_load < 80) {
new_performance_level = 2; // 中等性能
} else {
new_performance_level = 3; // 高性能
}
if (new_performance_level != spm->performance_level) {
apply_performance_level(spm, new_performance_level);
spm->performance_level = new_performance_level;
}
}
// 应用性能等级
void apply_performance_level(system_power_manager_t *spm, uint32_t level) {
if (spm == NULL) {
return;
}
uint32_t target_frequency = 0;
switch (level) {
case 0: // 最低性能
target_frequency = 8000000; // 8MHz
break;
case 1: // 低性能
target_frequency = 16000000; // 16MHz
break;
case 2: // 中等性能
target_frequency = 32000000; // 32MHz
break;
case 3: // 高性能
target_frequency = 72000000; // 72MHz
break;
}
// 调整DVFS
dvfs_adjust(&spm->dvfs_mgr, target_frequency);
// 根据性能等级调整外设电源
adjust_peripheral_power(spm, level);
}
// 调整外设电源
void adjust_peripheral_power(system_power_manager_t *spm, uint32_t level) {
if (spm == NULL) {
return;
}
// 根据性能等级决定哪些外设可以关闭
uint32_t peripherals_to_disable = 0;
switch (level) {
case 0: // 最低性能
// 关闭所有非关键外设
peripherals_to_disable = PERIPH_ALL & ~PERIPH_CRITICAL;
break;
case 1: // 低性能
// 关闭部分外设
peripherals_to_disable = PERIPH_LOW_PRIORITY;
break;
case 2: // 中等性能
// 保持所有外设开启
peripherals_to_disable = 0;
break;
case 3: // 高性能
// 所有外设都开启
peripherals_to_disable = 0;
break;
}
// 应用外设电源设置
apply_peripheral_power_settings(peripherals_to_disable);
}
第7章 实时时钟与时间管理
7.1 硬件RTC驱动
c
/* 实时时钟驱动实现 */
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
// RTC寄存器结构
typedef struct {
volatile uint32_t CRH; // 控制寄存器高
volatile uint32_t CRL; // 控制寄存器低
volatile uint32_t PRLH; // 预分频器高
volatile uint32_t PRLL; // 预分频器低
volatile uint32_t DIVH; // 预分频器余数高
volatile uint32_t DIVL; // 预分频器余数低
volatile uint32_t CNTH; // 计数器高
volatile uint32_t CNTL; // 计数器低
volatile uint32_t ALRH; // 闹钟高
volatile uint32_t ALRL; // 闹钟低
} RTC_TypeDef;
// RTC实例
#define RTC_BASE 0x40002800UL
#define RTC ((RTC_TypeDef *)RTC_BASE)
// 时间结构
typedef struct {
uint8_t year; // 年份(0-99,表示2000-2099)
uint8_t month; // 月份(1-12)
uint8_t day; // 日期(1-31)
uint8_t weekday; // 星期(0-6,0=周日)
uint8_t hour; // 小时(0-23)
uint8_t minute; // 分钟(0-59)
uint8_t second; // 秒(0-59)
uint16_t subsecond; // 亚秒(0-999)
} rtc_time_t;
// 闹钟结构
typedef struct {
rtc_time_t time;
uint32_t alarm_mask; // 闹钟掩码
bool enabled;
void (*callback)(void);
} rtc_alarm_t;
// RTC驱动结构
typedef struct {
RTC_TypeDef *instance;
rtc_time_t current_time;
rtc_alarm_t alarms[4]; // 最多4个闹钟
bool initialized;
uint32_t backup_registers[20]; // 备份寄存器
void (*second_callback)(void);
void (*alarm_callback)(uint8_t alarm_num);
} rtc_driver_t;
// RTC初始化
bool rtc_init(rtc_driver_t *rtc, uint32_t clock_source) {
if (rtc == NULL) {
return false;
}
// 检查RTC是否已初始化
if (rtc->initialized) {
return true;
}
rtc->instance = RTC;
memset(&rtc->current_time, 0, sizeof(rtc_time_t));
memset(rtc->alarms, 0, sizeof(rtc_alarm_t) * 4);
rtc->initialized = false;
rtc->second_callback = NULL;
rtc->alarm_callback = NULL;
// 使能PWR和BKP时钟
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
// 使能备份域访问
PWR->CR |= PWR_CR_DBP;
// 复位备份域
BKP->CR |= BKP_CR_TCE;
BKP->CR &= ~BKP_CR_TCE;
// 选择RTC时钟源
switch (clock_source) {
case RTC_CLOCK_LSE: // LSE 32.768KHz
RCC->BDCR |= RCC_BDCR_LSEON;
while (!(RCC->BDCR & RCC_BDCR_LSERDY));
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;
break;
case RTC_CLOCK_LSI: // LSI ~40KHz
RCC->CSR |= RCC_CSR_LSION;
while (!(RCC->CSR & RCC_CSR_LSIRDY));
RCC->BDCR |= RCC_BDCR_RTCSEL_LSI;
break;
case RTC_CLOCK_HSE: // HSE分频
RCC->BDCR |= RCC_BDCR_RTCSEL_HSE;
break;
default:
return false;
}
// 使能RTC时钟
RCC->BDCR |= RCC_BDCR_RTCEN;
// 进入配置模式
rtc_enter_config_mode();
// 配置预分频器
// 对于32.768KHz时钟,预分频器设置为:
// PRLH = 0, PRLL = 32767 (0x7FFF)
// 这样得到1Hz的时钟
RTC->PRLH = 0;
RTC->PRLL = 32767;
// 设置初始时间(可选)
// rtc_set_time(rtc, &initial_time);
// 退出配置模式
rtc_exit_config_mode();
// 等待同步
while (!rtc_is_synchronized());
rtc->initialized = true;
// 配置RTC中断
rtc_configure_interrupts();
return true;
}
// 进入配置模式
void rtc_enter_config_mode(void) {
// 等待寄存器同步
while (!(RTC->CRL & RTC_CRL_RTOFF));
// 进入配置模式
RTC->CRL |= RTC_CRL_CNF;
}
// 退出配置模式
void rtc_exit_config_mode(void) {
// 退出配置模式
RTC->CRL &= ~RTC_CRL_CNF;
// 等待操作完成
while (!(RTC->CRL & RTC_CRL_RTOFF));
}
// 检查同步状态
bool rtc_is_synchronized(void) {
return (RTC->CRL & RTC_CRL_RSF) != 0;
}
// 设置时间
bool rtc_set_time(rtc_driver_t *rtc, const rtc_time_t *time) {
if (rtc == NULL || time == NULL || !rtc->initialized) {
return false;
}
// 验证时间有效性
if (!rtc_validate_time(time)) {
return false;
}
// 进入配置模式
rtc_enter_config_mode();
// 转换时间为计数器值
uint32_t counter = rtc_time_to_counter(time);
// 设置计数器
RTC->CNTL = counter & 0xFFFF;
RTC->CNTH = (counter >> 16) & 0xFFFF;
// 退出配置模式
rtc_exit_config_mode();
// 更新本地时间
memcpy(&rtc->current_time, time, sizeof(rtc_time_t));
return true;
}
// 获取时间
bool rtc_get_time(rtc_driver_t *rtc, rtc_time_t *time) {
if (rtc == NULL || time == NULL || !rtc->initialized) {
return false;
}
// 等待寄存器同步
while (!rtc_is_synchronized());
// 读取计数器
uint32_t counter = (RTC->CNTH << 16) | RTC->CNTL;
// 转换计数器为时间
rtc_counter_to_time(counter, time);
// 读取亚秒
time->subsecond = 999 - ((RTC->DIVH << 16) | RTC->DIVL);
return true;
}
// 设置闹钟
bool rtc_set_alarm(rtc_driver_t *rtc, uint8_t alarm_num,
const rtc_alarm_t *alarm) {
if (rtc == NULL || alarm == NULL || alarm_num >= 4 || !rtc->initialized) {
return false;
}
// 验证时间有效性
if (!rtc_validate_time(&alarm->time)) {
return false;
}
// 进入配置模式
rtc_enter_config_mode();
// 转换时间为计数器值
uint32_t alarm_counter = rtc_time_to_counter(&alarm->time);
// 设置闹钟寄存器
switch (alarm_num) {
case 0:
RTC->ALRL = alarm_counter & 0xFFFF;
RTC->ALRH = (alarm_counter >> 16) & 0xFFFF;
break;
case 1:
// 使用备份寄存器存储第二个闹钟
BKP->DR1 = alarm_counter;
break;
default:
// 存储到软件闹钟数组
break;
}
// 退出配置模式
rtc_exit_config_mode();
// 更新闹钟配置
memcpy(&rtc->alarms[alarm_num], alarm, sizeof(rtc_alarm_t));
// 配置闹钟中断
rtc_configure_alarm_interrupt(alarm_num, alarm->enabled);
return true;
}
// 时间转换函数
uint32_t rtc_time_to_counter(const rtc_time_t *time) {
// 计算从2000-01-01 00:00:00开始的秒数
uint32_t days = rtc_calculate_days_since_2000(time->year, time->month, time->day);
uint32_t seconds = days * 86400 +
time->hour * 3600 +
time->minute * 60 +
time->second;
return seconds;
}
void rtc_counter_to_time(uint32_t counter, rtc_time_t *time) {
// 计算总天数
uint32_t days = counter / 86400;
uint32_t seconds_in_day = counter % 86400;
// 计算年、月、日
rtc_calculate_date_from_days(days, &time->year, &time->month, &time->day);
// 计算时间
time->hour = seconds_in_day / 3600;
time->minute = (seconds_in_day % 3600) / 60;
time->second = seconds_in_day % 60;
// 计算星期
time->weekday = rtc_calculate_weekday(days);
}
// 天数计算
uint32_t rtc_calculate_days_since_2000(uint8_t year, uint8_t month, uint8_t day) {
uint32_t days = 0;
// 加上之前年份的天数
for (uint8_t y = 0; y < year; y++) {
days += rtc_is_leap_year(2000 + y) ? 366 : 365;
}
// 加上之前月份的天数
for (uint8_t m = 1; m < month; m++) {
days += rtc_days_in_month(m, rtc_is_leap_year(2000 + year));
}
// 加上天数
days += day - 1;
return days;
}
// 从天数计算日期
void rtc_calculate_date_from_days(uint32_t days, uint8_t *year, uint8_t *month, uint8_t *day) {
uint32_t remaining_days = days;
uint8_t y = 0;
// 计算年份
while (remaining_days >= (rtc_is_leap_year(2000 + y) ? 366 : 365)) {
remaining_days -= rtc_is_leap_year(2000 + y) ? 366 : 365;
y++;
}
*year = y;
// 计算月份
bool leap_year = rtc_is_leap_year(2000 + y);
uint8_t m = 1;
while (remaining_days >= rtc_days_in_month(m, leap_year)) {
remaining_days -= rtc_days_in_month(m, leap_year);
m++;
}
*month = m;
*day = remaining_days + 1;
}
// 计算星期
uint8_t rtc_calculate_weekday(uint32_t days_since_2000) {
// 2000-01-01是星期六
return (days_since_2000 + 6) % 7;
}
// 闰年判断
bool rtc_is_leap_year(uint16_t year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
// 月份天数
uint8_t rtc_days_in_month(uint8_t month, bool leap_year) {
static const uint8_t days_in_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
if (month == 2 && leap_year) {
return 29;
}
if (month >= 1 && month <= 12) {
return days_in_month[month - 1];
}
return 0;
}
// 验证时间
bool rtc_validate_time(const rtc_time_t *time) {
if (time == NULL) {
return false;
}
// 检查范围
if (time->year > 99 ||
time->month < 1 || time->month > 12 ||
time->day < 1 || time->day > 31 ||
time->weekday > 6 ||
time->hour > 23 ||
time->minute > 59 ||
time->second > 59) {
return false;
}
// 检查月份天数
bool leap_year = rtc_is_leap_year(2000 + time->year);
uint8_t max_days = rtc_days_in_month(time->month, leap_year);
if (time->day > max_days) {
return false;
}
return true;
}
// RTC中断处理
void RTC_IRQHandler(void) {
if (RTC->CRL & RTC_CRL_SECF) {
// 秒中断
RTC->CRL &= ~RTC_CRL_SECF;
// 更新本地时间
rtc_update_local_time();
// 调用回调函数
if (g_rtc_driver.second_callback != NULL) {
g_rtc_driver.second_callback();
}
}
if (RTC->CRL & RTC_CRL_ALRF) {
// 闹钟中断
RTC->CRL &= ~RTC_CRL_ALRF;
// 确定哪个闹钟触发
uint8_t triggered_alarm = rtc_find_triggered_alarm();
// 调用回调函数
if (g_rtc_driver.alarm_callback != NULL) {
g_rtc_driver.alarm_callback(triggered_alarm);
}
if (triggered_alarm < 4 && g_rtc_driver.alarms[triggered_alarm].callback != NULL) {
g_rtc_driver.alarms[triggered_alarm].callback();
}
}
}
// 时间戳管理
typedef struct {
uint32_t start_tick; // 启动时的tick值
uint32_t overflow_count; // 溢出计数
uint32_t last_tick; // 最后记录的tick值
bool initialized;
} timestamp_manager_t;
// 获取高分辨率时间戳
uint64_t get_high_res_timestamp(timestamp_manager_t *tm) {
if (tm == NULL || !tm->initialized) {
return 0;
}
DISABLE_INTERRUPTS();
uint32_t current_tick = get_system_tick();
// 检查是否溢出
if (current_tick < tm->last_tick) {
tm->overflow_count++;
}
tm->last_tick = current_tick;
uint64_t timestamp = ((uint64_t)tm->overflow_count << 32) | current_tick;
ENABLE_INTERRUPTS();
return timestamp;
}
// 时间戳转换
uint64_t timestamp_to_nanoseconds(timestamp_manager_t *tm, uint64_t timestamp) {
if (tm == NULL) {
return 0;
}
// 假设系统tick频率为1MHz
const uint64_t tick_frequency = 1000000; // 1MHz
const uint64_t nanoseconds_per_tick = 1000000000 / tick_frequency; // 1000ns
return timestamp * nanoseconds_per_tick;
}
// 时间间隔测量
typedef struct {
uint64_t start_time;
uint64_t end_time;
uint64_t elapsed_time;
bool measuring;
} time_interval_t;
// 开始测量
void time_interval_start(time_interval_t *ti, timestamp_manager_t *tm) {
if (ti == NULL || tm == NULL) {
return;
}
ti->start_time = get_high_res_timestamp(tm);
ti->measuring = true;
}
// 停止测量
void time_interval_stop(time_interval_t *ti, timestamp_manager_t *tm) {
if (ti == NULL || tm == NULL || !ti->measuring) {
return;
}
ti->end_time = get_high_res_timestamp(tm);
ti->elapsed_time = ti->end_time - ti->start_time;
ti->measuring = false;
}
// 获取经过的时间(纳秒)
uint64_t time_interval_get_nanoseconds(time_interval_t *ti, timestamp_manager_t *tm) {
if (ti == NULL || tm == NULL) {
return 0;
}
return timestamp_to_nanoseconds(tm, ti->elapsed_time);
}
// 时间同步协议(简化NTP)
typedef struct {
uint32_t local_timestamp; // 本地时间戳
uint32_t remote_timestamp; // 远程时间戳
uint32_t round_trip_delay; // 往返延迟
int32_t clock_offset; // 时钟偏移
uint32_t sync_interval; // 同步间隔
uint32_t last_sync_time; // 上次同步时间
bool synchronized; // 是否已同步
} time_sync_context_t;
// 时间同步
bool time_synchronize(time_sync_context_t *ts,
uint32_t request_time,
uint32_t response_time) {
if (ts == NULL) {
return false;
}
// 计算时钟偏移和往返延迟
uint32_t t1 = ts->local_timestamp; // 请求发送时间
uint32_t t2 = request_time; // 请求接收时间(远程)
uint32_t t3 = response_time; // 响应发送时间(远程)
uint32_t t4 = get_system_tick(); // 响应接收时间
// 计算往返延迟
ts->round_trip_delay = (t4 - t1) - (t3 - t2);
// 计算时钟偏移
ts->clock_offset = ((t2 - t1) + (t3 - t4)) / 2;
// 调整本地时钟
if (abs(ts->clock_offset) > MIN_CLOCK_ADJUSTMENT) {
adjust_system_clock(ts->clock_offset);
ts->synchronized = true;
ts->last_sync_time = get_system_tick();
}
return ts->synchronized;
}
// 日历功能
typedef struct {
rtc_time_t date;
bool is_holiday;
const char *holiday_name;
void (*reminder_callback)(const char *event);
} calendar_event_t;
// 日历管理器
typedef struct {
calendar_event_t events[100]; // 最多100个事件
uint32_t event_count;
rtc_driver_t *rtc;
void (*daily_callback)(void);
void (*monthly_callback)(void);
void (*yearly_callback)(void);
} calendar_manager_t;
// 检查事件
void calendar_check_events(calendar_manager_t *cal) {
if (cal == NULL || cal->rtc == NULL) {
return;
}
rtc_time_t current_time;
if (!rtc_get_time(cal->rtc, ¤t_time)) {
return;
}
// 检查每日事件
if (cal->daily_callback != NULL) {
// 检查是否是新的一天
static uint8_t last_day = 0;
if (current_time.day != last_day) {
cal->daily_callback();
last_day = current_time.day;
}
}
// 检查预定义事件
for (uint32_t i = 0; i < cal->event_count; i++) {
calendar_event_t *event = &cal->events[i];
if (event->date.year == current_time.year &&
event->date.month == current_time.month &&
event->date.day == current_time.day) {
// 事件触发
if (event->reminder_callback != NULL) {
event->reminder_callback(event->holiday_name);
}
}
}
}
// 添加日历事件
bool calendar_add_event(calendar_manager_t *cal, const calendar_event_t *event) {
if (cal == NULL || event == NULL || cal->event_count >= 100) {
return false;
}
// 验证日期
if (!rtc_validate_time(&event->date)) {
return false;
}
// 添加事件
memcpy(&cal->events[cal->event_count], event, sizeof(calendar_event_t));
cal->event_count++;
return true;
}
7.2 定时器管理
c
/* 硬件定时器管理实现 */
#include <stdint.h>
#include <stdbool.h>
// 定时器模式
typedef enum {
TIMER_MODE_ONESHOT = 0, // 单次定时
TIMER_MODE_PERIODIC = 1, // 周期性定时
TIMER_MODE_PWM = 2, // PWM输出
TIMER_MODE_CAPTURE = 3, // 输入捕获
TIMER_MODE_ENCODER = 4 // 编码器模式
} timer_mode_t;
// 定时器通道
typedef enum {
TIMER_CHANNEL_1 = 0,
TIMER_CHANNEL_2 = 1,
TIMER_CHANNEL_3 = 2,
TIMER_CHANNEL_4 = 3
} timer_channel_t;
// PWM配置
typedef struct {
uint32_t frequency_hz; // PWM频率
uint32_t duty_cycle; // 占空比(0-10000,表示0-100%)
bool complementary_output; // 互补输出
uint32_t dead_time_ns; // 死区时间(纳秒)
} pwm_config_t;
// 输入捕获配置
typedef struct {
uint32_t filter; // 输入滤波器
uint32_t prescaler; // 预分频器
bool rising_edge; // 上升沿触发
bool falling_edge; // 下降沿触发
} capture_config_t;
// 定时器实例
typedef struct {
TIM_TypeDef *instance; // 定时器寄存器
uint32_t clock_frequency; // 定时器时钟频率
timer_mode_t mode; // 工作模式
uint32_t period; // 周期值
uint32_t prescaler; // 预分频值
bool enabled; // 是否启用
void (*callback)(void); // 回调函数
void *user_data; // 用户数据
} timer_instance_t;
// 定时器管理器
typedef struct {
timer_instance_t timers[8]; // 最多8个定时器
uint32_t timer_count;
bool initialized;
} timer_manager_t;
// 定时器初始化
bool timer_init(timer_manager_t *tm, uint8_t timer_num,
TIM_TypeDef *instance, uint32_t clock_frequency) {
if (tm == NULL || timer_num >= 8 || instance == NULL) {
return false;
}
timer_instance_t *timer = &tm->timers[timer_num];
timer->instance = instance;
timer->clock_frequency = clock_frequency;
timer->mode = TIMER_MODE_ONESHOT;
timer->period = 1000; // 默认1ms
timer->prescaler = (clock_frequency / 1000000) - 1; // 1MHz计数频率
timer->enabled = false;
timer->callback = NULL;
timer->user_data = NULL;
// 配置定时器
timer_configure_hardware(timer);
tm->timer_count++;
return true;
}
// 配置定时器硬件
void timer_configure_hardware(timer_instance_t *timer) {
if (timer == NULL || timer->instance == NULL) {
return;
}
TIM_TypeDef *tim = timer->instance;
// 禁用定时器
tim->CR1 &= ~TIM_CR1_CEN;
// 配置预分频器
tim->PSC = timer->prescaler;
// 配置自动重载值
tim->ARR = timer->period;
// 清除更新标志
tim->SR = ~TIM_SR_UIF;
// 启用更新中断
tim->DIER |= TIM_DIER_UIE;
// 根据模式配置
switch (timer->mode) {
case TIMER_MODE_ONESHOT:
tim->CR1 |= TIM_CR1_OPM; // 单脉冲模式
break;
case TIMER_MODE_PERIODIC:
tim->CR1 &= ~TIM_CR1_OPM; // 连续模式
break;
case TIMER_MODE_PWM:
// 配置PWM模式
timer_configure_pwm_mode(timer);
break;
case TIMER_MODE_CAPTURE:
// 配置输入捕获模式
timer_configure_capture_mode(timer);
break;
default:
break;
}
// 启用定时器
if (timer->enabled) {
tim->CR1 |= TIM_CR1_CEN;
}
}
// 启动定时器
bool timer_start(timer_instance_t *timer) {
if (timer == NULL || timer->instance == NULL) {
return false;
}
timer->enabled = true;
timer->instance->CR1 |= TIM_CR1_CEN;
return true;
}
// 停止定时器
bool timer_stop(timer_instance_t *timer) {
if (timer == NULL || timer->instance == NULL) {
return false;
}
timer->enabled = false;
timer->instance->CR1 &= ~TIM_CR1_CEN;
return true;
}
// 设置定时器周期
bool timer_set_period(timer_instance_t *timer, uint32_t period_us) {
if (timer == NULL || timer->instance == NULL || period_us == 0) {
return false;
}
// 计算ARR值
uint32_t timer_frequency = timer->clock_frequency / (timer->prescaler + 1);
uint32_t arr_value = (timer_frequency * period_us) / 1000000;
if (arr_value == 0 || arr_value > 0xFFFF) {
return false;
}
timer->period = arr_value;
// 更新硬件
DISABLE_INTERRUPTS();
timer->instance->ARR = arr_value;
ENABLE_INTERRUPTS();
return true;
}
// 定时器中断处理
void timer_irq_handler(timer_instance_t *timer) {
if (timer == NULL || timer->instance == NULL) {
return;
}
TIM_TypeDef *tim = timer->instance;
// 检查更新中断
if (tim->SR & TIM_SR_UIF) {
// 清除中断标志
tim->SR &= ~TIM_SR_UIF;
// 调用回调函数
if (timer->callback != NULL) {
timer->callback();
}
// 如果是单次模式,停止定时器
if (timer->mode == TIMER_MODE_ONESHOT) {
timer_stop(timer);
}
}
}
// 配置PWM模式
bool timer_configure_pwm_mode(timer_instance_t *timer,
timer_channel_t channel,
const pwm_config_t *config) {
if (timer == NULL || timer->instance == NULL || config == NULL) {
return false;
}
TIM_TypeDef *tim = timer->instance;
// 停止定时器
bool was_enabled = timer->enabled;
if (was_enabled) {
timer_stop(timer);
}
// 配置PWM频率和占空比
uint32_t timer_frequency = timer->clock_frequency / (timer->prescaler + 1);
uint32_t arr_value = timer_frequency / config->frequency_hz;
uint32_t ccr_value = (arr_value * config->duty_cycle) / 10000;
// 设置ARR和CCR
tim->ARR = arr_value;
switch (channel) {
case TIMER_CHANNEL_1:
tim->CCR1 = ccr_value;
tim->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM模式1
tim->CCER |= TIM_CCER_CC1E; // 启用通道1输出
break;
case TIMER_CHANNEL_2:
tim->CCR2 = ccr_value;
tim->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
tim->CCER |= TIM_CCER_CC2E;
break;
case TIMER_CHANNEL_3:
tim->CCR3 = ccr_value;
tim->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
tim->CCER |= TIM_CCER_CC3E;
break;
case TIMER_CHANNEL_4:
tim->CCR4 = ccr_value;
tim->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2;
tim->CCER |= TIM_CCER_CC4E;
break;
}
// 配置死区时间(如果支持)
if (config->dead_time_ns > 0) {
uint32_t dead_time_ticks = (config->dead_time_ns * timer_frequency) / 1000000000;
tim->BDTR = (dead_time_ticks & 0x7F) | TIM_BDTR_MOE;
}
// 重新启用定时器
if (was_enabled) {
timer_start(timer);
}
return true;
}
// 配置输入捕获模式
bool timer_configure_capture_mode(timer_instance_t *timer,
timer_channel_t channel,
const capture_config_t *config) {
if (timer == NULL || timer->instance == NULL || config == NULL) {
return false;
}
TIM_TypeDef *tim = timer->instance;
// 停止定时器
bool was_enabled = timer->enabled;
if (was_enabled) {
timer_stop(timer);
}
// 配置输入捕获
switch (channel) {
case TIMER_CHANNEL_1:
tim->CCMR1 |= TIM_CCMR1_CC1S_0; // 输入模式,映射到TI1
tim->CCER |= (config->rising_edge ? TIM_CCER_CC1P : 0) |
(config->falling_edge ? TIM_CCER_CC1NP : 0);
break;
case TIMER_CHANNEL_2:
tim->CCMR1 |= TIM_CCMR1_CC2S_0;
tim->CCER |= (config->rising_edge ? TIM_CCER_CC2P : 0) |
(config->falling_edge ? TIM_CCER_CC2NP : 0);
break;
case TIMER_CHANNEL_3:
tim->CCMR2 |= TIM_CCMR2_CC3S_0;
tim->CCER |= (config->rising_edge ? TIM_CCER_CC3P : 0) |
(config->falling_edge ? TIM_CCER_CC3NP : 0);
break;
case TIMER_CHANNEL_4:
tim->CCMR2 |= TIM_CCMR2_CC4S_0;
tim->CCER |= (config->rising_edge ? TIM_CCER_CC4P : 0) |
(config->falling_edge ? TIM_CCER_CC4NP : 0);
break;
}
// 配置滤波器
if (config->filter > 0) {
// 设置输入滤波器
// ...
}
// 启用捕获中断
tim->DIER |= (TIM_DIER_CC1IE << channel);
// 重新启用定时器
if (was_enabled) {
timer_start(timer);
}
return true;
}
// 获取输入捕获值
uint32_t timer_get_capture_value(timer_instance_t *timer, timer_channel_t channel) {
if (timer == NULL || timer->instance == NULL) {
return 0;
}
switch (channel) {
case TIMER_CHANNEL_1:
return timer->instance->CCR1;
case TIMER_CHANNEL_2:
return timer->instance->CCR2;
case TIMER_CHANNEL_3:
return timer->instance->CCR3;
case TIMER_CHANNEL_4:
return timer->instance->CCR4;
default:
return 0;
}
}
// 软件定时器
typedef struct {
uint32_t start_time;
uint32_t timeout;
bool auto_reload;
bool enabled;
void (*callback)(void);
void *user_data;
struct software_timer *next;
} software_timer_t;
// 软件定时器管理器
typedef struct {
software_timer_t *timer_list;
uint32_t system_tick;
uint32_t tick_resolution_us;
bool initialized;
} software_timer_manager_t;
// 初始化软件定时器管理器
bool software_timer_init(software_timer_manager_t *stm, uint32_t tick_resolution_us) {
if (stm == NULL || tick_resolution_us == 0) {
return false;
}
stm->timer_list = NULL;
stm->system_tick = 0;
stm->tick_resolution_us = tick_resolution_us;
stm->initialized = true;
return true;
}
// 创建软件定时器
software_timer_t *software_timer_create(software_timer_manager_t *stm,
uint32_t timeout_ms,
bool auto_reload,
void (*callback)(void),
void *user_data) {
if (stm == NULL || !stm->initialized || callback == NULL) {
return NULL;
}
software_timer_t *timer = (software_timer_t *)malloc(sizeof(software_timer_t));
if (timer == NULL) {
return NULL;
}
memset(timer, 0, sizeof(software_timer_t));
timer->start_time = stm->system_tick;
timer->timeout = (timeout_ms * 1000) / stm->tick_resolution_us; // 转换为tick数
timer->auto_reload = auto_reload;
timer->enabled = true;
timer->callback = callback;
timer->user_data = user_data;
timer->next = NULL;
// 添加到链表
if (stm->timer_list == NULL) {
stm->timer_list = timer;
} else {
software_timer_t *current = stm->timer_list;
while (current->next != NULL) {
current = current->next;
}
current->next = timer;
}
return timer;
}
// 软件定时器滴答处理
void software_timer_tick(software_timer_manager_t *stm) {
if (stm == NULL || !stm->initialized) {
return;
}
stm->system_tick++;
software_timer_t *timer = stm->timer_list;
software_timer_t *prev = NULL;
while (timer != NULL) {
if (timer->enabled) {
uint32_t elapsed = stm->system_tick - timer->start_time;
if (elapsed >= timer->timeout) {
// 定时器超时
if (timer->callback != NULL) {
timer->callback();
}
if (timer->auto_reload) {
// 重新启动定时器
timer->start_time = stm->system_tick;
prev = timer;
timer = timer->next;
} else {
// 单次定时器,从链表中移除
software_timer_t *to_delete = timer;
if (prev == NULL) {
stm->timer_list = timer->next;
} else {
prev->next = timer->next;
}
timer = timer->next;
free(to_delete);
continue;
}
} else {
prev = timer;
timer = timer->next;
}
} else {
prev = timer;
timer = timer->next;
}
}
}
// 启动软件定时器
void software_timer_start(software_timer_t *timer, software_timer_manager_t *stm) {
if (timer == NULL || stm == NULL) {
return;
}
timer->start_time = stm->system_tick;
timer->enabled = true;
}
// 停止软件定时器
void software_timer_stop(software_timer_t *timer) {
if (timer == NULL) {
return;
}
timer->enabled = false;
}
// 重置软件定时器
void software_timer_reset(software_timer_t *timer, software_timer_manager_t *stm) {
if (timer == NULL || stm == NULL) {
return;
}
timer->start_time = stm->system_tick;
}
// 修改软件定时器超时时间
void software_timer_set_timeout(software_timer_t *timer,
software_timer_manager_t *stm,
uint32_t timeout_ms) {
if (timer == NULL || stm == NULL) {
return;
}
timer->timeout = (timeout_ms * 1000) / stm->tick_resolution_us;
timer->start_time = stm->system_tick;
}
// 删除软件定时器
void software_timer_delete(software_timer_manager_t *stm, software_timer_t *timer) {
if (stm == NULL || timer == NULL) {
return;
}
software_timer_t *current = stm->timer_list;
software_timer_t *prev = NULL;
while (current != NULL) {
if (current == timer) {
if (prev == NULL) {
stm->timer_list = current->next;
} else {
prev->next = current->next;
}
free(current);
return;
}
prev = current;
current = current->next;
}
}
第8章 外设与传感器驱动
8.1 ADC采集系统
c
/* ADC驱动实现 */
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
// ADC配置
typedef struct {
uint32_t clock_prescaler; // 时钟预分频
uint32_t resolution; // 分辨率(8, 10, 12位)
uint32_t sampling_time; // 采样时间
uint32_t scan_mode; // 扫描模式
uint32_t continuous_mode; // 连续转换模式
uint32_t data_align; // 数据对齐
uint32_t external_trigger; // 外部触发
} adc_config_t;
// ADC通道配置
typedef struct {
uint8_t channel; // 通道号
uint8_t rank; // 转换序列中的排名
uint32_t sampling_time; // 通道采样时间
bool enabled; // 是否启用
} adc_channel_config_t;
// ADC校准数据
typedef struct {
int32_t offset; // 偏移校准值
float gain; // 增益校准系数
float nonlinearity; // 非线性校准
uint32_t calibration_time; // 校准时间
} adc_calibration_t;
// ADC驱动结构
typedef struct {
ADC_TypeDef *instance; // ADC寄存器实例
adc_config_t config; // 配置
adc_channel_config_t channels[16]; // 通道配置
adc_calibration_t calibration; // 校准数据
uint16_t raw_data[16]; // 原始数据
float converted_data[16]; // 转换后的数据
uint32_t channel_count; // 启用的通道数
bool dma_enabled; // DMA是否启用
bool interrupt_enabled; // 中断是否启用
void (*conversion_complete_callback)(uint8_t channel, uint16_t value);
void (*error_callback)(uint32_t error);
} adc_driver_t;
// ADC初始化
bool adc_init(adc_driver_t *adc, ADC_TypeDef *instance, const adc_config_t *config) {
if (adc == NULL || instance == NULL || config == NULL) {
return false;
}
adc->instance = instance;
adc->config = *config;
memset(adc->channels, 0, sizeof(adc->channels));
memset(adc->raw_data, 0, sizeof(adc->raw_data));
memset(adc->converted_data, 0, sizeof(adc->converted_data));
adc->channel_count = 0;
adc->dma_enabled = false;
adc->interrupt_enabled = false;
adc->conversion_complete_callback = NULL;
adc->error_callback = NULL;
// 初始化校准数据
adc->calibration.offset = 0;
adc->calibration.gain = 1.0f;
adc->calibration.nonlinearity = 0.0f;
adc->calibration.calibration_time = 0;
// 启用ADC时钟
if (instance == ADC1) {
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
} else if (instance == ADC2) {
RCC->APB2ENR |= RCC_APB2ENR_ADC2EN;
} else if (instance == ADC3) {
RCC->APB2ENR |= RCC_APB2ENR_ADC3EN;
}
// 复位ADC
instance->CR2 |= ADC_CR2_ADON; // 开启ADC
delay_us(1);
instance->CR2 |= ADC_CR2_RSTCAL; // 复位校准
while (instance->CR2 & ADC_CR2_RSTCAL);
// 校准ADC
if (!adc_calibrate(adc)) {
return false;
}
// 配置ADC
adc_configure(adc);
return true;
}
// ADC校准
bool adc_calibrate(adc_driver_t *adc) {
if (adc == NULL || adc->instance == NULL) {
return false;
}
ADC_TypeDef *adc_reg = adc->instance;
// 开始校准
adc_reg->CR2 |= ADC_CR2_CAL;
// 等待校准完成
while (adc_reg->CR2 & ADC_CR2_CAL);
// 读取校准值
if (adc_reg->CR2 & ADC_CR2_CAL) {
return false; // 校准失败
}
// 保存校准数据
adc->calibration.calibration_time = get_system_tick();
return true;
}
// 配置ADC
void adc_configure(adc_driver_t *adc) {
if (adc == NULL || adc->instance == NULL) {
return;
}
ADC_TypeDef *adc_reg = adc->instance;
adc_config_t *config = &adc->config;
// 禁用ADC
adc_reg->CR2 &= ~ADC_CR2_ADON;
// 配置控制寄存器1
uint32_t cr1 = 0;
// 分辨率
switch (config->resolution) {
case 8:
cr1 |= ADC_CR1_RES_0;
break;
case 10:
cr1 |= ADC_CR1_RES_1;
break;
case 12:
// 默认12位,无需设置
break;
}
// 扫描模式
if (config->scan_mode) {
cr1 |= ADC_CR1_SCAN;
}
adc_reg->CR1 = cr1;
// 配置控制寄存器2
uint32_t cr2 = ADC_CR2_ADON; // 开启ADC
// 数据对齐
if (config->data_align == ADC_ALIGN_RIGHT) {
cr2 &= ~ADC_CR2_ALIGN;
} else {
cr2 |= ADC_CR2_ALIGN;
}
// 连续转换模式
if (config->continuous_mode) {
cr2 |= ADC_CR2_CONT;
}
// 外部触发
cr2 |= config->external_trigger;
adc_reg->CR2 = cr2;
// 配置采样时间寄存器
// 这里设置所有通道使用相同的采样时间
adc_reg->SMPR1 = 0;
adc_reg->SMPR2 = 0;
for (uint8_t i = 0; i < 10; i++) {
if (i < 10) {
adc_reg->SMPR2 |= (config->sampling_time << (i * 3));
} else {
adc_reg->SMPR1 |= (config->sampling_time << ((i - 10) * 3));
}
}
// 启用ADC
adc_reg->CR2 |= ADC_CR2_ADON;
delay_us(1);
}
// 配置ADC通道
bool adc_configure_channel(adc_driver_t *adc, const adc_channel_config_t *channel_cfg) {
if (adc == NULL || channel_cfg == NULL ||
channel_cfg->channel >= 18 || // 最多18个通道
channel_cfg->rank == 0 || channel_cfg->rank > 16) {
return false;
}
// 保存通道配置
memcpy(&adc->channels[channel_cfg->channel], channel_cfg, sizeof(adc_channel_config_t));
if (channel_cfg->enabled) {
adc->channel_count++;
// 配置序列寄存器
if (channel_cfg->rank <= 6) {
adc->instance->SQR3 |= (channel_cfg->channel << ((channel_cfg->rank - 1) * 5));
} else if (channel_cfg->rank <= 12) {
adc->instance->SQR2 |= (channel_cfg->channel << ((channel_cfg->rank - 7) * 5));
} else {
adc->instance->SQR1 |= (channel_cfg->channel << ((channel_cfg->rank - 13) * 5));
}
// 设置通道数
adc->instance->SQR1 &= ~ADC_SQR1_L;
adc->instance->SQR1 |= ((adc->channel_count - 1) << 20);
}
return true;
}
// 开始转换
bool adc_start_conversion(adc_driver_t *adc) {
if (adc == NULL || adc->instance == NULL || adc->channel_count == 0) {
return false;
}
// 检查ADC是否就绪
if (!(adc->instance->SR & ADC_SR_STRT)) {
// 开始转换
adc->instance->CR2 |= ADC_CR2_SWSTART;
}
return true;
}
// 读取转换结果
bool adc_read_channel(adc_driver_t *adc, uint8_t channel, uint16_t *value) {
if (adc == NULL || value == NULL || channel >= 16 ||
!adc->channels[channel].enabled) {
return false;
}
// 等待转换完成
if (!adc_wait_for_conversion(adc, 100)) { // 100ms超时
return false;
}
// 读取数据
*value = adc->instance->DR;
// 应用校准
*value = adc_apply_calibration(adc, *value);
return true;
}
// 等待转换完成
bool adc_wait_for_conversion(adc_driver_t *adc, uint32_t timeout_ms) {
if (adc == NULL || adc->instance == NULL) {
return false;
}
uint32_t start_time = get_system_tick();
while (!(adc->instance->SR & ADC_SR_EOC)) {
if (timeout_ms > 0 && (get_system_tick() - start_time) >= timeout_ms) {
return false;
}
}
return true;
}
// 应用校准
uint16_t adc_apply_calibration(adc_driver_t *adc, uint16_t raw_value) {
if (adc == NULL) {
return raw_value;
}
// 应用偏移校准
int32_t calibrated_value = (int32_t)raw_value + adc->calibration.offset;
// 应用增益校准
calibrated_value = (int32_t)(calibrated_value * adc->calibration.gain);
// 确保值在有效范围内
if (calibrated_value < 0) {
calibrated_value = 0;
} else if (calibrated_value > 0xFFF) { // 12位ADC
calibrated_value = 0xFFF;
}
return (uint16_t)calibrated_value;
}
// ADC DMA配置
bool adc_configure_dma(adc_driver_t *adc, uint32_t *dma_buffer, uint32_t buffer_size) {
if (adc == NULL || dma_buffer == NULL || buffer_size == 0) {
return false;
}
// 启用DMA
adc->instance->CR2 |= ADC_CR2_DMA;
// 配置DMA
// ... DMA配置代码
adc->dma_enabled = true;
return true;
}
// ADC中断处理
void ADC_IRQHandler(adc_driver_t *adc) {
if (adc == NULL || adc->instance == NULL) {
return;
}
ADC_TypeDef *adc_reg = adc->instance;
// 检查转换完成中断
if (adc_reg->SR & ADC_SR_EOC) {
// 读取数据
uint16_t value = adc_reg->DR;
// 确定是哪个通道
uint8_t current_channel = (adc_reg->SQR3 >> 0) & 0x1F; // 简化处理
// 应用校准
value = adc_apply_calibration(adc, value);
// 保存数据
adc->raw_data[current_channel] = value;
// 调用回调函数
if (adc->conversion_complete_callback != NULL) {
adc->conversion_complete_callback(current_channel, value);
}
// 清除中断标志
adc_reg->SR &= ~ADC_SR_EOC;
}
// 检查其他错误中断
if (adc_reg->SR & ADC_SR_OVR) {
// 溢出错误
adc_reg->SR &= ~ADC_SR_OVR;
if (adc->error_callback != NULL) {
adc->error_callback(ADC_ERROR_OVERRUN);
}
}
}
// 温度传感器读取
typedef struct {
adc_driver_t *adc;
uint8_t channel;
float temperature_c;
float calibration_25c; // 25°C时的校准值
float avg_slope; // 平均斜率(mV/°C)
uint32_t vref_mv; // 参考电压(mV)
} temperature_sensor_t;
// 读取温度
bool temperature_sensor_read(temperature_sensor_t *sensor) {
if (sensor == NULL || sensor->adc == NULL) {
return false;
}
uint16_t adc_value;
if (!adc_read_channel(sensor->adc, sensor->channel, &adc_value)) {
return false;
}
// 转换为电压(mV)
float voltage_mv = (adc_value * sensor->vref_mv) / 4095.0f;
// 计算温度
// 公式:T = (V25 - V_sense) / Avg_Slope + 25
sensor->temperature_c = (sensor->calibration_25c - voltage_mv) / sensor->avg_slope + 25.0f;
return true;
}
// 电池电压监测
typedef struct {
adc_driver_t *adc;
uint8_t channel;
uint32_t voltage_mv;
uint32_t divider_ratio; // 分压比
uint32_t vref_mv; // 参考电压
uint32_t low_voltage_threshold; // 低电压阈值
void (*low_voltage_callback)(uint32_t voltage);
} battery_monitor_t;
// 读取电池电压
bool battery_monitor_read(battery_monitor_t *monitor) {
if (monitor == NULL || monitor->adc == NULL) {
return false;
}
uint16_t adc_value;
if (!adc_read_channel(monitor->adc, monitor->channel, &adc_value)) {
return false;
}
// 计算电压
float adc_voltage = (adc_value * monitor->vref_mv) / 4095.0f;
monitor->voltage_mv = (uint32_t)(adc_voltage * monitor->divider_ratio);
// 检查低电压
if (monitor->voltage_mv < monitor->low_voltage_threshold) {
if (monitor->low_voltage_callback != NULL) {
monitor->low_voltage_callback(monitor->voltage_mv);
}
}
return true;
}
// 多通道采集
typedef struct {
adc_driver_t *adc;
uint8_t channels[8];
uint8_t channel_count;
uint16_t buffer[8];
uint32_t sampling_interval_ms;
uint32_t last_sample_time;
void (*sample_callback)(uint16_t *samples, uint8_t count);
} multi_channel_adc_t;
// 多通道采样
bool multi_channel_sample(multi_channel_adc_t *mca) {
if (mca == NULL || mca->adc == NULL || mca->channel_count == 0) {
return false;
}
// 检查采样间隔
uint32_t current_time = get_system_tick();
if (current_time - mca->last_sample_time < mca->sampling_interval_ms) {
return true;
}
// 采样所有通道
for (uint8_t i = 0; i < mca->channel_count; i++) {
if (!adc_read_channel(mca->adc, mca->channels[i], &mca->buffer[i])) {
return false;
}
}
mca->last_sample_time = current_time;
// 调用回调函数
if (mca->sample_callback != NULL) {
mca->sample_callback(mca->buffer, mca->channel_count);
}
return true;
}
// ADC滤波器
typedef struct {
uint16_t *buffer;
uint32_t buffer_size;
uint32_t buffer_index;
uint32_t filter_type;
float alpha; // 用于指数滤波
} adc_filter_t;
// 初始化滤波器
bool adc_filter_init(adc_filter_t *filter, uint32_t size, uint32_t type) {
if (filter == NULL || size == 0) {
return false;
}
filter->buffer = (uint16_t *)malloc(size * sizeof(uint16_t));
if (filter->buffer == NULL) {
return false;
}
filter->buffer_size = size;
filter->buffer_index = 0;
filter->filter_type = type;
filter->alpha = 0.1f; // 默认值
memset(filter->buffer, 0, size * sizeof(uint16_t));
return true;
}
// 应用滤波器
uint16_t adc_filter_apply(adc_filter_t *filter, uint16_t new_sample) {
if (filter == NULL || filter->buffer == NULL) {
return new_sample;
}
switch (filter->filter_type) {
case ADC_FILTER_AVERAGE:
// 移动平均滤波
filter->buffer[filter->buffer_index] = new_sample;
filter->buffer_index = (filter->buffer_index + 1) % filter->buffer_size;
uint32_t sum = 0;
for (uint32_t i = 0; i < filter->buffer_size; i++) {
sum += filter->buffer[i];
}
return sum / filter->buffer_size;
case ADC_FILTER_EXPONENTIAL:
// 指数加权移动平均
if (filter->buffer_index == 0) {
filter->buffer[0] = new_sample;
} else {
float filtered = filter->alpha * new_sample +
(1.0f - filter->alpha) * filter->buffer[0];
filter->buffer[0] = (uint16_t)filtered;
}
filter->buffer_index = (filter->buffer_index + 1) % filter->buffer_size;
return filter->buffer[0];
case ADC_FILTER_MEDIAN:
// 中值滤波
filter->buffer[filter->buffer_index] = new_sample;
filter->buffer_index = (filter->buffer_index + 1) % filter->buffer_size;
// 复制缓冲区并排序
uint16_t temp_buffer[16];
memcpy(temp_buffer, filter->buffer, filter->buffer_size * sizeof(uint16_t));
// 简单冒泡排序
for (uint32_t i = 0; i < filter->buffer_size - 1; i++) {
for (uint32_t j = 0; j < filter->buffer_size - i - 1; j++) {
if (temp_buffer[j] > temp_buffer[j + 1]) {
uint16_t temp = temp_buffer[j];
temp_buffer[j] = temp_buffer[j + 1];
temp_buffer[j + 1] = temp;
}
}
}
return temp_buffer[filter->buffer_size / 2];
default:
return new_sample;
}
}
由于篇幅限制,本文档只展示了嵌入式C语言实战开发的部分内容。完整实现包括:
-
更多外设驱动:DMA控制器、看门狗、加密模块等
-
高级算法:数字信号处理、控制算法、数据压缩
-
通信协议:CAN总线、USB、以太网、无线通信
-
安全机制:加密算法、安全启动、固件保护
-
调试技术:日志系统、性能分析、在线调试
-
测试框架:单元测试、集成测试、硬件在环测试
每个部分都包含完整的代码实现、设计原理和实际应用示例,确保开发人员能够深入理解并应用于实际项目中。