找回密码
 立即注册
查看: 35|回复: 9

使用梁工的8H-PWMA输出示例,增加一路,就不正常

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 前天 23:39 | 显示全部楼层 |阅读模式
个人使用的是:梁要发的一个实例,匹配翻转输出脉冲控制步进电机驱动器-STC8H-PWMA输出
单独用这个是正常的,我现在在它基础上,再增加一个输出,原来是1P口输出脉冲。现在我在3P口也要输出一个可控的脉冲。
但是现在只要 使用了PWMA_IER   |= 0x08;            // 使能中断,第三路的中断,程序就不正常了。
就是使用L1,10000,38400 这个命令,在没见有PWMA_IER   |= 0x08;这句话时,我的实物电机转的都正常。一旦加上这句,实物电机,就不转
或是卡卡的,或是力度很小。
主要代码如下:
//========================================================================
// 函数: void PWMA_config(void)
// 描述: PPWM配置函数。
// 参数: noe.
// 返回: none.
// 版本: V1.0, 2021-5-10
// 备注:
//========================================================================
void PWMA_config(void)
{
    P_SW2 |= 0x80;        //SFR enable   

    PWMA_PSCR   = 1;    // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0]+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
    PWMA_DTR    = 0;    // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,  
                        //                0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
    PWMA_ARR    = 0xffff;    // 自动重装载寄存器,  控制PWM周期
    PWMA_CCER1  = 0;
    PWMA_CCER2  = 0;
    PWMA_SR1    = 0;
    PWMA_SR2    = 0;
    PWMA_CCMR1  = 0;
    PWMA_CCMR2  = 0;
    PWMA_CCMR3  = 0;
    PWMA_CCMR4  = 0;
    PWMA_ENO    = 0;
    PWMA_PS     = 0;
    PWMA_IER    = 0;

    PWMA_CCR1   = 0;            // 计数器比较值, 匹配时刻
    PWMA_CCMR1  = (3<<4);        // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
    PWMA_CCER1 |= 0x07;            // 开启比较输出, 低电平有效
    PWMA_PS    |= 0;            // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
    PWMA_ENO   |= 0x01;            // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
    PWMA_IER   |= 0x02;            // 使能中断
   
    #ifdef MOT2
        PWMA_CCR3   = 0;            // 计数器比较值, 匹配时刻
        PWMA_CCMR3  = (3<<4);        // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
        PWMA_CCER2 |= 0x03;            // 开启比较输出, 低电平有效
        PWMA_PS    |= (0<<4);        // 选择IO, 0:选择P1.4 P1.5, 1:选择P2.4 P2.5, 2:选择P6.4 P6.5,
        PWMA_ENO   |= 0x10;            // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
        PWMA_IER   |= 0x08;            // 使能中断
    #endif

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2025-06-27 08:53:15
已绑定手机

40

主题

2078

回帖

7159

积分

论坛元老

积分
7159
发表于 昨天 09:10 | 显示全部楼层
使能了PWM3中断后有没有在中断函数里增加处理代码,并清除对应的中断标志?
没清中断标志的话会反复触发中断,从而占用大量系统资源。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 昨天 10:40 | 显示全部楼层
//========================================================================
// 函数: void PWMA_ISR(void) interrupt PWMA_VECTOR
// 描述: PWMA中断处理程序. 捕获数据通过 TIM1-> CCRnH / TIM1-> CCRnL 读取
// 参数: None
// 返回: none.
// 版本: V1.0, 2021-6-1
//========================================================================
void PWMA_ISR(void) interrupt PWMA_VECTOR
{
        u8        sr1;
        u8        sr2;
        sr1 = PWMA_SR1;        //为了快速, 中断标志用一个局部变量处理
        PWMA_SR1 = 0;        //清除中断标志
        sr2 = PWMA_SR2;        //为了快速, 中断标志用一个局部变量处理
        PWMA_SR2 = 0;        /清除中断标志
        sr1 &= PWMA_ISR_En;        //每个通道可以单独允许中断处理

        if(sr1 & 0x02)        //通道1中断标志
        {
                if(B_M1_RunEn)        //电机运行中
                {
                        if(B_f1_update)        //刷新频率值
                        {
                                B_f1_update = 0;
                                f1_period = f1_period_set;
                        }
                        CCAP1_tmp += f1_period;
                        PWMA_CCR1  = CCAP1_tmp;        // 计数器比较值, 匹配时刻
                        if(P_M1_PULSE)        //产生了完整的一个脉冲
                        {
                                if(M1_PulseCnt != 0)        // 脉冲数未完成
                                {
                                        if(--M1_PulseCnt == 0)        //若 脉冲数-1 == 0
                                        {
                                                B_M1_RunEn = 0;                // 关停电机
                                                P_M1_DIR   = 1;                // 转向光耦关闭
                                                PWMA_CCMR1 = 0;                //禁止取反输出脉冲
                                        }
                                }
                                if(M1_DownCnt != 0)                // 减速脉冲未完
                                {
                                        if(--M1_DownCnt == 0)        f1_set = 200;        //设置目标频率, 开始减速
                                }
                        }
                }
                else  P_M1_PULSE = 1;
        }

感谢关注回复,PWMA_SR1 = 0;        //清除中断标志 这句话, 有清除中断的,是清除所有的中断了。问题好像不是这里造成的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 昨天 10:41 | 显示全部楼层
乘风*** 发表于 2025-6-27 09:10
使能了PWM3中断后有没有在中断函数里增加处理代码,并清除对应的中断标志?
没清中断标志的话会反复触发中 ...

感谢关注,但问题好像不在这里。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:106
  • 最近打卡:2025-06-28 00:08:16

74

主题

6160

回帖

1万

积分

超级版主

积分
12921
发表于 昨天 11:18 | 显示全部楼层
再查下程序吧,每一路都可以独立输出的,我曾经做过8路的。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 昨天 13:53 | 显示全部楼层
梁*** 发表于 2025-6-27 11:18
再查下程序吧,每一路都可以独立输出的,我曾经做过8路的。

梁工,一直是用您的例程,改了很多实用的工程,可能还是我个人能力太弱了。但是搞了二天了,左右都在试,又用的AI编程找错。但是一直没搞好。还请您出手,就是在您的匹配翻转输出脉冲控制步进电机驱动器-STC8H-PWMA输出,这个示例上,怎么修改下,才到正常控二路电机就行了。现在用L1,20000,38400 控第一路好的,我用的是STC8H4K64TL,怎么实现L3,20000,38400 从PWM3p口再出一路可控脉冲。这个项目,就卡在 这

tft_-motore.7z

361.58 KB, 下载次数: 0

2路代码

点评

程序中我保留另外3路的初始化,只是注释掉了而已!按照通道1拷贝整理一下即可。 我花了20分钟拷贝了通道3,使用方法一样。 /************* 功能说明 ************** 用高级PWMA匹配取反输出脉冲控制步进电机驱动器  详情 回复 发表于 昨天 15:43
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 昨天 14:17 | 显示全部楼层
我上传的这个压缩包里,是在您 的示例基础上,增加成二路。关键的代码是下面
        PWMA_CCR1   = 0;                        // 计数器比较值, 匹配时刻
//        PWMA_CCMR1  = (3<<4);                // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
        PWMA_CCER1 |= 0x07;                        // 开启比较输出, 低电平有效
        PWMA_PS    |= 0;                        // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
        PWMA_ENO   |= 0x01;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
//        PWMA_IER   |= 0x02;                        // 使能中断



        PWMA_CCR3   = 0;                        // 计数器比较值, 匹配时刻
//        PWMA_CCMR3  = (3<<4);                // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
        PWMA_CCER2 |= 0x07;                        // 开启比较输出, 低电平有效
        PWMA_PS    |= (0);                // 选择IO, 0:选择P1.4 P1.5, 1:选择P2.4 P2.5, 2:选择P6.4 P6.5,
        PWMA_ENO   |= 0x10;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
        PWMA_IER   |= 0x08;                        // 使能中断
PWMA_IER   |= 0x02;        PWMA_IER   |= 0x08;        这两个中断,不能同时开启,在使用第1路时,启用PWMA_IER   |= 0x02;  删掉PWMA_IER   |= 0x08;           ,在使用第二路时,同理,这样实际电机,才正常运行。现在有什么办法,能同时打开,不用切换。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:106
  • 最近打卡:2025-06-28 00:08:16

74

主题

6160

回帖

1万

积分

超级版主

积分
12921
发表于 昨天 15:43 | 显示全部楼层
AHBb*** 发表于 2025-6-27 13:53
梁工,一直是用您的例程,改了很多实用的工程,可能还是我个人能力太弱了。但是搞了二天了,左右都在试, ...

程序中我保留另外3路的初始化,只是注释掉了而已!按照通道1拷贝整理一下即可。
我花了20分钟拷贝了通道3,使用方法一样。


/*************        功能说明        **************
用高级PWMA匹配取反输出脉冲控制步进电机驱动器.

为了简单, 利于初学者, 本例使用线性加减速, 如要使用别的加减速算法, 用户自行设计.

使用外设:
Timer0: 工作于1ms中断, 提供1ms时隙标志和串口超时处理.
Timer2: 串口1波特率.
串口1:  命令控制, 串口设置115200,8,1,n.
PWMA1P: 从P1.0输出驱动脉冲, 低驱动, 接步进电机驱动器脉冲输入端(一般是光耦输入, 低有效).
        从P1.1输出转向信号, 接步进电机驱动器方向输入端(一般是光耦输入, 低有效), 1:顺时针(正转), 0:逆时针(反转).

PWMA3P: 从P1.4输出驱动脉冲, 低驱动, 接步进电机驱动器脉冲输入端(一般是光耦输入, 低有效).
        从P1.5输出转向信号, 接步进电机驱动器方向输入端(一般是光耦输入, 低有效), 1:顺时针(正转), 0:逆时针(反转).

串口命令设置:
L1,500,1000   --> 电机1以500Hz正转1000个脉冲, 脉冲数为0则连续转动.
R1,500,1000   --> 电机1以500Hz反转1000个脉冲, 脉冲数为0则连续转动

L3,500,1000   --> 电机3以500Hz正转1000个脉冲, 脉冲数为0则连续转动.
R3,500,1000   --> 电机3以500Hz反转1000个脉冲, 脉冲数为0则连续转动

s             --> 停止所有电机

******************************************/



24A-PWMA-匹配翻转输出脉冲控制2个步进电机驱动器.rar (219.21 KB, 下载次数: 2)


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-27 10:40:40

6

主题

19

回帖

172

积分

注册会员

积分
172
发表于 昨天 16:33 | 显示全部楼层
感谢梁工百忙中抽时间给修改代码。
这个代码,我下载到了板子上经过试验。如果是在低速时比如发送L1,5000,38400  两个电机,都是正常的。 但是如果速度提高,比如L1,10000,38400   两个电机就时不时的就不转了,只是发出嗯嗯的声音。
如果用你“匹配翻转输出脉冲控制步进电机驱动器-STC8H-PWMA输出” 这个例子,L1,20000,38400  ,速度达2W,电机都能正常运转的。感觉还是这两个中断产生了冲突造成,但一直没找到问题点。

点评

那是你的电机不能高速,失步了。 步进电机的转速,56~85电机一般600以下,36、42电机可以到1500转。  详情 回复 发表于 昨天 19:38
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:106
  • 最近打卡:2025-06-28 00:08:16

74

主题

6160

回帖

1万

积分

超级版主

积分
12921
发表于 昨天 19:38 | 显示全部楼层
AHBb*** 发表于 2025-6-27 16:33
感谢梁工百忙中抽时间给修改代码。
这个代码,我下载到了板子上经过试验。如果是在低速时比如发送L1,5000,3 ...

应该是你的电机不能高速,失步了。我的程序同时输出2路50KHz没有任何问题。
步进电机的转速,56~85电机一般600以下,36、42电机可以到1500转。
要高转速,就要高电压驱动,比如36V或48V,电流要设置3A以上。步进电机高转速时反电动势也高,电压低时(24V以下)力矩小,很容易失步。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-28 13:14 , Processed in 0.317893 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表