PWM脉冲引脚怎么转为普通IO拉低电平
// 方案003
/*
配置说明:
比较器电平:
0表示 正输入 小于 负输入
1表示 正输入 大于 负输入
*/
// 头文件
#include "STC8Hxxx.h"
// 引脚定义
sbit OUT_INT0 = P3^2; // 外部中断0输入引脚
sbit Pulse = P3^4; // PWM脉冲输出引脚
sbit CMP = P3^7; // 比较器正输入端
// 宏定义
#define MAIN_Fosc 35000000L // 35MHz主频
// 声明
// 数组
// 函数
// 变量
bit cmp_filtered = 1; // 当前比较器稳定状态
bit trigger_lock = 0; // 锁存标志:0=允许触发,1=已触发等待解锁
u8 stable_cnt = 0;
// 函数模块
// 比较器初始化
void CMP_Init(void)
{
CMPEXCFG = 0x00;
CMPEXCFG |= 0x00; // P3.7 为 CMP+ 输入脚
CMPEXCFG |= 0x04; // 内部 1.19V 参考为 CMP?
P_SW2 &= 0x7F; // 禁止XFR访问
CMPCR2 = 0x00;
CMPCR2 &= ~0x80; // 输出不反向
CMPCR2 &= ~0x40; // 使能0.1us滤波
CMPCR2 |= 0x10; // 输出结果经过16个去抖时钟稳定输出
CMPCR1 = 0x00;
CMPCR1 |= 0x02; // 输出使能
CMPCR1 |= 0x80; // 比较器模块使能
}
// PWMB脉冲配置
void PWMB_config(void)
{
PWMB_PSCR = 11; // 预分频寄存器, Fpwm = SYSclk / ((PSCR+1)*(ARR+1))
PWMB_DTR = 0; // 死区时间配置
PWMB_ARR = 29165; // 自动重装载寄存器,控制PWM周期
PWMB_CCER1= 0;
PWMB_CCER2= 0;
PWMB_SR1 = 0;
PWMB_SR2 = 0;
PWMB_ENO = 0;
PWMB_PS = 0;
PWMB_IER = 0;
PWMB_CR1 = 0;
PWMB_CCR4 = 14582; // 比较匹配值: 输出脉宽 = 2000 - 1750 = 250
PWMB_CCMR4= (7 << 4) + 8; // 通道4 PWM模式2 + 允许CCR预装载
PWMB_CCER2 |= 0x50; // 使能通道4输出, 高电平有效 (CH4P=0, CH4E=1)
PWMB_PS |= (1 << 6); // 选择P3.4作为PWM输出引脚(bit7:6 = 01)
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_BKR = 0x80; // 主输出使能(MOE=1)
PWMB_CR1 |= 0x08; // 单脉冲模式(OPM=1)
}
// 主函数
void main(void)
{
P_SW2 |= 0x80; // 允许XFR访问
// 引脚初始化
P3M0 = (P3M0 & ~0x84) | 0x10; P3M1 = (P3M1 & ~0x10) | 0x84; // P32 37 高阻输入P34 推挽输出
Pulse = 0;
// 函数初始化
CMP_Init();
PWMB_config();
// 主循环
while (1)
{
bit now_cmp = CMPCR1 & 0x01;// 读取比较器结果(1=V+>V?,0=V+<V?)
//------------------ 去抖判断 ------------------
if (now_cmp == cmp_filtered)
{
stable_cnt = 0;// 状态稳定,不计数
}
else if (++stable_cnt > 3)
{
cmp_filtered = now_cmp; // 确认状态改变
stable_cnt = 0;
}
//------------------ 主逻辑 ------------------
if (cmp_filtered == 0)
{
// 电压 < 1.19V
static unsigned char low_cnt = 0;
if (!trigger_lock)
{
// 连续三次低电平确认后触发一次
if (++low_cnt >= 3)
{
PWMB_CCER2 |= 0x10; // 重新启用CH2输出
PWMB_CR1 |= 0x01; // 触发一次单脉冲输出
PWMB_CCER2 &= ~0x10; // 关闭CH2输出
Pulse = 0; // 输出脚保持低电平
trigger_lock = 1; // 锁住,不再重复触发
low_cnt = 0;
}
}
else
{
low_cnt = 0; // 已锁定期间不计数
}
}
else // cmp_filtered == 1
{
// 电压 > 1.19V
PWMB_CCER2 &= ~0x10; // 关闭CH2输出
PWMB_ENO |= 0x00;
Pulse = 0; // 输出脚保持低电平
trigger_lock = 0; // 解锁允许下次触发
}
}
}
// 中断服务函数
现在发现一个问题
当我cmp_filtered = 0的时候 打完一个脉冲 Pulse 就是低电平了 这是我需要的
而当cmp_filtered = 1的时候 应该也是强制拉低的状态 但是现在拉不低 是还需要配置哪个寄存器才能让Pulse 引脚脱离PWMB模块吗?
按照AI的方案改了一下
发现还是电压高于比较器的参考电压1.19的时候 会检测到P34为高电平(此处应该是低电平)
低于1.19的时候会发送一次脉冲 然后低电平 神农鼎 发表于 2025-10-25 11:50
// 主函数
void main(void)
{
P_SW2 |= 0x80; // 允许XFR访问
// 引脚初始化
P3M0 = (P3M0 & ~0x84) | 0x10; P3M1 = (P3M1 & ~0x10) | 0x84; // P32 37 高阻输入P34 推挽输出
Pulse = 0;
// 函数初始化
CMP_Init();
PWMB_config();
// 主循环
while (1)
{
bit now_cmp = CMPCR1 & 0x01;// 读取比较器结果(1=V+>V?,0=V+<V?)
//------------------ 去抖判断 ------------------
if (now_cmp == cmp_filtered)
{
stable_cnt = 0;// 状态稳定,不计数
}
else if (++stable_cnt > 3)
{
cmp_filtered = now_cmp; // 确认状态改变
stable_cnt = 0;
}
//------------------ 主逻辑 ------------------
if (cmp_filtered == 0)
{
// 电压 < 1.19V
static unsigned char low_cnt = 0;
if (!trigger_lock)
{
// 连续三次低电平确认后触发一次
if (++low_cnt >= 3)
{
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_CR1 |= 0x01; // 触发一次单脉冲输出
PWMB_ENO &= ~0x40; // 清除 bit6,使通道4输出禁止
P3M1 &= ~0x10; // 设置为输出模式
P3M0 |=0x10;
Pulse = 0; // 输出低电平
trigger_lock = 1; // 锁住,不再重复触发
low_cnt = 0;
}
}
else
{
low_cnt = 0; // 已锁定期间不计数
}
}
else // cmp_filtered == 1
{
// 电压 > 1.19V
PWMB_ENO &= ~0x40; // 清除 bit6,使通道4输出禁止
P3M1 &= ~0x10; // 设置为输出模式
P3M0 |=0x10;
Pulse = 0; // 输出低电平
trigger_lock = 0; // 解锁允许下次触发
}
}
}
这样么
我改了一下ENO
但还是当高于1.19的时候输出高电平
神农鼎 发表于 2025-10-25 12:46
两个方案都不行
高于1.19的时候直接强制输出无效电平
也会直接高电平了// 方案003
/*
配置说明:
比较器电平:
0表示 正输入 小于 负输入
1表示 正输入 大于 负输入
*/
// 头文件
#include "STC8Hxxx.h"
// 引脚定义
sbit OUT_INT0 = P3^2; // 外部中断0输入引脚
sbit Pulse = P3^4; // PWM脉冲输出引脚
sbit CMP = P3^7; // 比较器正输入端
// 宏定义
#define MAIN_Fosc 35000000L // 35MHz主频
// 声明
// 数组
// 函数
// 变量
bit cmp_filtered = 1; // 当前比较器稳定状态
bit trigger_lock = 0; // 锁存标志:0=允许触发,1=已触发等待解锁
u8 stable_cnt = 0;
// 函数模块
// 比较器初始化
void CMP_Init(void)
{
CMPEXCFG = 0x00;
CMPEXCFG |= 0x00; // P3.7 为 CMP+ 输入脚
CMPEXCFG |= 0x04; // 内部 1.19V 参考为 CMP?
P_SW2 &= 0x7F; // 禁止XFR访问
CMPCR2 = 0x00;
CMPCR2 &= ~0x80; // 输出不反向
CMPCR2 &= ~0x40; // 使能0.1us滤波
CMPCR2 |= 0x10; // 输出结果经过16个去抖时钟稳定输出
CMPCR1 = 0x00;
CMPCR1 |= 0x02; // 输出使能
CMPCR1 |= 0x80; // 比较器模块使能
}
// PWMB脉冲配置
void PWMB_config(void)
{
PWMB_PSCR = 11; // 预分频寄存器, Fpwm = SYSclk / ((PSCR+1)*(ARR+1))
PWMB_DTR = 0; // 死区时间配置
PWMB_ARR = 29165; // 自动重装载寄存器,控制PWM周期
PWMB_CCER1= 0;
PWMB_CCER2= 0;
PWMB_SR1 = 0;
PWMB_SR2 = 0;
PWMB_ENO = 0;
PWMB_PS = 0;
PWMB_IER = 0;
PWMB_CR1 = 0;
PWMB_CCR4 = 14582; // 比较匹配值: 输出脉宽 = 2000 - 1750 = 250
PWMB_CCMR4= (7 << 4) + 8; // 通道4 PWM模式2 + 允许CCR预装载
PWMB_CCER2 |= 0x50; // 使能通道4输出, 高电平有效 (CH4P=0, CH4E=1)
PWMB_PS |= (1 << 6); // 选择P3.4作为PWM输出引脚(bit7:6 = 01)
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_BKR = 0x80; // 主输出使能(MOE=1)
PWMB_CR1 |= 0x08; // 单脉冲模式(OPM=1)
}
// 主函数
void main(void)
{
P_SW2 |= 0x80; // 允许XFR访问
// 引脚初始化
P3M0 = (P3M0 & ~0x84) | 0x10; P3M1 = (P3M1 & ~0x10) | 0x84; // P32 37 高阻输入P34 推挽输出
Pulse = 0;
// 函数初始化
CMP_Init();
PWMB_config();
// 主循环
while (1)
{
bit now_cmp = CMPCR1 & 0x01;// 读取比较器结果(1=V+>V?,0=V+<V?)
//------------------ 去抖判断 ------------------
if (now_cmp == cmp_filtered)
{
stable_cnt = 0;// 状态稳定,不计数
}
else if (++stable_cnt > 3)
{
cmp_filtered = now_cmp; // 确认状态改变
stable_cnt = 0;
}
//------------------ 主逻辑 ------------------
if (cmp_filtered == 0)
{
// 电压 < 1.19V
static unsigned char low_cnt = 0;
if (!trigger_lock)
{
// 连续三次低电平确认后触发一次
if (++low_cnt >= 3)
{
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_CR1 |= 0x01; // 触发一次单脉冲输出
PWMB_CCMR1 |= 0x40; // 强制输出无效电平0%
trigger_lock = 1; // 锁住,不再重复触发
low_cnt = 0;
}
}
else
{
low_cnt = 0; // 已锁定期间不计数
}
}
else // cmp_filtered == 1
{
// 电压 > 1.19V
PWMB_CCMR1 |= 0x40; // 强制输出无效电平0%
trigger_lock = 0; // 解锁允许下次触发
}
}
}
// 中断服务函数
HyunYong_7782 发表于 2025-10-25 13:10
两个方案都不行
高于1.19的时候直接强制输出无效电平
也会直接高电平了
将PWMx_ENO对应通道关闭后就可以使用IO口方式输出高低电平
#define ENO5P 0x01
#define ENO6P 0x04
#define ENO7P 0x10
#define ENO8P 0x40
if(P34 == 0)
{
PWMB_ENO &= ~ENO5P; //关闭输出
PWMB_ENO &= ~ENO6P; //关闭输出
P20 = 0; //输出低电平
P21 = 0; //输出低电平
}
if(P35 == 0)
{
PWMB_ENO |= ENO5P; //使能输出
PWMB_ENO |= ENO6P; //使能输出
} 乘风飞扬 发表于 2025-10-25 14:08
将PWMx_ENO对应通道关闭后就可以使用IO口方式输出高低电平
好的哥 我试一下
乘风飞扬 发表于 2025-10-25 14:08
将PWMx_ENO对应通道关闭后就可以使用IO口方式输出高低电平
// 方案003
/*
配置说明:
比较器电平:
0表示 正输入 小于 负输入
1表示 正输入 大于 负输入
*/
// 头文件
#include "STC8Hxxx.h"
// 引脚定义
sbit OUT_INT0 = P3^2; // 外部中断0输入引脚
sbit Pulse = P3^4; // PWM脉冲输出引脚
sbit CMP = P3^7; // 比较器正输入端
// 宏定义
#define MAIN_Fosc 35000000L // 35MHz主频
#define ENO5P 0x01
#define ENO6P 0x04
#define ENO7P 0x10
#define ENO8P 0x40
// 声明
// 数组
// 函数
// 变量
bit cmp_filtered = 1; // 当前比较器稳定状态
bit trigger_lock = 0; // 锁存标志:0=允许触发,1=已触发等待解锁
u8 stable_cnt = 0;
// 函数模块
// 比较器初始化
void CMP_Init(void)
{
CMPEXCFG = 0x00;
CMPEXCFG |= 0x00; // P3.7 为 CMP+ 输入脚
CMPEXCFG |= 0x04; // 内部 1.19V 参考为 CMP?
P_SW2 &= 0x7F; // 禁止XFR访问
CMPCR2 = 0x00;
CMPCR2 &= ~0x80; // 输出不反向
CMPCR2 &= ~0x40; // 使能0.1us滤波
CMPCR2 |= 0x10; // 输出结果经过16个去抖时钟稳定输出
CMPCR1 = 0x00;
CMPCR1 |= 0x02; // 输出使能
CMPCR1 |= 0x80; // 比较器模块使能
}
// PWMB脉冲配置
void PWMB_config(void)
{
PWMB_PSCR = 11; // 预分频寄存器, Fpwm = SYSclk / ((PSCR+1)*(ARR+1))
PWMB_DTR = 0; // 死区时间配置
PWMB_ARR = 29165; // 自动重装载寄存器,控制PWM周期
PWMB_CCER1= 0;
PWMB_CCER2= 0;
PWMB_SR1 = 0;
PWMB_SR2 = 0;
PWMB_ENO = 0;
PWMB_PS = 0;
PWMB_IER = 0;
PWMB_CR1 = 0;
PWMB_CCR4 = 14582; // 比较匹配值: 输出脉宽 = 2000 - 1750 = 250
PWMB_CCMR4= (7 << 4) + 8; // 通道4 PWM模式2 + 允许CCR预装载
PWMB_CCER2 |= 0x50; // 使能通道4输出, 高电平有效 (CH4P=0, CH4E=1)
PWMB_PS |= (1 << 6); // 选择P3.4作为PWM输出引脚(bit7:6 = 01)
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_BKR = 0x80; // 主输出使能(MOE=1)
PWMB_CR1 |= 0x08; // 单脉冲模式(OPM=1)
}
// 主函数
void main(void)
{
P_SW2 |= 0x80; // 允许XFR访问
// 引脚初始化
P3M0 = (P3M0 & ~0x84) | 0x10; P3M1 = (P3M1 & ~0x10) | 0x84; // P32 37 高阻输入P34 推挽输出
Pulse = 0;
// 函数初始化
CMP_Init();
PWMB_config();
// 主循环
while (1)
{
bit now_cmp = CMPCR1 & 0x01; // 读取比较器结果(1=V+>V?,0=V+<V?)
//------------------ 去抖判断 ------------------
if (now_cmp == cmp_filtered)
{
stable_cnt = 0; // 状态稳定,不计数
}
else if (++stable_cnt > 3)
{
cmp_filtered = now_cmp; // 确认状态改变
stable_cnt = 0;
}
//------------------ 主逻辑 ------------------
if (cmp_filtered == 0)
{
// 电压 < 1.19V
static unsigned char low_cnt = 0;
if (!trigger_lock)
{
// 连续三次低电平确认后触发一次
if (++low_cnt >= 3)
{
PWMB_ENO |= 0x40; // 允许通道4输出到IO (bit6: ENO8P)
PWMB_CR1 |= 0x01; // 触发一次单脉冲输出
PWMB_ENO &= ~ENO8P; // 关闭输出
Pulse = 0;
trigger_lock = 1; // 锁住,不再重复触发
low_cnt = 0;
}
}
else
{
low_cnt = 0; // 已锁定期间不计数
}
}
else // cmp_filtered == 1
{
// 电压 > 1.19V
PWMB_ENO &= ~ENO8P; // 关闭输出
Pulse = 0;
trigger_lock = 0; // 解锁允许下次触发
}
}
}
// 中断服务函数
我现在是这样写的
但是实际检测的时候发现高于1.19的时候还是高电平
而且我判断有可能低1.19的时候有可能拉低电平也没有起作用 而仅仅只是因为脉冲刚好在低电平结束 所以持续低于的状态
"C:\Users\Administrator\Desktop\2a96f1d4430870ed9c85fc98386c9656.jpg""C:\Users\Administrator\Desktop\52da0eed6833e3250b37268fb928bbca.jpg"
这是最新回复的测试结果
页:
[1]
2