1. 代码功能概述
PWM 模块:配置 PWM0 和 PWM01 输出,设置周期和占空比,并通过 PWM 匹配中断触发 ADC 转换。
ADC 模块:配置 ADC 模块,使用外部通道 1(P11 引脚)采集模拟信号,并将转换结果存储在变量 gui_AdcValue 中。
中断服务函数:
PWM 中断:在 PWM 匹配时触发,翻转 P0_0 引脚状态。
ADC 中断:在 ADC 转换完成后触发,翻转 P0_1 引脚状态,并清除 ADC 中断标志。
系统初始化
WDTCCR = 0x00; // 关闭看门狗
CLKCON = 0x02; // 选择内部高频 RC 为系统时钟,Fosc = 32MHz
CLKDIV = 0x02; // Fosc 2 分频得到 Fcpu,Fcpu = 16MHz
IO 配置初始化
P0M0 = 0x88; // P00、P01 设置为推挽输出
P2M1 = P2M1 & 0xF0 | 0x08; // P22 设置为推挽输出
P1M0 = P1M0 & 0xF0 | 0x08; // P10 设置为推挽输出
PWM 配置初始化
PWM0_MAP = 0x12; // PWM0 通道映射到 P22 口
PWM01_MAP = 0x08; // PWM01 通道映射到 P10 口
PWMCON0 = 0x04; // 边沿对齐,12 位 PWM 计数
PWMCON1 = 0x30; // PWM0 计数器匹配中断使能,不移相
PWMCON3 = 0x01; // 独立模式
PWM0C = 0x80; // 允许 PWM0 中断,PWM0 和 PWM01 高有效,Fosc 时钟 2 分频
PWM0PH = 0x03; // 周期高 4 位
PWM0PL = 0xFF; // 周期低 8 位
PWM0DH = 0x02; // PWM0 高 4 位占空比
PWM0DL = 0x00; // PWM0 低 8 位占空比
PWM0DTH = 0x02; // PWM01 高 4 位占空比
PWM0DTL = 0x00; // PWM01 低 8 位占空比
PWM0INTDIV = 0x10; // PWM0 匹配中断分频
PWMEN = 0x11; // 使能 PWM0 和 PWM01 输出
PWM 周期和占空比计算:
周期 = 0x03FF / (Fosc / PWM 分频系数) = 1023 / (32MHz / 2) ≈ 63.93μs。
占空比 = 0x0200 / (Fosc / PWM 分频系数) = 512 / (32MHz / 2) ≈ 21.31μs,占空比为 33.3%。
PWM0_MAP 和 PWM01_MAP:将 PWM0 和 PWM01 输出映射到 P22 和 P10 引脚。
PWMCON0 和 PWMCON1:配置 PWM 的工作模式和中断使能。
PWMEN:使能 PWM0 和 PWM01 输出。
ADC 配置初始化
P1M0 = P1M0 & 0x0F | 0x30; // P11 设置为模拟输入
ADCC0 = 0xC3; // 启动 ADC 电源,内部参考电压 2V
Delay_2us(10); // 延时 20us,确保 ADC 系统稳定
ADCC1 = 0x01; // 选择外部通道 1(P11)
ADCC2 = 0x4B; // 转换结果 12 位数据,数据右对齐,ADC 时钟 8 分频
ADCC3 = 0x0D; // PWM0 匹配中断触发 ADC 转换
ADCDLYH = 0x00;
ADCDLYL = 0x01;
IP3 = 0x30; // ADC 优先级为 3
EADC = 1; // 打开 ADC 中断
EA = 1; // 打开总中断
P1M0:配置 P11 为模拟输入模式,用于 ADC 采样。
ADCC0:启动 ADC 电源,选择内部参考电压 2V。
ADCC1:选择外部通道 1(P11)作为 ADC 输入。
ADCC2:配置 ADC 转换结果为 12 位,数据右对齐,ADC 时钟 8 分频。
ADCC3:配置 PWM0 匹配中断触发 ADC 转换。
EADC 和 EA:使能 ADC 中断和全局中断。
ADC 中断服务函数:
void ADC_Rpr() interrupt ADC_VECTOR {
if (ADCC0 & 0x20) { // 检查 ADC 中断标志
P0_1 = ~P0_1; // 翻转 P0_1 引脚状态
ADCC0 &= ~0x20; // 清除 ADC 中断标志
}
}
当 ADC 转换完成时,触发中断,翻转 P0_1 引脚状态,并清除中断标志。
PWM 中断服务函数:
void PWM_Rpt() interrupt PWM_VECTOR {
if (PWMCON1 & 0x40) { // 检查 PWM 中断标志
PWMCON1 &= ~0x40; // 清除 PWM 中断标志
P0_0 = ~P0_0; // 翻转 P0_0 引脚状态
}
}
当 PWM 匹配时,触发中断,翻转 P0_0 引脚状态,并清除中断标志。
void Delay_2us(unsigned int fui_i) {
while (fui_i--);
}
|