单片机的C程序中的问题

#include <REG51.H>

sbit p=P1^0;

void delay(void)
{
unsigned int i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}

main()
{
while(1)
{
p=0;
delay();
p=1;
delay();
}
}
问题很简单,那个void delay下面的两个20分别是什么意思?20毫秒?248又是什么意思?void delay(void),为什么括号里还要加一个(void)?什么意思?
while(1)是什么意思?可以讲讲while循环的方法和结构吗?
还有,在p=0;后面的delay()是延时吧?为什么括号里什么都不用写?是不是跟上面定义的void delay有关?如果没有void delay那段的话,是不是p=0;下面的delay()的括号里就要加什么语句了?
跪求解答,在线等(等3小时),一出现完整的答案,立即采纳。

1、关于delay内的三个for指令:
20、248都是循环的次数。这是个三级嵌套循环。如果是12MHz晶振的情况下,一次delay大约是800ms。C中的这种循环延时具体时间取决于晶振、使用的语句、编译选择等多个条件,这里不能完全确定
for(i=20;i>0;i--)
{//最外层循环,每次i-1,直到i=0,计20次
for(j=20;j>0;j--)
{//第二层循环,每次j-1,直到j=0,计20次
for(k=248;k>0;k--)
{//最内层循环,每次K-1 ,直到k=0,计248次。
}
}
}//总循环次数为20*20*248次
2、void delay(void):第一个void代表调用的函数delay无返回值,第二个void代表调用delay函数时不需要传递参数。void:说白了就是没有参数。
3、while(1):while语句的结构如下
while (条件表达式)
{
循环体语句
}
含义是:如果“条件表达式”结果为真(条件表达式的结果只有真、假两种情况,也就是1或0),则执行后面的“循环体语句”,否则跳过“循环体语句”,执行循环体后的语句。本例中,{ }之间的四条语句均为循环体内的语句,而条件表达式为逻辑常数1(即:真),所以就是说永远循环顺序执行这四条语句。
while(1)
{
p=0;
delay();
p=1;
delay();
}
4、delay()是编程者自己编制的一个延时函数,不是C语言中的标准函数,正因为在前面定义了此函数,所以main()中才能调用;如果没有前面的定义,在程序编译的环节就会报错,无法生成代码。至于调用方法,上面说过了,因为不需要传递参数,所以括号中什么也不用写,如果写了反倒会出错。你可以详细看一下2、。追问

两个问题:
1.那么,delay()延时函数延时的时间是多长?那如果在前面没有void delay(void)申明不需要参数的话,那么这delay()的括号里面应该怎么写?
2.同上...

追答

延时与选用的单片机型号(有12振荡一个机器周期和单振荡一个机器周期的芯片)、工作方式(正常还是倍频模式)、晶振的大小、编译模式(变量选择内部寄存器还是外部寄存器及优化模式),包括delay函数体内的i、j、k初值等都有关系。
就你的这段程序而言,如果是标准的51单片机、12MHz晶振、正常工作模式的情况下,编译模式使用KEIL C编译器的缺省设置,那么:
一次delay()的时间大约是800ms,最内层的for(k=248;k>0;k--)每次循环是8us。
延时时长都是固定值。

如果想灵活控制时间的话,可以将i、j、k都设定为函数的参数,改成如下形式
void delay(unsigned int i, unsigned int j, unsigned int k)
{//下面循环的初值在调用delay函数时传递过来
for(;i>0;i--)
for(;j>0;j--)
for(;k>0;k--);
}

主程序中就可以这样调用:
delay(20,20,248); //20*20*248
达到的效果是一样的;
如果需要400ms的延时,就可以这样调用
delay(10,20,248); //10*20*248
不知这样你是否能理解?

你不必对这种循环延时的时间过于关注,因为ms级的延时在单片机C语言中都是通过定时中断来完成的,你的程序中的这种用法在实际运用中几乎不会使用。

我感觉你还需要对函数的概念及单片机的基础知识再深入了解一下,是不是刚学没多久?

追问

1.for嵌套循环最多可以嵌套几个?还是说可以无限嵌套?
2.delay(10,20,248); //10*20*248
不知这样你是否能理解?
这个了解,就是数值1就表示1个时钟周期(1us),10*20*248差不多是400ms,对吧?
3.我感觉你还需要对函数的概念及单片机的基础知识再深入了解一下,是不是刚学没多久?
是的,非常非常菜的那种,所以需要大侠指点...
函数的概念是什么?单片机的基础知识是什么?指导一个方向给我?

追答

1、理论上可以无限嵌套,实际应用中5级就差不多了,嵌套越多程序的易读性越差
2、再重复一下:for(k=248;k>0;k--)每次循环K--,执行时间是8us(这一句for的执行时间,相当于8个机器周期),所以10*20*248 *8us=49600*8us =396800us, 差不多就是400ms。强调一下:并不是说for语句的执行时间一定是8us,仅仅是本例当中是这样。

从你对待这个问题的执着我觉得你是一个认真的人,只是你现在的知识掌握的还不多,不要着急,没什么难的,冲这个认真劲没问题的。

单片机的学习是离不开实践的,所以最重要的应该去买一个开发板,开发板一般都附带实战练习手册,好一些的还会将一些理论。你可以边学习边实践,那样会更快。

作为辅助的学习过程可以分两步:首先是系统性的学习单片机的理论,包括硬件特性、汇编指令等。自学的话推荐一本书给你看看(我已经向无数初学者推荐过这本书了):《mcs-51、96系列单片机原理及应用》,孙涵方著,32开本大小,北京航空航天大学出版社1988年出版。
第二步,C语言的学习。其实有条件的话我觉得你可以稍微放一下,因为C语言的难点主要在后期的指针、结构等概念,等你了解了51后,再去理解这些概念就会感到简单的多。当然同时都学也不是不行,如果想同时都学我也给你推荐一本书:《单片机高级语言C51应用程序设计》,徐爱均、彭秀华著,电子工业出版社1998年第一版出版。

追问

《mcs-51、96系列单片机原理及应用》,这本书我已经下载了,谢谢你!

追答

先读读吧,把基础打好。祝你进步。

温馨提示:内容为网友见解,仅供参考
第1个回答  2011-05-16
你这里面应该就是一个灯的闪烁程序了。。
while(1)就是让他一直在循环,亮--灭--亮--灭的过程
void delay(void):前面一个void是指没有返回值,后一个void是指没有参数输入。
20,20,248其实就是延时时间了,具体多少得算才知道。。。你也可以通过改变这些数来观察灯的点亮变化就明白了。。。
第2个回答  2011-05-16
248是循环执行248次,两个20都是循环执行20次,共执行248*20*20次,延时多长时间和你选用的晶振有关系
第3个回答  2011-05-16
从问题可以看出楼主你是初学者吧,不过没关系,这是一个过程,如果你想学好单片机的话,那得好好学习C51,多看看实例,多动手写写程序,软硬件结合,祝你顺利追问

可以针对问题回答吗?谢谢啦!

单片机的C程序中的问题
1、关于delay内的三个for指令:20、248都是循环的次数。这是个三级嵌套循环。如果是12MHz晶振的情况下,一次delay大约是800ms。C中的这种循环延时具体时间取决于晶振、使用的语句、编译选择等多个条件,这里不能完全确定 for(i=20;i>0;i--){\/\/最外层循环,每次i-1,直到i=0,计20次 for(j=20...

关于单片机C语言的问题
1:你的示例中没有中断服务程序;2:中断发生后,如果当时没有其它同级或更高级的中断服务程序在执行,会马上停在正在执行的主程序,并记住这个位置,然后进入中断函数(当然CPU还要做些必要的处理,如压栈等操作);3:中断函数完后,程序会返回当初停止的那个位置,继续往下执行;4:示例中,当程序开始...

单片机编程(C语言)问题
include <stdio.h>#include <string.h>void main(){unsigned char num=0;int index=0;for(index=0;index<300;index++){printf("%3d ",num);if(num % 15==0){putchar('\\n');}num++;}}

【满分求教】单片机C程序,关于定时设置初值的n多疑问
12MHz的晶振下,CPU得到的频率是1M,因为51单片机是内部十二分频的。那么对应的一个时钟的周期就是1us,16000us就是16ms,也就是16000个周期后将产生溢出,如果你的程序里全能了定时中断和全局中断,那么将会发生定时器中断。但你程序一里面的写法是有问题的。应该是 TH0 = (-16000\/256);TL0 = (-...

C语言单片机程序 初学大家帮忙看看错在哪里了 #include <reg51.h...
也有可能是你烧写程序的时候 数据传输的过程中出错了,校验出错 一般是传输过程中某个或者某些bit或者byte出错 建议你重新编译 重新下载烧写试试, 单片机这东西就是经常出些小问题,有时候我们买的开发板或者有些数据线质量不过关也会导致一些莫名其妙的问题,多尝试尝试 相信你能解决的 ...

单片机C语言中碰到的问题?
都是循环延时函数,其中都包含了如下两句;for(m=20;m>0;m--) 、 for(n=20;n>0;n--);但是不同的是语义不同(这里就是有无“;”分号的不同);而 是镶套循环,那么其循环次数 = m * n;而 则是两个独立的循环,其循环次数 = m + n;...

单片机C语言中断问题
你有个地方没弄清楚。单片机执行的是机器码,机器码对应的是汇编指令。而C语言表述的句子,会编译成若干汇编指令。就是说没有C指令这一说,以51举例,_nop_()对应汇编的NOP,但是一个简单的a*b,编译后可能长度就有好几百字节。每条指令执行的周期不同。有些只要一个周期,有些需要几个周期。中断...

单片机C语言小疑问
你用的晶振应该是12M的吧,其实这段C程序编译成汇编就是三条MOV指令和三条DJNZ指令,程序的大部分时间是反复的执行DJNZ这条指令,DJNZ指令周期是2us,所以这段程序的时间大约是20*20*248=0.2S左右.那为什么用K=248而不是250呢,因为在一个循环(第三个for循环),即248个对变量k的DJNZ后,还会有一个...

为什么我的单片机c语言中for循环有问题呢,如下
这个是不会成功的.因为单片机中的P1不是变量,是端口.给P1赋值是把对应值输出到端口,读取P1是读取端口.两个是完全无关的操作.for(P1=0XFE;P1!=0X7F;P1=left(P1));中P1!=0xF7就对端口P1进行了读取,left(P1)又读取,P1=这样的是输出到端口P1. 读取的情况就不能确定了,如果外围电路没有变化,...

关于单片机C程序的一个菜鸟级问题
是把0x40即二级制01000000B赋值给P2端口从高到低的八个引脚 同理,P2=0x80 即把八位二进制数 1000 0000B 赋值给P2端口 由此可以推知,同时满足P2.7=1、P2.6=1并且其余P2端口为0的赋值语句就是 P2=0xC0 最后,回答楼主的问题 (1)可以直接赋值 P2=0x80 (2)直接全端口取反P2=~P2 (...

相似回答