STC8 16通道模拟采集 + 4路串口 + 8路PWM 程序

一、系统架构设计

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    STC8 多功能数据采集系统                 │
├─────────────────────────────────────────────────────────────┤
│  模拟采集层  │  通信接口层  │  控制输出层  │  系统管理层   │
│              │              │              │              │
│  • 16路ADC   │  • UART1     │  • 8路PWM    │  • 系统初始化 │
│  • 采样率配置 │  • UART2     │  • 频率调节  │  • 中断管理   │
│  • 滤波处理  │  • UART3     │  • 占空比控制 │  • 看门狗     │
│  • 数据校准  │  • UART4     │  • 死区设置  │  • 低功耗模式 │
└─────────────────────────────────────────────────────────────┘

二、硬件配置

2.1 STC8A8K64S4A12 引脚分配

复制代码
STC8A8K64S4A12 引脚配置:
┌─────────────┬─────────────────────┬──────────────────┐
│ 引脚        │ 功能描述            │ 说明             │
├─────────────┼─────────────────────┼──────────────────┤
│ P0.0-P0.7   │ ADC0-ADC7          │ 模拟输入通道0-7  │
│ P1.0-P1.7   │ ADC8-ADC15         │ 模拟输入通道8-15 │
│ P2.0-P2.7   │ PWM0-PWM7          │ PWM输出通道0-7   │
│ P3.0/RXD1   │ UART1接收          │ 串口1接收        │
│ P3.1/TXD1   │ UART1发送          │ 串口1发送        │
│ P3.2/RXD2   │ UART2接收          │ 串口2接收        │
│ P3.3/TXD2   │ UART2发送          │ 串口2发送        │
│ P3.4/RXD3   │ UART3接收          │ 串口3接收        │
│ P3.5/TXD3   │ UART3发送          │ 串口3发送        │
│ P3.6/RXD4   │ UART4接收          │ 串口4接收        │
│ P3.7/TXD4   │ UART4发送          │ 串口4发送        │
│ P4.0        │ ADC参考电压选择    │ 参考电压控制     │
│ P4.1        │ 系统时钟输出       │ 时钟输出         │
│ P4.2        │ 外部中断0          │ 外部触发         │
│ P4.3        │ 外部中断1          │ 外部触发         │
│ P5.0        │ 系统复位/唤醒      │ 复位引脚         │
└─────────────┴─────────────────────┴──────────────────┘

2.2 硬件连接示例

复制代码
模拟输入:
• 通道0-7:P0.0-P0.7,连接传感器信号
• 通道8-15:P1.0-P1.7,连接传感器信号
• 参考电压:P4.0,连接2.5V精密参考电压

PWM输出:
• PWM0-PWM3:P2.0-P2.3,连接电机驱动/LED调光
• PWM4-PWM7:P2.4-P2.7,连接舵机/继电器

串口通信:
• UART1:连接上位机/调试终端
• UART2:连接GPS模块
• UART3:连接无线通信模块
• UART4:连接传感器扩展板

三、完整源码实现

3.1 系统头文件 (stc8_multifunc.h)

c 复制代码
#ifndef __STC8_MULTIFUNC_H
#define __STC8_MULTIFUNC_H

#include "STC8.H"
#include <intrins.h>
#include <string.h>
#include <stdio.h>

// 系统时钟配置
#define SYSCLK          24000000    // 24MHz系统时钟
#define BAUD_RATE      115200      // 串口波特率

// 模拟采集配置
#define ADC_CHANNELS   16          // 16个ADC通道
#define ADC_SAMPLES    10          // 每个通道采样次数
#define ADC_FILTER_LEN 5           // 滤波长度

// PWM配置
#define PWM_CHANNELS   8           // 8路PWM
#define PWM_BASE_FREQ  1000        // PWM基准频率1kHz
#define PWM_RESOLUTION 1000        // PWM分辨率1000级

// 串口配置
#define UART_BUFF_SIZE 128         // 串口缓冲区大小
#define UART_TIMEOUT   100         // 串口超时时间(ms)

// 系统状态枚举
typedef enum {
    SYS_INIT = 0,
    SYS_RUNNING,
    SYS_SLEEP,
    SYS_FAULT
} SystemState_t;

// ADC数据结构体
typedef struct {
    uint16_t raw_value[ADC_CHANNELS];      // 原始ADC值
    float    voltage[ADC_CHANNELS];        // 转换后的电压值
    float    filtered[ADC_CHANNELS];       // 滤波后的值
    uint8_t  channel_enable[ADC_CHANNELS]; // 通道使能标志
    uint32_t sample_count;                 // 采样计数
} ADC_Data_t;

// PWM数据结构体
typedef struct {
    uint16_t frequency[PWM_CHANNELS];      // PWM频率
    uint16_t duty_cycle[PWM_CHANNELS];     // 占空比(0-1000)
    uint8_t  channel_enable[PWM_CHANNELS]; // 通道使能标志
    uint8_t  polarity[PWM_CHANNELS];       // 极性(0:正,1:负)
} PWM_Data_t;

// 串口数据结构体
typedef struct {
    uint8_t rx_buffer[UART_BUFF_SIZE];     // 接收缓冲区
    uint8_t tx_buffer[UART_BUFF_SIZE];     // 发送缓冲区
    uint8_t rx_head;                       // 接收头指针
    uint8_t rx_tail;                       // 接收尾指针
    uint8_t tx_head;                       // 发送头指针
    uint8_t tx_tail;                       // 发送尾指针
    uint8_t frame_ready;                   // 帧就绪标志
    uint32_t last_rx_time;                 // 最后接收时间
} UART_Data_t;

// 系统配置结构体
typedef struct {
    SystemState_t system_state;            // 系统状态
    uint16_t adc_sample_rate;              // ADC采样率(Hz)
    uint8_t  uart_baud_rate[4];            // 串口波特率索引
    uint8_t  pwm_resolution;               // PWM分辨率
    uint8_t  watchdog_enable;              // 看门狗使能
    uint8_t  low_power_mode;               // 低功耗模式
} SystemConfig_t;

// 全局变量声明
extern ADC_Data_t adc_data;
extern PWM_Data_t pwm_data;
extern UART_Data_t uart_data[4];
extern SystemConfig_t sys_config;

// 函数声明
void System_Init(void);
void ADC_Init(void);
void PWM_Init(void);
void UART_Init(void);
void WatchDog_Init(void);
void System_Process(void);
void ADC_SampleAllChannels(void);
void ADC_FilterData(void);
void PWM_SetDutyCycle(uint8_t channel, uint16_t duty);
void PWM_SetFrequency(uint8_t channel, uint16_t freq);
void UART_SendString(uint8_t uart_num, char *str);
void UART_SendData(uint8_t uart_num, uint8_t *data, uint16_t len);
void UART_ProcessCommand(uint8_t uart_num);
void System_Sleep(void);
void System_Wakeup(void);

#endif /* __STC8_MULTIFUNC_H */

3.2 主程序 (main.c)

c 复制代码
#include "stc8_multifunc.h"

// 全局变量定义
ADC_Data_t adc_data;
PWM_Data_t pwm_data;
UART_Data_t uart_data[4];
SystemConfig_t sys_config;

// 系统初始化
void System_Init(void) {
    // 关闭看门狗
    WDT_CONTR = 0x37;  // 禁止看门狗
    
    // 设置系统时钟为24MHz
    CLK_DIV = 0x00;    // 不分频,使用内部24MHz IRC
    
    // 初始化IO口
    P0M0 = 0x00; P0M1 = 0xFF;  // P0口全部设置为高阻输入(ADC)
    P1M0 = 0x00; P1M1 = 0xFF;  // P1口全部设置为高阻输入(ADC)
    P2M0 = 0xFF; P2M1 = 0x00;  // P2口全部设置为推挽输出(PWM)
    P3M0 = 0xFF; P3M1 = 0x00;  // P3口全部设置为推挽输出(串口)
    P4M0 = 0x00; P4M1 = 0x00;  // P4口准双向口
    
    // 初始化数据结构
    memset(&adc_data, 0, sizeof(ADC_Data_t));
    memset(&pwm_data, 0, sizeof(PWM_Data_t));
    memset(&uart_data, 0, sizeof(UART_Data_t)*4);
    memset(&sys_config, 0, sizeof(SystemConfig_t));
    
    // 设置默认配置
    sys_config.system_state = SYS_INIT;
    sys_config.adc_sample_rate = 1000;  // 1kHz采样率
    sys_config.uart_baud_rate[0] = 3;    // UART1: 115200
    sys_config.uart_baud_rate[1] = 3;    // UART2: 115200
    sys_config.uart_baud_rate[2] = 2;    // UART3: 57600
    sys_config.uart_baud_rate[3] = 1;    // UART4: 38400
    sys_config.pwm_resolution = 1000;     // 1000级分辨率
    sys_config.watchdog_enable = 0;       // 关闭看门狗
    sys_config.low_power_mode = 0;        // 关闭低功耗
    
    // 初始化各模块
    ADC_Init();
    PWM_Init();
    UART_Init();
    WatchDog_Init();
    
    // 使能所有ADC通道
    for(uint8_t i = 0; i < ADC_CHANNELS; i++) {
        adc_data.channel_enable[i] = 1;
    }
    
    // 使能所有PWM通道
    for(uint8_t i = 0; i < PWM_CHANNELS; i++) {
        pwm_data.channel_enable[i] = 1;
        pwm_data.frequency[i] = PWM_BASE_FREQ;
        pwm_data.duty_cycle[i] = 0;
    }
    
    sys_config.system_state = SYS_RUNNING;
    
    printf("System Initialized Successfully!\r\n");
    printf("STC8 Multi-function Data Acquisition System\r\n");
    printf("ADC Channels: 16, PWM Channels: 8, UART Ports: 4\r\n");
}

// 主循环
void main(void) {
    uint32_t last_adc_time = 0;
    uint32_t last_uart_time = 0;
    uint32_t system_tick = 0;
    
    // 系统初始化
    System_Init();
    
    while(1) {
        system_tick++;
        
        // ADC采样(1kHz)
        if(system_tick - last_adc_time >= 1000/sys_config.adc_sample_rate) {
            ADC_SampleAllChannels();
            ADC_FilterData();
            last_adc_time = system_tick;
        }
        
        // 串口数据处理
        if(system_tick - last_uart_time >= 10) {  // 每10ms处理一次串口
            for(uint8_t i = 0; i < 4; i++) {
                if(uart_data[i].frame_ready) {
                    UART_ProcessCommand(i);
                    uart_data[i].frame_ready = 0;
                }
            }
            last_uart_time = system_tick;
        }
        
        // 系统处理
        System_Process();
        
        // 喂狗
        if(sys_config.watchdog_enable) {
            WDT_CONTR = 0x35;  // 喂狗
        }
        
        // 延时1ms
        Delay_ms(1);
    }
}

// 系统处理
void System_Process(void) {
    static uint32_t status_counter = 0;
    
    status_counter++;
    
    // 每秒发送一次状态
    if(status_counter >= 1000) {
        printf("ADC Sample Count: %lu\r\n", adc_data.sample_count);
        printf("ADC Channel 0: %.3fV, Channel 1: %.3fV\r\n", 
               adc_data.voltage[0], adc_data.voltage[1]);
        printf("PWM Duty Cycle: CH0=%d%%, CH1=%d%%\r\n", 
               pwm_data.duty_cycle[0]*100/pwm_data.frequency[0],
               pwm_data.duty_cycle[1]*100/pwm_data.frequency[1]);
        status_counter = 0;
    }
}

3.3 ADC 驱动 (adc_driver.c)

c 复制代码
#include "stc8_multifunc.h"

// ADC初始化
void ADC_Init(void) {
    // 设置ADC时钟为系统时钟/2 = 12MHz
    ADCCFG = 0x0F;  // 设置ADC时钟为系统时钟/2
    
    // 设置ADC参考电压为内部2.5V
    ADC_CONTR = 0x80;  // 使能ADC模块
    
    // 延时等待ADC稳定
    Delay_ms(1);
}

// 读取单个ADC通道
uint16_t ADC_ReadChannel(uint8_t channel) {
    uint16_t adc_value = 0;
    
    // 设置ADC通道
    ADC_CONTR = (ADC_CONTR & 0xF0) | (channel & 0x0F);
    
    // 启动ADC转换
    ADC_CONTR |= 0x40;  // 启动ADC转换
    
    // 等待转换完成
    while(!(ADC_CONTR & 0x20));  // 等待转换完成标志
    
    // 读取ADC结果
    adc_value = (ADC_RES << 8) | ADC_RESL;
    
    // 清除转换完成标志
    ADC_CONTR &= ~0x20;
    
    return adc_value;
}

// 采样所有ADC通道
void ADC_SampleAllChannels(void) {
    uint16_t temp_value;
    uint32_t sum;
    
    for(uint8_t ch = 0; ch < ADC_CHANNELS; ch++) {
        if(!adc_data.channel_enable[ch]) continue;
        
        sum = 0;
        
        // 多次采样取平均
        for(uint8_t i = 0; i < ADC_SAMPLES; i++) {
            temp_value = ADC_ReadChannel(ch);
            sum += temp_value;
            Delay_us(10);
        }
        
        adc_data.raw_value[ch] = sum / ADC_SAMPLES;
        
        // 转换为电压值 (假设参考电压2.5V,12位ADC)
        adc_data.voltage[ch] = (float)adc_data.raw_value[ch] * 2.5f / 4096.0f;
    }
    
    adc_data.sample_count++;
}

// 中值滤波
uint16_t Median_Filter(uint16_t *buffer, uint8_t len) {
    uint16_t temp;
    uint8_t i, j;
    
    // 冒泡排序
    for(i = 0; i < len-1; i++) {
        for(j = 0; j < len-1-i; j++) {
            if(buffer[j] > buffer[j+1]) {
                temp = buffer[j];
                buffer[j] = buffer[j+1];
                buffer[j+1] = temp;
            }
        }
    }
    
    return buffer[len/2];  // 返回中值
}

// 数据滤波
void ADC_FilterData(void) {
    static uint16_t filter_buffer[ADC_CHANNELS][ADC_FILTER_LEN];
    static uint8_t filter_index = 0;
    uint16_t median_value;
    
    // 存储当前采样值到滤波缓冲区
    for(uint8_t ch = 0; ch < ADC_CHANNELS; ch++) {
        filter_buffer[ch][filter_index] = adc_data.raw_value[ch];
    }
    
    filter_index++;
    if(filter_index >= ADC_FILTER_LEN) {
        filter_index = 0;
    }
    
    // 对每个通道进行中值滤波
    for(uint8_t ch = 0; ch < ADC_CHANNELS; ch++) {
        median_value = Median_Filter(filter_buffer[ch], ADC_FILTER_LEN);
        adc_data.filtered[ch] = (float)median_value * 2.5f / 4096.0f;
    }
}

3.4 PWM 驱动 (pwm_driver.c)

c 复制代码
#include "stc8_multifunc.h"

// PWM初始化
void PWM_Init(void) {
    uint16_t pwm_period;
    
    // 设置PWM时钟为系统时钟/12 = 2MHz
    PWMCKS = 0x0B;  // PWM时钟 = 系统时钟/12
    
    // 计算PWM周期值
    pwm_period = SYSCLK / 12 / PWM_BASE_FREQ;
    
    // 设置PWM周期
    PWMC = pwm_period;
    
    // 初始化所有PWM通道
    for(uint8_t i = 0; i < PWM_CHANNELS; i++) {
        // 设置PWM通道的初始占空比为0
        switch(i) {
            case 0: PWM0 = 0; break;
            case 1: PWM1 = 0; break;
            case 2: PWM2 = 0; break;
            case 3: PWM3 = 0; break;
            case 4: PWM4 = 0; break;
            case 5: PWM5 = 0; break;
            case 6: PWM6 = 0; break;
            case 7: PWM7 = 0; break;
        }
        
        // 设置PWM通道为独立模式
        switch(i) {
            case 0: PWM0CR = 0x00; break;  // PWM0独立模式
            case 1: PWM1CR = 0x00; break;  // PWM1独立模式
            case 2: PWM2CR = 0x00; break;  // PWM2独立模式
            case 3: PWM3CR = 0x00; break;  // PWM3独立模式
            case 4: PWM4CR = 0x00; break;  // PWM4独立模式
            case 5: PWM5CR = 0x00; break;  // PWM5独立模式
            case 6: PWM6CR = 0x00; break;  // PWM6独立模式
            case 7: PWM7CR = 0x00; break;  // PWM7独立模式
        }
    }
    
    // 使能PWM模块
    PWMCFG = 0x01;  // 使能PWM模块
}

// 设置PWM占空比
void PWM_SetDutyCycle(uint8_t channel, uint16_t duty) {
    uint16_t pwm_duty_value;
    
    // 限制占空比范围
    if(duty > sys_config.pwm_resolution) {
        duty = sys_config.pwm_resolution;
    }
    
    // 计算PWM比较值
    pwm_duty_value = (uint32_t)duty * PWMC / sys_config.pwm_resolution;
    
    // 设置对应通道的占空比
    switch(channel) {
        case 0: PWM0 = pwm_duty_value; break;
        case 1: PWM1 = pwm_duty_value; break;
        case 2: PWM2 = pwm_duty_value; break;
        case 3: PWM3 = pwm_duty_value; break;
        case 4: PWM4 = pwm_duty_value; break;
        case 5: PWM5 = pwm_duty_value; break;
        case 6: PWM6 = pwm_duty_value; break;
        case 7: PWM7 = pwm_duty_value; break;
    }
    
    pwm_data.duty_cycle[channel] = duty;
}

// 设置PWM频率
void PWM_SetFrequency(uint8_t channel, uint16_t freq) {
    uint16_t pwm_period;
    
    // 限制频率范围 (10Hz - 100kHz)
    if(freq < 10) freq = 10;
    if(freq > 100000) freq = 100000;
    
    // 计算PWM周期值
    pwm_period = SYSCLK / 12 / freq;
    
    // 更新PWM周期
    PWMC = pwm_period;
    
    pwm_data.frequency[channel] = freq;
}

// 设置PWM极性
void PWM_SetPolarity(uint8_t channel, uint8_t polarity) {
    switch(channel) {
        case 0: 
            if(polarity) PWM0CR |= 0x02;  // 负极性
            else PWM0CR &= ~0x02;         // 正极性
            break;
        case 1: 
            if(polarity) PWM1CR |= 0x02;
            else PWM1CR &= ~0x02;
            break;
        // ... 其他通道类似
    }
    
    pwm_data.polarity[channel] = polarity;
}

// 使能/禁用PWM通道
void PWM_EnableChannel(uint8_t channel, uint8_t enable) {
    switch(channel) {
        case 0: 
            if(enable) PWM0CR |= 0x01;
            else PWM0CR &= ~0x01;
            break;
        case 1: 
            if(enable) PWM1CR |= 0x01;
            else PWM1CR &= ~0x01;
            break;
        // ... 其他通道类似
    }
    
    pwm_data.channel_enable[channel] = enable;
}

3.5 串口驱动 (uart_driver.c)

c 复制代码
#include "stc8_multifunc.h"

// 串口初始化
void UART_Init(void) {
    // 初始化UART1
    SCON = 0x50;     // 8位数据,可变波特率
    TMOD &= 0x0F;    // 清除定时器1模式位
    TMOD |= 0x20;    // 设置定时器1为模式2
    TH1 = 0xFD;      // 波特率115200
    TL1 = 0xFD;
    TR1 = 1;         // 启动定时器1
    ES = 1;         // 使能串口1中断
    
    // 初始化UART2 (使用定时器2)
    S2CON = 0x50;    // 8位数据,可变波特率
    T2L = 0xFD;      // 波特率115200
    T2H = 0xFD;
    AUXR |= 0x14;    // 启动定时器2
    IE2 |= 0x01;     // 使能串口2中断
    
    // 初始化UART3 (使用定时器3)
    S3CON = 0x50;    // 8位数据,可变波特率
    T3L = 0xFA;      // 波特率57600
    T3H = 0xFA;
    T4T3M |= 0x02;   // 启动定时器3
    IE2 |= 0x04;     // 使能串口3中断
    
    // 初始化UART4 (使用定时器4)
    S4CON = 0x50;    // 8位数据,可变波特率
    T4L = 0xF6;      // 波特率38400
    T4H = 0xF6;
    T4T3M |= 0x20;   // 启动定时器4
    IE2 |= 0x10;     // 使能串口4中断
    
    EA = 1;          // 使能总中断
}

// 串口发送单个字节
void UART_SendByte(uint8_t uart_num, uint8_t dat) {
    switch(uart_num) {
        case 0:  // UART1
            SBUF = dat;
            while(!TI);
            TI = 0;
            break;
        case 1:  // UART2
            S2BUF = dat;
            while(!(S2CON & 0x02));
            S2CON &= ~0x02;
            break;
        case 2:  // UART3
            S3BUF = dat;
            while(!(S3CON & 0x02));
            S3CON &= ~0x02;
            break;
        case 3:  // UART4
            S4BUF = dat;
            while(!(S4CON & 0x02));
            S4CON &= ~0x02;
            break;
    }
}

// 串口发送字符串
void UART_SendString(uint8_t uart_num, char *str) {
    while(*str) {
        UART_SendByte(uart_num, *str++);
    }
}

// 串口发送数据
void UART_SendData(uint8_t uart_num, uint8_t *data, uint16_t len) {
    for(uint16_t i = 0; i < len; i++) {
        UART_SendByte(uart_num, data[i]);
    }
}

// 串口接收中断处理
void UART_ProcessReceive(uint8_t uart_num, uint8_t dat) {
    UART_Data_t *uart = &uart_data[uart_num];
    
    // 存储接收到的数据
    uart->rx_buffer[uart->rx_head] = dat;
    uart->rx_head = (uart->rx_head + 1) % UART_BUFF_SIZE;
    
    // 检查是否接收到帧结束符
    if(dat == '\n' || dat == '\r') {
        uart->frame_ready = 1;
    }
    
    uart->last_rx_time = Get_SystemTick();
}

// 串口命令处理
void UART_ProcessCommand(uint8_t uart_num) {
    UART_Data_t *uart = &uart_data[uart_num];
    char cmd_buffer[64];
    uint8_t len = 0;
    
    // 提取命令字符串
    while(uart->rx_tail != uart->rx_head && len < sizeof(cmd_buffer)-1) {
        cmd_buffer[len] = uart->rx_buffer[uart->rx_tail];
        uart->rx_tail = (uart->rx_tail + 1) % UART_BUFF_SIZE;
        len++;
    }
    cmd_buffer[len] = '\0';
    
    // 解析命令
    if(strstr(cmd_buffer, "ADC")) {
        UART_SendString(uart_num, "ADC Values:\r\n");
        for(uint8_t i = 0; i < ADC_CHANNELS; i++) {
            char response[64];
            sprintf(response, "CH%d: %.3fV\r\n", i, adc_data.voltage[i]);
            UART_SendString(uart_num, response);
        }
    }
    else if(strstr(cmd_buffer, "PWM")) {
        uint8_t channel;
        uint16_t duty;
        sscanf(cmd_buffer, "PWM %d %d", &channel, &duty);
        if(channel < PWM_CHANNELS) {
            PWM_SetDutyCycle(channel, duty);
            char response[64];
            sprintf(response, "PWM%d set to %d%%\r\n", channel, duty*100/sys_config.pwm_resolution);
            UART_SendString(uart_num, response);
        }
    }
    else if(strstr(cmd_buffer, "HELP")) {
        UART_SendString(uart_num, "Available Commands:\r\n");
        UART_SendString(uart_num, "ADC - Show ADC values\r\n");
        UART_SendString(uart_num, "PWM <ch> <duty> - Set PWM duty\r\n");
        UART_SendString(uart_num, "STATUS - Show system status\r\n");
        UART_SendString(uart_num, "RESET - Reset system\r\n");
    }
    else if(strstr(cmd_buffer, "STATUS")) {
        char response[128];
        sprintf(response, "System State: %d\r\n", sys_config.system_state);
        UART_SendString(uart_num, response);
        sprintf(response, "ADC Samples: %lu\r\n", adc_data.sample_count);
        UART_SendString(uart_num, response);
    }
}

// 串口中断服务函数
void UART1_ISR(void) interrupt 4 {
    uint8_t dat;
    
    if(RI) {
        RI = 0;
        dat = SBUF;
        UART_ProcessReceive(0, dat);
    }
}

void UART2_ISR(void) interrupt 8 {
    uint8_t dat;
    
    if(S2CON & 0x01) {
        S2CON &= ~0x01;
        dat = S2BUF;
        UART_ProcessReceive(1, dat);
    }
}

void UART3_ISR(void) interrupt 17 {
    uint8_t dat;
    
    if(S3CON & 0x01) {
        S3CON &= ~0x01;
        dat = S3BUF;
        UART_ProcessReceive(2, dat);
    }
}

void UART4_ISR(void) interrupt 18 {
    uint8_t dat;
    
    if(S4CON & 0x01) {
        S4CON &= ~0x01;
        dat = S4BUF;
        UART_ProcessReceive(3, dat);
    }
}

3.6 看门狗和系统管理 (system_manager.c)

c 复制代码
#include "stc8_multifunc.h"

// 看门狗初始化
void WatchDog_Init(void) {
    if(sys_config.watchdog_enable) {
        WDT_CONTR = 0x37;  // 使能看门狗,设置预分频
    }
}

// 系统休眠
void System_Sleep(void) {
    sys_config.system_state = SYS_SLEEP;
    
    // 关闭不必要的外设
    PWMCFG = 0x00;  // 关闭PWM
    ADC_CONTR = 0x00;  // 关闭ADC
    
    // 进入掉电模式
    PCON |= 0x02;  // 进入掉电模式
    _nop_();
    _nop_();
}

// 系统唤醒
void System_Wakeup(void) {
    sys_config.system_state = SYS_RUNNING;
    
    // 重新初始化外设
    PWM_Init();
    ADC_Init();
}

// 系统复位
void System_Reset(void) {
    // 软件复位
    IAP_CONTR = 0x60;  // 软件复位
}

// 延时函数
void Delay_ms(uint16_t ms) {
    uint16_t i, j;
    for(i = 0; i < ms; i++) {
        for(j = 0; j < 1200; j++) {
            _nop_();
        }
    }
}

void Delay_us(uint16_t us) {
    while(us--) {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

// 获取系统滴答计数
uint32_t Get_SystemTick(void) {
    static uint32_t tick = 0;
    static uint16_t last_count = 0;
    uint16_t current_count = TH0;  // 使用定时器0作为系统滴答
    
    if(current_count < last_count) {
        tick += 65536;
    }
    last_count = current_count;
    
    return tick + current_count;
}

参考代码 STC8 16通道模拟采集、4路串口通讯、8路PWM程序 www.youwenfan.com/contentcsu/60707.html

四、工程配置与使用

4.1 编译配置

复制代码
Keil C51 工程配置:
• Target: STC8A8K64S4A12
• Code Rom Size: Large
• Xdata Ram Size: 8192
• Memory Model: Large
• Code Optimization: Level 8 (Maximum)

4.2 使用示例

c 复制代码
// 示例:控制PWM输出呼吸灯效果
void BreathingLED(void) {
    static uint16_t duty = 0;
    static uint8_t direction = 0;
    
    if(direction == 0) {
        duty++;
        if(duty >= 1000) {
            direction = 1;
        }
    } else {
        duty--;
        if(duty == 0) {
            direction = 0;
        }
    }
    
    PWM_SetDutyCycle(0, duty);  // PWM0控制LED
    Delay_ms(5);
}

// 示例:读取ADC并通过串口发送
void ADC_Report(void) {
    char report[128];
    
    sprintf(report, "ADC Report:\r\n");
    UART_SendString(0, report);
    
    for(uint8_t i = 0; i < 16; i++) {
        if(adc_data.channel_enable[i]) {
            sprintf(report, "CH%d: %.3fV (Raw: %d)\r\n", 
                   i, adc_data.voltage[i], adc_data.raw_value[i]);
            UART_SendString(0, report);
        }
    }
}

4.3 常见问题解决

问题 原因 解决方案
ADC读数不稳定 电源噪声干扰 增加电源滤波电容,使用外部参考电压
PWM输出不正常 频率设置错误 检查PWM时钟分频和周期设置
串口通信失败 波特率不匹配 确认系统时钟频率,重新计算波特率
系统经常复位 看门狗超时 增加喂狗频率,检查程序死循环
相关推荐
星夜夏空991 小时前
STM32单片机学习(4)——嵌入式概述
stm32·单片机·学习
Deitymoon2 小时前
STM32——OLED显示字符串
单片机·嵌入式硬件
LCG元2 小时前
STM32实战:基于STM32F407的FFT频谱分析(音频信号处理)
stm32·音视频·信号处理
Graceful_scenery3 小时前
龙芯2k0300 - 走马观碑组按键驱动移植
单片机·嵌入式硬件
d111111111d3 小时前
MQTT+STM32+ESP8266网络程序分层+韦老师
笔记·stm32·单片机·嵌入式硬件·学习·php
长安第一美人3 小时前
RT-Thread 工业屏驱动开发实战:UART 串口屏协议解析 + 数据实时刷新 + 设备驱动框架完整实现
驱动开发·嵌入式硬件·rt-thread·工业控制·uart通信·串口屏驱动
LDR0063 小时前
突破快充壁垒,赋能全场景体验——LDR6600 2C1A快充协议芯片重磅来袭
嵌入式硬件
weixin_457943303 小时前
arduino-舵机驱动
单片机·嵌入式硬件
AUTO_150756759653 小时前
SCT2160FNBR:7V 输入、6A、高效率同步降压 DC-DC 转换器
单片机·嵌入式硬件