WDTCCR = 0x00; // 关闭看门狗 CLKCON = 0x02; // 选择内部高频 RC 为系统时钟,Fosc = 32MHz CLKDIV = 0x02; // Fosc 2 分频得到 Fcpu,Fcpu = 16MHzIO 配置初始化 复制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--); }
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--); }
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--); }
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--); }
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--); }
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--); }
void Delay_2us(unsigned int fui_i) { while (fui_i--); }
举报
/** * ************************************************************************************ * 上海芯圣电子股份有限公司 * www.holychip.cn * ************************************************************************************ * @Examle Version V1.0.0.5 * @Date 2023.04.07 * ************************************************************************************ * 模块性能介绍 * 1、HC89S105AC8提供10/12位ADC检测,拥有32路外部输入通道以及2路内部输入通道 * 2、参考电压可选择内部Vref(VDD、2V、3V、4V)以及外部Vref,转换后的数据可选择数 * 据位数和对齐方向 * 3、ADC 模拟看门狗功能,被 ADC 转换的模拟电压与高、低阈值比较寄存器的值比较 * 4、可由外部触发信号启动 ADC 转换,并带有触发延时计时器 * 5、提供 ADC 连续转换,并可设置连续转换的时间间隔 * ************************************************************************************ * 应用注意事项 * 1、在掉电模式下,ADCEN强制为0,ADC失能。 * 2、为保证ADC转换精度,建议ADC转换时钟频率在2MHz及2MHz以下。 * 3、内部参考电压选择2V时,VDD工作电压须高于2.7V。内部参考电压选择3V/4V时,VDD工作电 * 压须高于内部参考电压0.5V以上。 * 4、使能ADC模块或者切换通道后,为保证精度建议延时20us再启动转换。 * 5、启动转换时,ADCIF需要先软件清0,ADCIF位为1时,置ADCST不能启动新的转换。在转换过 * 程中,若ADCST位软件清0将终止转换。 * 6、在进行内部通道选择时,外部通道选择XCHS[3:0]应配置为1111,否则可能会造成内部通道 * 和外部通道同时打开的情况。 * 7、选择内部参考电压 2/3/4V时,相应的 ADC 时钟需要配置ADCTS [2:0]设置一次转换需要 * 的 ADC_CLK 个数。如果选择 VDD 作参考电压,无论 ADC 时钟为多少,都可以选择 15 个 * ADC_CLK。 * 8、PWM 中点触发仅适用于中心对齐模式的 PWM 输出。 * 9、当 ADCST 为 1 时(正在转换),外部触发信号不会影响 ADC 直到本次 ADC 转换结束即 * ADCST 被硬件清 0。 * ************************************************************************************ * 客户服务 * 感谢您使用我们的单片机,若发现错误或对函数的使用存在疑问。请添加上海芯圣电子官方QQ群 * ****************************技术支持群:201030494*********************************** * **************************************************************************************/ #define ALLOCATE_EXTERN #include "HC89S105AC8.h" void Delay_2us(unsigned int fui_i); //延时函数 unsigned int gui_AdcValue = 0; //存放当前获取的ADC的值 /*************************************************************************************** * @实现效果 PWM匹配中断触发ADC * @操作方法 P11端口接1V电压,P01,P00翻转 ***************************************************************************************/ void main(void) { /************************************系统初始化****************************************/ WDTCCR = 0x00; //关闭看门狗 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程 CLKCON = 0x02; //选择内部高频RC为系统时钟,Fosc=32MHz CLKDIV = 0x02; //Fosc 2分频得到Fcpu,Fcpu=16MHz /**********************************IO配置初始化**************************************/ P0M0 = 0x88; //P00、P01设置为推挽输出 /**********************************PWM 配置初始化**************************************/ P2M1 = P2M1 & 0xF0 | 0x08; //P22设置为推挽输出 P1M0 = P1M0 & 0xF0 | 0x08; //P10设置为推挽输出 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分频 //独立模式下,PWM0和PWM01共用一个周期寄存器 //PWM0的占空比调节使用 PWM0组的占空比寄存器 //PWM01的占空比调节使用 PWM0组的死区寄存器 //周期计算 = 0x03ff / (Fosc / PWM分频系数) // = 0x03ff / (32000000 / 2) // = 1023 /16000000 // = 63.93us PWM0PH = 0x03; //周期高4位 PWM0PL = 0xFF; //周期低8位 //占空比计算= 0x0200 / (Fosc / PWM分频系数) // = 0x0200 / (32000000 / 2) // = 341 / 16000000 // = 21.31us 占空比为 21.31/63.93 = 33.3% PWM0DH = 0x02; //PWM0高4位占空比 PWM0DL = 0x00; //PWM0低8位占空比 PWM0DTH = 0x02; //PWM01高4位占空比 PWM0DTL = 0x00; //PWM01低8位占空比 PWM0INTDIV = 0x10; // PWM0匹配中断分频 PWMEN = 0x11; //使能PWM0和PWM01输出 /************************** ADC配置初始化 ************************************************/ P1M0 = P1M0 & 0x0F | 0x30; //P11设置为模拟输入 ADCC0 = 0xC3; //启动ADC电源,内部参考电压 2V Delay_2us(10); //延时20us,确保ADC系统稳定 ADCC1 = 0x01; //选择外部通道1 ADCC2 = 0x4B; //转换结果12位数据,数据右对齐,ADC时钟8分频 ADCC3 = 0x0D; //PWM0 匹配中断 ADCDLYH = 0x00; ADCDLYL = 0x01; IP3 = 0x30; //ADC优先级为3 EADC = 1; //打开ADC中断 EA = 1; //打开总中断 while (1); } /*************************************************************************************** * @说明 ADC中断服务函数 * @参数 无 * @返回值 无 * @注 无 ***************************************************************************************/ void ADC_Rpr() interrupt ADC_VECTOR { if (ADCC0 & 0X20) { P0_1 = ~P0_1; ADCC0 &= ~0x20; //清ADCIF标志 } } /*************************************************************************************** * @说明 PWM中断服务函数 * @参数 无 * @返回值 无 * @注 无 ***************************************************************************************/ void PWM_Rpt() interrupt PWM_VECTOR { if (PWMCON1 & 0x40) { PWMCON1 &= ~0x40; P0_0 = ~P0_0; } } /************************************************************************************ * @说明 延时函数 * @参数 fui_i : 延时时间 * @返回值 无 * @注 Fcpu = 16MHz,fui_i = 1时,延时时间约为2us ***********************************************************************************/ void Delay_2us(unsigned int fui_i) { while (fui_i--); }
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
125
1624
1
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号