如果PWM还有剩余,启动一路PWM,不输出,占空比50%,周期中间的跳变允许中断,就是对应周期的一半。 ...
梁工,咨询一下,ST15W4K系列,PWM发生器,可以利用中断来判断PWM产生个数吗?我想用PWM来做电机加减速,目前尝试了,中断里面累加的个数和实际产生个数差好远 glint112 发表于 2023-8-25 15:49
梁工,咨询一下,ST15W4K系列,PWM发生器,可以利用中断来判断PWM产生个数吗?我想用PWM来做电机加减速, ...
使用PCA来做,请参考:
步进电机驱动 程序, 直接驱动, 或驱动步进电机驱动器 一共8个程序
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=2160
(出处: 国芯论坛-STC全球32位8051爱好者互助交流社区)
本帖最后由 glint112 于 2023-8-28 17:17 编辑
梁工 发表于 2023-8-25 20:29
使用PCA来做,请参考:
步进电机驱动 程序, 直接驱动, 或驱动步进电机驱动器 一共8个程序
https://www.st ...
试了前面4个程序,没输出脉冲{:cry:}
我用的芯片型号 : IAP15F2K61S2
之前想用PWM输出超过200Khz的脉冲,中断里控制输出5000个脉冲,但是实际出来2W多个
以下是我目前的代码:
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
#define CYCLE 0x10L //定义PWM周期
long count=0;
sfr PIN_SW2 = 0xba;
void pwm_isr() interrupt 22 using 1
{
static bit dir = 1;
static int val = 0;
if (PWMIF & 0x40)
{
PWMIF &= ~0x40;
}
count++;
if(count >5000)
{
PWMCR = 0x01; //关闭PWM信号输出
}
}
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
P7M0 = 0x00;
P7M1 = 0x00;
PIN_SW2 |= 0x80; //使能访问XSFR
PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
PWMCKS = 0x00; //选择PWM的时钟为Fosc/1
PWMC = CYCLE; //设置PWM周期
PWM2T1 = CYCLE/2; //设置PWM2第1次反转的PWM计数
PWM2T2 = CYCLE/2; //设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM2CR = 0x05; //选择PWM2输出到P3.7,不使能PWM2中断 T1翻转中断
PWMCR = 0x01; //使能IO口PWM信号输出
PWMCR |= 0x40; //使能PWM归零中断
PIN_SW2 &= ~0x80;
EA = 1;
PWMCR |= 0x80; //开启计数
while (1);
}
梁工 发表于 2023-8-25 20:29
使用PCA来做,请参考:
步进电机驱动 程序, 直接驱动, 或驱动步进电机驱动器 一共8个程序
https://www.st ...
大神,帮忙看下这个程序为啥中断控制5000个脉冲,但实际输出了2W多个(用的是芯片 IAP15W4K61S4)
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
#define CYCLE 0x10L //定义PWM周期
long count=0;
sfr PIN_SW2 = 0xba;
void pwm_isr() interrupt 22 using 1
{
static bit dir = 1;
static int val = 0;
if (PWMIF & 0x40)
{
PWMIF &= ~0x40;
}
count++;
if(count >5000)
{
PWMCR = 0x01; //关闭PWM信号输出
}
}
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
P7M0 = 0x00;
P7M1 = 0x00;
PIN_SW2 |= 0x80; //使能访问XSFR
PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
PWMCKS = 0x00; //选择PWM的时钟为Fosc/1
PWMC = CYCLE; //设置PWM周期
PWM2T1 = CYCLE/2; //设置PWM2第1次反转的PWM计数
PWM2T2 = CYCLE/2; //设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM2CR = 0x45; //选择PWM2输出到P3.7,不使能PWM2中断 T1翻转中断
PWMCR = 0x01; //使能IO口PWM信号输出
PWMCR |= 0x40; //使能PWM归零中断
PWM4CR = 0x45;
PIN_SW2 &= ~0x80;
EA = 1;
PWMCR |= 0x80; //开启计数
while (1);
}
glint112 发表于 2023-8-29 08:37
大神,帮忙看下这个程序为啥中断控制5000个脉冲,但实际输出了2W多个(用的是芯片 IAP15W4K61S4)
PWM周期太短(才16个时钟),中断会忙不过来的,进入中断就可能超过16个时钟了。
你将PWM周期设置为100以上试试。 梁工 发表于 2023-8-29 10:22
PWM周期太短(才16个时钟),中断会忙不过来的,进入中断就可能超过16个时钟了。
你将PWM周期设置为100 ...
试了一下,的确把PWM周期改大就可以了。
然后试验了一下,大概CYCLE =0xB2左右就可以统计,好奇为啥处理个中断要178(0xB2)个时钟 glint112 发表于 2023-8-29 17:11
试了一下,的确把PWM周期改大就可以了。
然后试验了一下,大概CYCLE =0xB2左右就可以统计,好奇为啥处 ...
你的变量 count定义的是long型,无符号长整形,4个字节, count++要操作4个字节, if(count >5000)也要做两个4字节有符号变量减法再判断,所以耗时,还有进入、退出中断、现场保护、现场恢复等等都要指令,看一下反汇编就会明白。178个时钟,如果是30MHz时钟,就是6us左右。
页:
1
[2]