STC32G12K128编码器模式无法实现4倍频求助
void PWM_Config(){
EAXFR=1;
P6M1 = 0xFF;
P6M0 = 0x00;
PWMA_PS=0X0A;//PWM1P功能切换到P6.0,PWM2P功能切换到P6.2
PWMA_ENO = 0x00; // 配置成 TRGI 的 pin 需关掉 ENO 对应 bit 并配成 input
PWMA_PSCRH=0X00;
PWMA_PSCRL=0X00;
PWMA_CCMR1 = 0x21; // 通道模式配置为输入,接编码器 , 滤波器 4 时钟
PWMA_CCMR2 = 0x21; // 通道模式配置为输入,接编码器 , 滤波器 4 时钟
PWMA_CCER1 = 0x55; // 配置通道使能和极性
PWMA_CCER2 = 0x55; // 配置通道使能和极性
// PWMA_SMCR = 0x01; // 编码器模式 1
// PWMA_SMCR = 0x02; // 编码器模式 2
PWMA_SMCR = 0x03; // 编码器模式 3
PWMA_IER = 0x02; // 使能中断
PWMA_CR1 |= 0x01; // 使能PWM计数器
EA = 1; //CPU开放中断,打开总中断。
}
void Encoder_Check() //检测编码器计数值
{
newcount = cnt_H * 256 + cnt_L; //获取新的计数器值
if(newcount < count) //如果新计数值 小于 计数值
{
leftmove = 1; //左转标志置1
count = newcount; //更新计数值
numberchange = 1;
if(number > 0) number--;
}
else if(newcount > count) //如果新计数值 大于 计数值
{
rightmove = 1; //右转标志置1
count = newcount; //更新计数值
numberchange = 1;
if(number < 60000) number++;
}
}
/******************** PWM 中断读编码器计数值 **************************/
void PWM_ISR() interrupt 26
{
// P20 = ~P20;
if (PWMA_SR1 & 0X02) //捕获1中断标志置1时
{
cnt_H = PWMA_CCR1H; //读取PWM计数器高8位
cnt_L = PWMA_CCR1L; //读取PWM计数器低8位
PWMA_SR1 &= ~0X02; //清零捕获1中断标志
Encoder_Check(); //检测编码器计数值
}
}
使用编码器模式3,但是实现不了4倍频,模式1、模式2和模式3效果都是一样的,1200线光电编码器,3个模式都是取1200个数(旋转一圈),各位高人帮忙分析一下,感谢
你好,感谢你在论坛上分享这个问题。关于你提到的 STC32G12K128 编码器模式无法实现 4 倍频 的问题,我将从硬件配置、寄存器设置、编码器模式原理等角度进行分析,并尝试给出可能的解决方案。
一、问题分析
你提供的代码片段中,使用了 STC32G12K128 的 PWM 模块配置为编码器接口模式,试图通过 PWM 外设来读取编码器信号。但目前无法实现 4 倍频功能。
1. 编码器 4 倍频原理简介
编码器通常输出两路正交信号 A 和 B,相位差为 90°。通过检测这两路信号的边沿变化,可以实现以下几种倍频模式:
1 倍频:只检测 A 或 B 的上升沿。
2 倍频:检测 A 的上升沿和下降沿。
4 倍频:检测 A 和 B 的上升沿和下降沿,共 4 个边沿。
要实现 4 倍频,需要 PWM 模块支持编码器接口模式,并正确配置相关寄存器以识别四边沿。
二、STC32G12K128 编码器模式配置分析
你使用的是 PWM 模块的编码器接口功能,以下是你配置中的关键部分:
c
PWMACCMR1 = 0x21; // 通道模式配置为输入,接编码器,滤波器 4 时钟
PWMACCMR2 = 0x21;
PWMACCER1 = 0x55; // 配置通道使能和极性
PWMACCER2 = 0x55;
PWMASMCR = 0x03;// 编码器模式 3
1. PWMACCMR1/2 配置分析
0x21 表示将通道配置为 输入模式,滤波器长度为 4 个系统时钟周期。
正确配置了输入滤波器,可以有效防止信号抖动。
2. PWMACCER1/2 配置分析
0x55 表示使能通道 1~4,且所有通道设置为上升沿触发。
这里需要注意:在编码器模式下,极性设置必须与信号的实际相位匹配,否则可能导致边沿无法识别。
3. PWMASMCR 配置分析
你尝试了三种模式:
0x01:编码器模式 1(仅 A 通道边沿计数)
0x02:编码器模式 2(仅 B 通道边沿计数)
0x03:编码器模式 3(A 和 B 的上升沿和下降沿都计数)
根据 STC32G 的参考手册,编码器模式 3 应该对应 4 倍频功能。但你在实际测试中未能实现,说明配置可能存在问题。
三、可能的问题点与解决方案
1. 引脚配置错误
你配置了 P6M1 = 0xFF,P6M0 = 0x00,即所有 P6 口设置为 准双向口,但编码器信号输入通常需要 输入模式(高阻态)。
建议改为:
c
P6M1 = 0x00; // 设置为输入模式
P6M0 = 0x00;
或根据实际引脚功能,设置为 高阻输入模式,以避免内部上拉影响编码器信号电平。
2. PWMAENO 配置是否正确?
你注释中提到:
c
// 配置成 TRGI 的 pin 需关掉 ENO 对应 bit 并配成 input
PWMAENO = 0x00;
这说明你可能将某些 PWM 引脚复用为 TRGI(触发输入)使用。请确认:
是否将编码器信号连接到了支持编码器接口的通道?
是否关闭了对应的 ENO 位,避免输出干扰?
3. PWMASMCR 是否正确启用编码器模式?
你配置了:
c
PWMASMCR = 0x03; // 编码器模式 3
但需要注意:编码器模式必须与计数器方向控制配合使用。请确认:
是否清除了 DIR 位(计数方向)?
是否设置了正确的时钟源?
建议初始化时加上:
c
PWMACR1 = 0x00; // 清除原有配置
PWMACR1 |= 0x01; // 启用计数器
4. 中断处理是否正确?
你启用了中断:
c
PWMAIER = 0x02; // 使能中断
但未提供中断服务函数。建议检查:
是否编写了中断服务函数?
是否读取了状态寄存器(PWMAISR)并清除标志位?
是否在中断中更新了计数值?
5. 硬件连接是否正确?
编码器信号是否稳定?
是否存在信号干扰?是否使用屏蔽线?
是否在编码器信号端加了上拉电阻?
建议使用示波器观察编码器 A/B 信号的波形,确认其相位差为 90°,频率是否符合预期。
四、建议的配置流程
以下是建议的编码器接口初始化流程:
c
void PWMConfig()
{
EAXFR = 1; // 扩展寄存器访问使能
// 设置 P6 为输入模式
P6M1 = 0x00;
P6M0 = 0x00;
// 复用PWM1P和PWM2P到P60和P62
PWMAPS = 0x0A;
// 关闭 ENO 输出,防止干扰
PWMAENO = 0x00;
// 清空预分频寄存器
PWMAPSCRH = 0x00;
PWMAPSCRL = 0x00;
// 配置通道为输入模式,滤波器长度为 4 个系统时钟
PWMACCMR1 = 0x21;
PWMACCMR2 = 0x21;
// 使能通道并设置为上升沿触发
PWMACCER1 = 0x55;
PWMACCER2 = 0x55;
// 启用编码器模式 3(4 倍频)
PWMASMCR = 0x03;
// 使能中断(可选)
PWMAIER = 0x02;
// 启动计数器
PWMACR1 |= 0x01;
EA = 1; // 开启全局中断
}
五、中断服务函数建议
c
void PWMISR(void) interrupt 16
{
if (PWMAISR & 0x02) // 检查是否为更新中断
{
cntL = PWMACNTRL; // 读取低字节
cntH = PWMACNTRH; // 读取高字节
PWMAISR &= ~0x02; // 清除中断标志
}
}
六、总结
| 问题点 | 分析 | 建议 |
|--------|------|------|
| 引脚配置 | P6 设置为准双向口可能导致输入干扰 | 改为输入模式(P6M1=0x00, P6M0=0x00) |
| PWMAENO | 未明确关闭 ENO 输出 | 确保 ENO 对应位为 0 |
| PWMASMCR | 设置为编码器模式 3,理论上支持 4 倍频 | 检查是否与其他寄存器冲突 |
| 中断配置 | 启用了中断但未提供中断处理函数 | 补充中断服务函数并清除标志 |
| 硬件连接 | 未提及信号稳定性 | 使用示波器检查 A/B 相位和频率 |
如果你能提供更详细的硬件连接图、编码器型号、以及当前计数值变化的测试数据,我可以进一步帮你分析是否是硬件或软件配置问题。
希望以上分析对你有所帮助,祝你调试顺利!
如有其他问题,欢迎继续交流。
[本文内容由国芯人工智能辅助生成,仅供参考] 首先是需要设置PWMA_ARR的值为转一圈的最大值,例如1200线的设置最大值为(4800-1),-1是因为计数器从零开始计数,不设置这个,会导致PWMA_CNT无法增长
PWM外设确实可以做到四倍频计数,只需要设置模式3即可
至于你说的设置三个都一样,是因为需要读的寄存器是PWMA_CNTH和PWMA_CNTL这两个寄存器,我看你发的程序读的是PWMA_CCR1寄存器,这个显然是不对的,需要改动一下
王昱顺 发表于 2025-10-17 10:50
首先是需要设置PWMA_ARR的值为转一圈的最大值,例如1200线的设置最大值为(4800-1),-1是因为计数器从零开 ...
谢谢王工{:4_196:},我试一下 王昱顺 发表于 2025-10-17 10:50
首先是需要设置PWMA_ARR的值为转一圈的最大值,例如1200线的设置最大值为(4800-1),-1是因为计数器从零开 ...
你好王工,我找到原因了,读取 PWMA_CCR的值也可以实现4倍频,问题出在编码器模式3的情况下,已经实现4倍频的功能了,但是中断还是按编码器脉冲数进的,我是1200线的编码器,不管哪种模式,旋转一圈都是进1200次中断,我之前的程序不是读的寄存器的值,而是自己定义了一个变量,进入中断更改变量的值,导致三种模式读数都一样。现在实现4倍频了,但还是有问题,我想监控4倍频之后每一个数据的值,查询的方式不够及时,有没有办法在中断中能读到4倍频后的所有值 siiuwyhw 发表于 2025-10-19 21:25
你好王工,我找到原因了,读取 PWMA_CCR的值也可以实现4倍频,问题出在编码器模式3的情况下,已经实现4倍 ...
可以尝试使用TIE触发中断,每次触发的时候都会中断
页:
[1]