使用梁工的8H-PWMA输出示例,增加一路,就不正常
个人使用的是:梁要发的一个实例,匹配翻转输出脉冲控制步进电机驱动器-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+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
使能了PWM3中断后有没有在中断函数里增加处理代码,并清除对应的中断标志?
没清中断标志的话会反复触发中断,从而占用大量系统资源。 //========================================================================
// 函数: 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; //设置目标频率, 开始减速
}
}
}
elseP_M1_PULSE = 1;
}
感谢关注回复,PWMA_SR1 = 0; //清除中断标志 这句话, 有清除中断的,是清除所有的中断了。问题好像不是这里造成的 乘风飞扬 发表于 2025-6-27 09:10
使能了PWM3中断后有没有在中断函数里增加处理代码,并清除对应的中断标志?
没清中断标志的话会反复触发中 ...
感谢关注,但问题好像不在这里。 再查下程序吧,每一路都可以独立输出的,我曾经做过8路的。 梁工 发表于 2025-6-27 11:18
再查下程序吧,每一路都可以独立输出的,我曾经做过8路的。
梁工,一直是用您的例程,改了很多实用的工程,可能还是我个人能力太弱了。但是搞了二天了,左右都在试,又用的AI编程找错。但是一直没搞好。还请您出手,就是在您的匹配翻转输出脉冲控制步进电机驱动器-STC8H-PWMA输出,这个示例上,怎么修改下,才到正常控二路电机就行了。现在用L1,20000,38400 控第一路好的,我用的是STC8H4K64TL,怎么实现L3,20000,38400 从PWM3p口再出一路可控脉冲。这个项目,就卡在 这{:baoquan:} 我上传的这个压缩包里,是在您 的示例基础上,增加成二路。关键的代码是下面
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; ,在使用第二路时,同理,这样实际电机,才正常运行。现在有什么办法,能同时打开,不用切换。 AHBbGao 发表于 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 --> 停止所有电机
******************************************/
感谢梁工百忙中抽时间给修改代码。
这个代码,我下载到了板子上经过试验。如果是在低速时比如发送L1,5000,38400两个电机,都是正常的。 但是如果速度提高,比如L1,10000,38400 两个电机就时不时的就不转了,只是发出嗯嗯的声音。
如果用你“匹配翻转输出脉冲控制步进电机驱动器-STC8H-PWMA输出” 这个例子,L1,20000,38400,速度达2W,电机都能正常运转的。感觉还是这两个中断产生了冲突造成,但一直没找到问题点。 AHBbGao 发表于 2025-6-27 16:33
感谢梁工百忙中抽时间给修改代码。
这个代码,我下载到了板子上经过试验。如果是在低速时比如发送L1,5000,3 ...
应该是你的电机不能高速,失步了。我的程序同时输出2路50KHz没有任何问题。
步进电机的转速,56~85电机一般600以下,36、42电机可以到1500转。
要高转速,就要高电压驱动,比如36V或48V,电流要设置3A以上。步进电机高转速时反电动势也高,电压低时(24V以下)力矩小,很容易失步。
页:
[1]