yangcheng84 发表于 2014-5-21 00:15:50

初学贴<2>:学习51单片机,点亮一个灯以后....

本帖最后由 yangcheng84 于 2014-5-21 00:17 编辑

初学贴<1>:http://www.crystalradio.cn/thread-552316-1-1.html

学习51单片机,点亮一个灯以后....

在第一帖子的视频里我们看到,当单片机时钟没有的时候(视频中用镊子对地短接19脚),单片机外部LED的状态保持上次状态不变,这就是我们常说的“数据锁存”. C51单片机的8位端口,内部都有一个对应的端口寄存器,命名为P0 \   P1\P2\3, 每个端口8位(

即视频中说的定义位,点亮一个灯的脚就是1个位);这些端口寄存器是可以“整体控制(专业术语:读写)”的,也可以单独对某位读写,点亮1个灯就是操作了其中的一位.

   和汇编类似,对整体端口赋值就可以实现“写”操作:


   P1=0xAA; //把十六进制0xaa写进P1端口,此时端口的状态就是10101010


而对于读,我们像数学那样,如果存在一个变量a,那么

a=P1; //P1的数据被读入变量a 中保存起来


当然,这里的a是需要预先定义说明的.这一点和数学定义类似


定义变量,其实就是定义数据类型,而数据类型,说白了就是表明 变量的大小范围(数学不也经常出题目求解方程,最后说明变量是属于自然数还是整数还是有理数集合吗?说白就是要确定范围的)

对于8位变量,可以使用单字节的“unsineg char "做声明,因为单字节变量刚好可以表达2的8次方范围内的数值.完整写法即:

unsineg char a;

a=P1;


实际中原则上,只要存贮用的变量所容纳的大小能装得下 需保存的数值,那么定义是能使用的,例如

unsineg char a;

a=200;//正确,因为a的最大值就是255(从0算起,0-255 刚好256个单位)

而若此时写a=256;或 a=257; a=500.....都是逻辑不正确的,有的编译器可能不会提醒你,但是写入单片机就会出现逻辑错误.


看看这个例子:

假设有一个变量x,编程 ,验证单片机判断数字的大小逻辑功能正确与否?

简易方法:假定x=20,我们让单片机和2比较,如果单片机认为x>2就点亮一个灯,否则就不点灯,那么就可验证了。


#include <AT89X52.H>

#defineLEDP1_0    //验证结果指示灯

main()
{
unsineg char x=20;//数值20写入变量x

if(x>2)
{
    LED=0;         //成立则执行点灯
}
else
   {
    LED=1 ;       //否则不执行,灭灯
      }

while(1);


}


这里定义的变量如果写:
       
#include <AT89X52.H>

#defineLEDP1_0    //验证结果指示灯

main()
{
unsineg char x=256;//数值256写入变量x

if(x>2)
{
    LED=0;         //成立则执行点灯
}
else
   {
    LED=1 ;       //否则不执行,灭灯
      }

while(1);


}


因为 x=256是不对的,因此尽管程序结构正确,但是最终的运算逻辑还是不对的(单片机不认为x>2,灯不亮).呵呵,所以要把握好数据类型的大小.


最后再说一次:单片机是读还是写操作,完全是有程序写入后自动切换的,不需要人工干预.

P1=0x??;   //写

a=P1;       //读

补充内容 (2014-5-21 09:08):
上文:unsineg char   确实笔误,应为:unsigned char,现在帖子发了不能改过来了

whm800128 发表于 2014-5-21 05:03:23

好帖必须顶

绝对整烂 发表于 2014-5-21 08:31:23

本帖最后由 绝对整烂 于 2014-5-21 08:41 编辑

unsignedchar
不是 unsineg char

/*我抄成这样*/
#include<AT89X52.H>
#define LED1 P1_1
#define LED0 P1_7

char code dx516 _at_ 0x003b;
unsigned char x=20;

main()
{    LED1=0;
while(1)
{if(x>2)
         {LED0=0;}
                           else{LED0=1; }
}}
运行后这样。

yangcheng84 发表于 2014-5-21 09:22:49

绝对整烂 发表于 2014-5-21 08:31 static/image/common/back.gif
unsignedchar
不是 unsineg char



呵呵,通过观察灯的最终状态,您认为程序运行结果正不正确呢?:)

绝对整烂 发表于 2014-5-21 09:40:38

yangcheng84 发表于 2014-5-21 09:22 static/image/common/back.gif
呵呵,通过观察灯的最终状态,您认为程序运行结果正不正确呢?

亮了我想要亮的两个灯.结果是正确的,不同的时,我抄的程序是不停也重复检测X的值,而楼主程式是停在那里,
我改写楼主的程序的时候发现, C语言中用来表示层序层次的花括号是很有讲究的,比如我就因为少了一个括号而无法编译通过,软件提示我语法错误,我找了好一会才找到,看来C语言是比汇编要高级(费话),如果用汇编,可能不是报错,而是程序飞掉了。
   我没有完全照抄楼主的程序,我认为按自已的想试着改一下,可以发现自己的错误。这好比老师的例题和作业的关系,虽然它们差不多,但是对于学习来说,是很在帮助的。也不致于学了几年单片机,还是只会点亮个流水灯,或者脱手就联个流水灯都点不亮了。

yangcheng84 发表于 2014-5-21 09:51:28

绝对整烂 发表于 2014-5-21 09:40 static/image/common/back.gif
亮了我想要亮的两个灯.结果是正确的,不同的时,我抄的程序是不停也重复检测X的值,而楼主程式是停在那 ...

:lol绝对乱整确实很用心啊。


和你差不多,以前我也是受教于汇编语言,写简单的程序可以,但是稍微复杂的就头大了。 最直接能说明头大的事情:用汇编计算 y=3x+1.5其中x=5,因为汇编搞数学运算确实太难了,数据内存分配需要人工干预,


独立写这个公式计算,汇编一个上午写出来都难。但是C语言就好办,如下:


floaty;

unsignedcharx=5;


y=3x+1.5 ;   //此时结果已经存入变量y中


说白了,C语言中,数学公式许多情况基本照数学写法就可以了

无烟男人 发表于 2014-6-13 23:13:08

yangcheng84 发表于 2014-5-21 09:51 static/image/common/back.gif
绝对乱整确实很用心啊。




:'( 我不懂C语言!!    能教我吗?

yangcheng84 发表于 2014-6-13 23:16:14

无烟男人 发表于 2014-6-13 23:13 static/image/common/back.gif
我不懂C语言!!    能教我吗?

讨论学习,交流吧。教,这个就有点过分了. 记得请吃老友粉:lol

无烟男人 发表于 2014-6-13 23:25:31

yangcheng84 发表于 2014-6-13 23:16 static/image/common/back.gif
讨论学习,交流吧。教,这个就有点过分了. 记得请吃老友粉

绝对有!!管饱!!!:lol   

现在我也是刚玩用汇编,现在占时没出现太大的问题,就是想学C语言,大学的时候都忘光了,咳

游戏机123456 发表于 2014-11-2 10:31:19

讲的太好啦通过这一讲是我明白了好多概念。谢谢

12386 发表于 2019-5-17 07:33:51

谢谢分享。学习了。辛苦楼主了。

12386 发表于 2019-5-17 07:34:12

谢谢分享。学习了。辛苦楼主了。

KAILAI 发表于 2019-6-16 21:09:51

谢谢分享,学习。学习。楼主辛苦

182525708 发表于 2019-11-29 18:13:03

正在学习,好羡慕会写程序的都是高手
页: [1]
查看完整版本: 初学贴<2>:学习51单片机,点亮一个灯以后....