微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 单片机的PWM输出死机

单片机的PWM输出死机

时间:10-02 整理:3721RD 点击:
我用STC的单片机输出一个17K的PWM波形。 我写了一个程序让PWM自己增加占空比。  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) 应该就可以看到问题症结所在。

上一篇:protel中元件名称
下一篇:求教C语言编程

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top