打印

新人第一条,求简单程序的讲解(注释)

[复制链接]
2381|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沁雨飞扬|  楼主 | 2010-5-21 07:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 沁雨飞扬 于 2010-5-21 07:18 编辑

不晓得为什么管理员要设置23点至7点不能发帖,苦苦等到7点以后才能发帖!

      下面是求教的内容,是课堂实验要求,别人的程序,新手的我相当不明白,故来论坛请教各位学长学姐!希望大家尽情的注释和讲解以及程序的改进!实验室里用的是THGQC-1型嵌入式单片机实验开发系统!再次谢谢各位!


#include<c8051f020.h>

void yanshi( unsigned int x)//延时程序
{

unsigned
char i;

while (x--)

{ for(i=0;i<125;i++)

{;}

}
}
void main()
{

unsigned char key=0;

WDTCN=0XDE;//禁止看门狗

WDTCN=0XAD;

OSCXCN=0X65;//外部晶振

yanshi(1);//延时1ms

OSCICN=OSCICN|0X08;

XBR2=0X40;

P1MDOUT=0X00;//p1输入

P2MDOUT=0XFF;//p2输出

P2=0XFF;

while (1)

{

if (P1!=0xFF)//检测是否有输入

{

yanshi(10);


if(P1!=0xFF) //再次检测是否有输入


{


key=P1;

while(P1!=0xFF)

switch(key)

{


case 0xFE: P2=0xFE;break;//按下KEY1L0

case 0xFD: P2=0xF9;break;//按下KEY2,L1,L2

case 0xFB: P2=0xE3;break;//按下KEY3,L3,L4,L5

case 0xF7: P2=0xFF;break;//按下KEY4,等灭

default:
break;

}

}

}
}


}

相关帖子

沙发
ZRL700424| | 2010-5-21 08:44 | 只看该作者
1,估计是管理员怕大家熬夜把身体搞垮;

2,我也是相当不明白,你要问什么?

使用特权

评论回复
板凳
zq1987731| | 2010-5-21 09:31 | 只看该作者
个人认为,这程序只有拿来玩玩以及忽悠老师的价值...
1,yanshi(10);→这种函数纯粹就是在浪费CPU时间,坚决禁止
2,while(P1!=0xFF)→这种程序结构相当之不可靠,如果你按键坏了一个(按下去上不来)的情况该怎么办?
3,风格比较混乱...嫌麻烦的话可以用SlickEdit的Beautify功能自动排版(下面这段我就是这么干的)

#include <c8051f020.h>

void yanshi( unsigned int x)//延时程序
{
    unsigned char i;
    while (x--)             /*纯粹就是在浪费的时间,具体延时多久可以到Keil仿真下面插2个断点看*/
    {
        for(i=0;i<125;i++)
        {
            ;
        }
    }
}
void main()
{
    unsigned char key=0;
    WDTCN=0XDE; //禁止看门狗
    WDTCN=0XAD;
    OSCXCN=0X65;//外部晶振
    yanshi(1);  //延时1ms
    OSCICN=OSCICN|0X08;
    XBR2=0X40;
    /*上面几句是在初始化单片机时钟部分及相关寄存器,下面几句是IO口配置*/
    P1MDOUT=0X00;//p1输入
    P2MDOUT=0XFF;//p2输出
    P2=0XFF;
                    
    /*主循环开始,通过P1口连接的按键输入情况选择switch分支下的一条执行*/
    while (1)
    {
        if (P1!=0xFF)       //检测是否有输入
        {
            yanshi(10);     /*延时程序调用,目的在于消抖*/
            if (P1!=0xFF)   //再次检测是否有输入
            {
                key=P1;     /*将当前键值暂存*/  
                while(P1!=0xFF)     /*按下的按键如果不放开则一直执行下面的switch语句*/   
                    switch (key)    /*通过暂存的键值决定采取的操作*/
                    {
                    case 0xFE: P2=0xFE;break;//按下KEY1,L0亮
                    case 0xFD: P2=0xF9;break;//按下KEY2,L1,L2亮
                    case 0xFB: P2=0xE3;break;//按下KEY3,L3,L4,L5亮
                    case 0xF7: P2=0xFF;break;//按下KEY4,等灭
                    default:
                        break;
                    }
            }
        }
    }
}

使用特权

评论回复
地板
沁雨飞扬|  楼主 | 2010-5-21 21:20 | 只看该作者
3# zq1987731
嗯,谢谢您的讲解啊!C语言部分我懂,搞不懂的就是您所说的“上面几句是在初始化单片机时钟部分及相关寄存器,下面几句是IO口配置”这一段,譬如说看门狗怎么用,为什么用······再次谢谢哈!

使用特权

评论回复
5
沁雨飞扬|  楼主 | 2010-5-21 21:23 | 只看该作者
2# ZRL700424
我只学过C语言,C语言部分懂,其他涉及单片机的就零基础了·····谢谢啊!

使用特权

评论回复
6
zq1987731| | 2010-5-21 23:10 | 只看该作者
看门狗...就是个定时器,分为外部看门狗和内部看门狗
原理就是不断地累加,比如将看门狗复位门限时间值设置为10000,从0累加到这数字需要10秒
那么你程序中就10秒内必须要将这个数字清0,如果超时...使其超过10000产生溢出的话...
外部看门狗会直接给你单片机的RST脚发送复位信号,内部看门狗则采用软复位机制模拟个复位信号
操作起来也就是——设置看门狗复位时间+使能看门狗(启动),比如你程序中用到的WDTCN,这个寄存器每个bit对应什么功能你到单片机对应的Datasheet上一查就明白了

c8051f020系列我没用过,但从开头就能推测出,这是在配置时钟源,该单片机应该是内部集成了一个振荡器
OSCXCN=0X65;//外部晶振    →这句就是由内部振荡器切换到外部时钟源
yanshi(1);  //延时1ms    →为了使外部晶振稳定,比如涉及到PLL什么的(貌似这里没有)

输入输出口的话很多单片机都需要额外配置,输入口的属性常见的就是模拟输入、上/下拉输入,输出口属性常用的有推挽输出以及开漏/开集输出,其中开漏输出在输出高电平时通常是可以进行读操作的...

真要细说的话东西多了去了,如果你多钻研下书本就会发现,前人总结的已经足够多了...

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
原野之狼 + 2
7
沁雨飞扬|  楼主 | 2010-5-23 07:47 | 只看该作者
6# zq1987731
再问一句
  • P1MDOUT=0X00;//p1输入   为什么这个是按键的输入,用的是P1MDOUT
  •                                      而不是P1MDIN啊???是你所说的推免吗?
  •                                      是不是换成P1MDIN=0XFF也行啊?
  •     P2MDOUT=0XFF;//p2输出

使用特权

评论回复
8
NE5532| | 2010-5-23 08:20 | 只看该作者
没规定过程序不允许这样写延时哈,比如12M的51,延时5uS,不用这个写,又怎么写呢?只是说写长延时的时候,要注意CPU的占用罢了,如果还有其他事情要做,就要用定时器来写。

另外FF的问题,3楼的说**确,但是理由不对,按钮坏了就得修,不管是哪个啦。这里应该使用位操作,因为可能有多个按钮同时按下,而其他按钮是负责其他控制的情况出现,所以你只应该关注控制自己的那个按钮。

使用特权

评论回复
9
NE5532| | 2010-5-23 08:21 | 只看该作者
说~法~不~正~确

老大,这个屏蔽啥意思啊?

使用特权

评论回复
10
沁雨飞扬|  楼主 | 2010-5-23 20:23 | 只看该作者
while(P1!=0xFF)     /*按下的按键如果不放开则一直执行下面的switch语句*/   

按键不是应该就按一下就放开的吗?为什么是如果不放开则一直执行下面的switch语句,那我放开意味着是执行那一条语句啊?

使用特权

评论回复
11
zhangjiwei2007| | 2010-5-23 20:46 | 只看该作者
不是很懂

使用特权

评论回复
12
zq1987731| | 2010-5-23 21:43 | 只看该作者
1,us级的延时直接用_nop_();根本无需另外写个函数,一般要延时多少us就define一个Xus
2,程序初始化时开头插入等待其余外设准备完毕的ms级延时
以上两者都是常规应用,我所指的是消抖、串口接收之类应用中,需要延时ms级别时使用yanshi(10);是绝对禁止
另外我所提出的按钮这块的理由从应用角度出发的话,比如电视遥控器,3频道的按钮坏了,是不是整个遥控器都要送去检修???对于一个合格的遥控器,完全可以将该按钮弃置不用,顶多切换到2频道再按“NEXT”,不然带给客户的麻烦可想而知,产品质量口碑等等潜在影响又是可想而知!

while(P1!=0xFF)     /*按下的按键如果不放开则一直执行下面的switch语句*/   
按键不是应该就按一下就放开的吗?为什么是如果不放开则一直执行下面的switch语句,那我放开意味着是执行那一条语句啊?

P1!=0xFF条件指的就是有按钮按下,一旦所有按钮放开,那么自然P1的状态就等于0xFF
不放开的话while判定条件无限成立当然一直执行switch语句了,放开就跳出while循环继续从31行开始执行,这个是C的范畴

使用特权

评论回复
13
NE5532| | 2010-5-24 14:23 | 只看该作者
没有谁规定过mS级以上的延时不能用软件延时哈,只要程序没有服务其他应用的需要,软件延时是最简单的实现方法。

使用特权

评论回复
14
麻辣鸭脖子| | 2010-5-24 17:25 | 只看该作者
这个解释很详细啊,偶也学习学习

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

5

帖子

1

粉丝