| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 601 人关注过本帖
标题:8051的問題,可以的話請幫幫忙
只看楼主 加入收藏
kkdc0426
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2012-9-11
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:1 
8051的問題,可以的話請幫幫忙
以下是我自已寫出來的程式,但是,PWM在Low的時候不是為0(約1%),high的時候也不是完全為1(約99%左右),
可否有人教學一下,如何修改會比較好些

//硬體:P0接LED共陽,P1接SW落地
//目的:按SW,LED燈漸亮,再按一次,LED漸滅
//ok

#include <C8051F330.h>

sbit P10 = P1^0;

char one=0;
char zero=0;
unsigned char KeyTemp=0xff;
unsigned char KeyData=0xff;
unsigned char a;

void delay(unsigned int t);

void main(void)
{
    void KeyScan(void);                      //呼叫按鍵掃描函數
    unsigned int CYCLE=1000,PWM_LOW=1;
    PCA0MD &= ~0x40;                      //關看門狗
    XBR1 = 0x40;                          //Cossbar Enable
    while(1)
    {
        KeyScan();                        //掃描按鍵
        if(KeyData!=0xff)                 //按下任何按鍵
        {
            a++;
            if(a>1)
            a=0;
            KeyData=0xff;
        }
        if(a==0x00)
        {
            
            P0=0x00;
            delay(PWM_LOW);
            P0=0xff;
            delay(CYCLE-PWM_LOW);
            PWM_LOW--;
            if(PWM_LOW<=0)
                PWM_LOW++;
        }
        else if(a==0x01)
        {
            P0=0x00;  
            delay(PWM_LOW);
            P0=0xff;
            delay(CYCLE-PWM_LOW);
            PWM_LOW++;
            if(PWM_LOW>=999)
                PWM_LOW--;
        }
    }
}

void KeyScan(void)                   //按鍵掃描函數
{
    bit KeyStatus;                   //按鍵狀態
    P10=1;                           //設定P10為輸入
    KeyStatus=~P10;                  //反相讀取按鍵狀態
    if(KeyStatus!=0)                 //按下?
    {
        one=0;
        if(KeyTemp!=KeyStatus)       //與上次所讀的鍵值不同?
        {
            KeyTemp=KeyStatus;       //儲存新鍵值
            zero=1;                  //設定zero=1
        }  
        else                         //與上次所讀的鍵值相同
        {
            if(zero<5)               //zero<5?
            {
                zero+=1;             //zero+1
                if(zero==5)          //zero=5?
                KeyData=KeyTemp;     //按鍵已除彈跳
            }        
        }   
    }   
    one+=1;
    if(one==5)                       //按鍵已放開
    {   
        zero=0;
        KeyTemp=0xff;                //清除按鍵值
        KeyData=0xff;                //清除按鍵值
    }
}

void delay(unsigned int t)
{
    while(--t);
}
搜索更多相关主题的帖子: 如何 include void 
2012-09-18 11:09
stophin
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:227
专家分:618
注 册:2010-3-26
收藏
得分:20 
楼主两个if语句里面有些问题,我举例来说,就拿PWM不是完全为0来说
初始化后如果不按任何按钮,进入第一个if的循环,这里面,PWM_LOW一直保持为1,
P0=0x00;
delay(PWM_LOW);
P0=0xff;
delay(CYCLE-PWM_LOW);
这里P0=0x00后,虽然PWM_LOW为1,delay里面while循环很短暂,但是实际上灯仍旧点亮了一下,
所以看到很暗的灯光。这里即使PWM_LOW=0,delay循环不起作用,这种现象仍然会出现,
这是因为你是在几个个机器周期(也就是delay那里)里面对灯进行的开-关操作。
这里除非你写成
P0=0x00;
P0=0xff;
这样,一些好的编译器才会将你的代码优化成一个语句:P0=0xff;。但如果中间插入了delay,
再好的编译器也不会为你优化。所以我们只好自己优化,看代码:
程序代码:
if (a==0)
{
    if (PWM_LOW-1)    //这里解决上面说的PWM_LOW=1的循环问题,如果PWM_LOW=1,那么就不点亮它,只灭掉他就行了(使用下面的if语句)
    {
    P0=0x00;        //点亮灯,不管之前的状态
    if (PWM_LOW-CYCLE)    //如果PWM_LOW=CYCLE循环了怎么办?(这种情况只有a=1时才出现,这样写是为了使a=1和a=0的代码保持一致,
        delay(PWM_LOW);    //但对a=0时不会有什么影响)那就不要延迟它,否则会影响到按键的检测
    }
    if (PWM_LOW-CYCLE)    //如果(a=1时)PWM_LOW=CYCLE循环了,那么就不灭掉他,使用上面的if语句来持续点亮它
    {
    P0=0xff;        //关闭灯,同样不管之前的状态
    if (PWM_LOW-1)      //如果PWM_LOW=1循环,则同样不延迟它,只灭掉它就可以了
        delay(CYCLE-PWM_LOW); 
    }
    PWM_LOW--;        //这里如果PWM_LOW=1,那么如果a一直为0,PWM_LOW减了后再加仍旧为1,构成一个PWM_LOW=1的循环
    if (PWM_LOW<=0)       
    PWM_LOW++;
}

对比楼主你的原码,当PWM_LOW不为1或CYCLE时,剔除if语句后,仍旧是楼主你的原来那四句代码。这就是所谓的"边缘检测"吧 : 0
a=1的情况和上面的类似,注意后面改成PWM_LOW++和判断语句PWM_LOW>=CYCLE以及PWM_LOW--。
也可以把上面的除PWM_LOW更改之外的两个if代码做成一个函数来调用更方便些
好吧说了这么多,乱的很,不知道楼主能不能看懂
2012-09-18 14:27
快速回复:8051的問題,可以的話請幫幫忙
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028183 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved