单片机的PWM输出死机
但是在实验的过程中出现了一个问题
当我的单片机不带负载的时候占空比能自动的增加,不会出现问题。
但是当接上负载之后占空比增加了几秒钟之后就停止了,类似于死机的样子。当我把负载卸掉,占空比又能自动增加了
我查了一下单片机的拉电流是20ma
下面是我写的一个自动加减占空比的程序
while (1)
{
if (signal == 1)
{
if(pwm<2000)
{
pwm+=10;
PWM_SetHighReg(pwm);
write_pwm(11,pwm);
delay_ms(500);
}
else
signal = 0;
}
else
{
if(pwm>50)
{
pwm-=10;
PWM_SetHighReg(pwm);
write_pwm(11,pwm);
delay_ms(500);
}
else
signal = 1;
}
建议LZ加段测试程序,看看加上负载后是不是程序跑飞了。
你说的测试程序是什么意思
因为我把程序烧录进去之后连上电机测试的,但是过了几秒钟后PWM的输出就暂停了。这时我把PWM的接线给分开。PWM的占空比又继续增加了。
我测试的时候是在PWM管脚引出两根线,一个给示波器一个给电机。是同时开始测试的
可能电流带不起,换上一个LED灯看看,要不就加反相器或达林顿管增大电流看看。
造成这个问题的有可能是硬件,也可能是软件,或者是两者交互作用下的结果。
5楼说的是个好方法——换轻一点的负载,看看是否工作正常,然后逐步加重负载。看看是不是有问题,如果有的话什么时候出现。
如果LZ方便的话,原理图也上一个?
负载太重,加三极管扩流。
我试了一下 是软件的原因 我尝试了只是发出PWM不计数的话就没有问题
我试了一下是加上计数之后程序给跑飞了 我写了一段程序 麻烦你给我看看
/*====================================================================*/
/*函数:unit read() */
/*描述:读取计数值 */
/*参数:无 */
/*返回:无 */
/*备注:无 */
/*====================================================================*/
unsigned int read()
{
unsigned char t1, th1, th2;
unsigned int val;
while(1)
{
th1 = TH0;
t1 = TL0;
th2 = TH0;
if(th1==th2)
break;
}
val=th1*256+t1;
return val;
}
这个是读出计数脉冲的次数
void t1(void) interrupt 3 using 0
{
TF1 = 0;
TH1 = 0x1C;
TL1 = 0x22;
timecount++;
if (timecount == 25) //0.5s计时
{
TR1 = 0; //关闭定时器1,为了读出计数器0计数个数
timecount = 0;
x = read();
write_count(11,x);
TH0 = 0; //计数器初值清零
TL0 = 0;
TR0 = 1; //重新启动计数器0
TR1 = 1;
}
}
这个是一个中断程序每隔0.5S读一次计数数据
我前面的程序还定义了一个PCA的中断
我用的是35M的晶振, 我用一个管脚发出来20KHZ的PWM,用P3.4再把他显示出来
就是不知道程序哪里出了问题
非常可能是中断服务程序的问题。在中断服务程序中,要执行只与该中断至关重要的操作,而该操作耗时也要尽可能的短。如果相关操作耗时比较长,可以考虑向主循环发送一个消息(比如某个标志位置位,操作执行完后复位),然后尽快退出中断服务程序。
貌似你的程序很有可能是中断重入的问题——就是中断服务程序没有执行完,这个中断请求又来了。
void t1(void) interrupt 3 using 0
{
TF1 = 0;
TH1 = 0x1C;
TL1 = 0x22;
timecount++;}
我的这个也就是单独的一个中断
if (timecount == 25) //0.5s计时
{
TR1 = 0; //关闭定时器1,为了读出计数器0计数个数
timecount = 0;
x = read();
write_count(11,x);
TH0 = 0; //计数器初值清零
TL0 = 0;
TR0 = 1; //重新启动计数器0
TR1 = 1;
}
也就是说我要把这部分写在程序的里面,我的主程序里面加了4个按键的判断来增加PWM的占空比
不是很理解程序结构是如何组织的,但从9楼的代码中可以看出中断服务程序中调用了 read(),而这个函数有可能消耗非常长的运行时间,从而使得中断服务程序有可能未能及时退出。如果是这种情况,用仿真 (Simulation) 应该就可以看到问题症结所在。
