找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5145|回复: 13
打印 上一主题 下一主题
收起左侧

关于51单片机输出PWM波的问题

  [复制链接]
跳转到指定楼层
楼主
我用51单片机输出PWM时, 将PWM输出部分放在中断服务函数里面可以正常输出; 但是如果放在其他部分就不可以了。这是为什么呢?

即, 如下方式可以正常输出PWM波。


即如下方式不能正常输出PWM波。




完整代码如下:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int


sbit s1 = P3^1;
sbit s2 = P3^2;
sbit PWM1 = P1^0;


int  count1 = 150;
int time;
void delay_ms(uint z)
{
    uint x,y;
    for(x = z;x > 0;x--)
    for(y = 114;y > 0;y--);
}


void init0()
{
    TMOD = 0x10;//定时方式一
    TH1 = (65536 - 10) / 256;
    TL1 = (65536 - 10) % 256;
    TR1 = 1;
        EA = 1;
        ET1 = 1;
}


void timer_inter() interrupt 3
{


    TH1 = (65536 - 10) / 256;
    TL1 = (65536 - 10) % 256;


        time++;




        if(time == 250)
        {
                time = 0;
        }
}


void control()
{
        if(s1 == 0)
        {
                delay_ms(10);
                if(s1 == 0)        
                {
                        count1 -= 50;
                }
                while(!s1);
        }
        if(s2 == 0)
        {        
                delay_ms(5);
                if(s2 == 0)
                {
                        count1+= 50;
                }
                while(!s2);
        }
          if(time <= count1)
        {
                PWM1 = 1;        
        }
        else
        {
                PWM1 = 0;
        }
}


void main()
{
        init0();
        while(1)
        {
                control();
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:253891 发表于 2017-11-26 20:17 | 只看该作者
不清楚,可能和c的规则有关系
回复

使用道具 举报

板凳
ID:235664 发表于 2017-11-26 20:55 | 只看该作者
Yusutitsa 发表于 2017-11-26 20:17
不清楚,可能和c的规则有关系

给了我希望又让我失望
回复

使用道具 举报

地板
ID:219796 发表于 2017-11-26 21:40 来自手机 | 只看该作者
while(!s1);while(!s2);去掉试试
回复

使用道具 举报

5#
ID:164602 发表于 2017-11-27 09:06 | 只看该作者
你的说法是不对的。
看我的程序:
#include<reg51.h>       
#define LED P2
unsigned int T=0,Tt=500,i=0,Ii=100,j=0;
bit A=1;
void TimeConfig();
void main(void)
{
        TimeConfig();
        while(1)
        {
                if (T>=Tt)
                {
                        T=0;
                }
                if (i>=Ii)
                {
                        i=0;
                        if (A==1)
                        {
                                j++;
                        }
                        else
                        {
                                j--;
                        }
                }
                if (j==Tt)
                {
                        A=0;
                }
                if (j==0)
                {
                        A=1;
                }
                if (T<=j)
                {
                        LED=0x00;
                }
                else
                {
                        LED=0xff;
                }
        }
}
void TimeConfig()
{
    TMOD = 0x01;
    TH0 = 0xff;       
    TL0 = 0xff;
    EA = 1;               
    ET0 = 1;       
    TR0 = 1;       
}

void Time0() interrupt 1
{
        TH0 = 0xff;         
    TL0 = 0xff;
        T++;               
        i++;
}

看出我们的程序有什么不同了没?

就是那点不同,却得到不同的结果。

分析程序可以知道:你和我都是用的time++,你用的判断是<=,我作的>=。我们都没有学汇编,对语句执行的时间不了解,中断在什么时候发生就不可预见。我的语句判断,是大了就怎么样,你的判断是小了就怎么样。大了,不论大多少,总是可以判断到的,而小了的判断,当数据大了后,就无法判断,这正是你的程序执行不了的原因。
回复

使用道具 举报

6#
ID:235664 发表于 2017-11-27 15:02 | 只看该作者
HC6800-ES-V2.0 发表于 2017-11-27 09:06
你的说法是不对的。
看我的程序:
#include       

首先谢谢你的解答。 但是 我是当它小了之后输出高电平, 大了之后输出低电平啊。 无论大小都可以检测到的啊。
回复

使用道具 举报

7#
ID:235664 发表于 2017-11-27 15:04 | 只看该作者
谢谢大家的解答, 我今天试的时候又可以输出PWM波了;我猜 是不是示波器的问题?  如果有知道答案的欢迎留言
回复

使用道具 举报

8#
ID:235664 发表于 2017-11-27 15:06 | 只看该作者
sldx 发表于 2017-11-26 21:40
while(!s1);while(!s2);去掉试试

这个是按键松手检测啊, 和定时器有什么问题吗? 就算程序一直卡在这里, 无法执行后面的, 但是也会进入中断服务函数的,  而且我是在 没有按按键的情况下输出不了PWM波(这个不好意思, 问题没有说清楚 /尴尬)
回复

使用道具 举报

9#
ID:508386 发表于 2019-7-7 08:25 | 只看该作者
sldx 发表于 2017-11-26 21:40
while(!s1);while(!s2);去掉试试

加上WHILE是因为等待按键结束,不过不加,就会一直判断按下,一直执行判断
回复

使用道具 举报

10#
ID:564631 发表于 2019-7-7 11:20 | 只看该作者
注意的是不断地产生中断,对于按键的判断还有外面的的执行有一定的影响,毕竟每次中断的时间都很短,所以建议在中断服务程序里面首先停止中断服务,等运行完任务后再开启,这样比较好
回复

使用道具 举报

11#
ID:332444 发表于 2019-7-7 12:36 | 只看该作者
按钮和PWM波都放到中断外,不要什么都往中断仍,中断越轻量级越好https://bbs.csdn.net/topics/392742676
回复

使用道具 举报

12#
ID:93224 发表于 2019-7-7 13:31 | 只看该作者
中断里面实时性高
回复

使用道具 举报

13#
ID:478635 发表于 2019-7-7 15:12 | 只看该作者
应该也可以的,只是时间不对了
回复

使用道具 举报

14#
ID:482935 发表于 2020-5-15 17:25 来自手机 | 只看该作者
你放到while(1)里就变成大概3微秒扫描到一次这部分,改变一次pwm高低信号 1或 0,你定时器里却要10微秒才改变一次单位步进值time,不同步了。按道理你10微秒time加1,和10微秒进来改变pwm信号要一起做。你分开扫描一个在主函数里很快做,一个在定时器里10微秒才做肯定不行。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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