51单片机的编程问题?

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-08-27
51单片机编程问题?

你这单片机程序跟谁学的这么写,三个程序中都有while(1),这是无限循环结构,只允许主程序中用,而被调用的子程序不能再用了。你现在程序肯定是只执行 zuo(); 这一个,因为,有while(1),就无限循环在这个程序中了,跳不出来,就不会执行另两个程序的。把三个程序中的while(1)都删掉。

目前为止,接触单片机已有不少,从选择元器件、原理图、PCB、电路硬件调试、软件开发也算小有心得。

单片机软件开发里面第一步当属下载程序了,如果这一步都有问题,那么后面的一切便无从谈起,记得当初刚接触单片机时,对于下载电路方法及原理也是一头雾水。好在随着经验的积累以及自己的努力探求,现在对此问题算是有了点点自己的经验理解。故今天在此针对常用51单片机下载程序问题做下详解,以求新手们少走弯路。

1:C51编译器如何区分位地址和字节地址
是靠预定义实现的,比如:sfr P0 = 0x80; sbit P0_0 = 0x80;前者声明了P0端口地址位于0x80,后者说明了P0端口的bit0,即P0.0位于位地址空间0x80处。这2个0x80具有完全不同的含义,靠关键字sfr和sbit来区别。这样当程序被编译时,编译器会依此编译成相应的汇编语言。例如:

C51语句: P0 = 1;

P0声明为sfr,因此编译成:mov 80h,01h,将把0x01数据送入0x80单元,由于0x80单元物理上对应P0端口,因此,P0.0脚将输出高电平(其实是呈现高阻态,P0口独有的),其他.1-.7脚输出低电平。

C51语句: P0_0 = 1;

P0_0声明为sbit,因此编译成:setb 80h,这将把位地址空间的0x80地址的bit的值置1。这个位正是P0口的bit0,执行后,P0.0将输出高阻态。而P0.1-.7不会变化。

2:C51为什么要嵌套汇编
51单片机一个显著优点就是指令执行时间固定,因此可以适应时序要求严格的场合。例如符合ISO7816协议的cpu卡的读写,对时序要求比较严格。其实就是用io脚做出来的同步半双工串口。支持cpu卡的程序一般比较庞大,需要用c51来组织,但是由于c编译的不确定性,必须把底层程序封装成汇编语言模块嵌入到工程中。这就带来几个问题:如何声明函数、参数如何传递等。限于篇幅,不能说得很细。下面举例:

汇编程序单独保存一个文件,加入到工程中,函数如下:

_proc_a:

mov a, r7

inc a

mov r7, a

ret

用c语言在.h文件中声明: extern unsigned char proc_a(unsigned char val);

调用时形如: retvalue = proc_a(0x11);

说明:

a:汇编程序如果带参数,则需要在汇编程序前多加一个下划线。而声明它的地方不用加(伟福编译器这么要求的)。

b:函数的形参中第一参数用R7传递,函数返回值用R7返回,这是C51的通用规范。其他参数都有相应规定。函数可以返回一个位,用psw的c位返回。c:上面的语句,执行顺序是把0x11给R7,然后跳转子程序,子程序将它加1后送回。

d:函数跳转到汇编程序时,本区的R0-R7,A,B,PSW,DPTR等寄存器可以供子程序使用,不必考虑调用后是否要恢复这些常规资源。上例中,A的值被函数使用了,编程者不必恢复调用前的值。

利用MCS51系列单片机指令编写8位数x和16位数y的乘法程序,x存在片内RAM的30H中,y的低8位、高8位分别存在片内RAM的32H和33H单元,计算结果所存的单元自行安排。数码管可以显一位16进制数,即0~F,就是四位二进制数,而显示码需要是8位的,因单片机内部是没有四位二进制数的,必须配成8位,那高四位就配成0000,这就是数码管的显示码。
一个RAM单元存放的无符号数的高四位和低四位可以用两位数码管分别显示出来,所以,要拆开,变成两个8位的显示码,才能用查表法查出对应的段码。目前为止,接触单片机已有不少,从选择元器件、原理图、PCB、电路硬件调试、软件开发也算小有心得。
单片机软件开发里面第一步当属下载程序了,如果这一步都有问题,那么后面的一切便无从谈起,记得当初刚接触单片机时,对于下载电路方法及原理也是一头雾水。好在随着经验的积累以及自己的努力探求,现在对此问题算是有了点点自己的经验理解。故今天在此针对常用51单片机下载程序问题做下详解,以求新手们少走弯路。如果是8位单片机没有问题。。
如果使用的是16位32位单片机,uchar定义变量只允许是字母变量,而不能是数字变量,否则会出错。。
因为16位、32位存储单元最少存储位都是16位、32位的,必须定义为int变量才行。。定义uchar存储的认为是字母,而不会认为是数字了。所以运行会判断错误。
这也和汇编软件有关系。

把它们交错在一起,改动几行、删除几行、再填上几行,即可。

  • 关于51单片机C语言编程的问题
    答:你定义P1_0 程序里却用P1_1 当然要报错:P1_1未定义 P1^0  P1^1... 这些符号是在头文件 reg52.h 中定义过的,它与单片机内部寄存器的地址已经联系上了 但P1.0或P1_0是我们习惯的写法,编译器并不认识 所以 我们写sbit P1_1=P1^1 ,意思是定义一个位变量P1_1 和已有位变量P1^1...
  • 关于51单片机c语言编程的问题
    答:答:PinC PinB PinA是位变量(只有两个值0、1);Address是字节变量(八位二进制数,用16进制表示是从00H到FFH)。这几句:PinC = (bit) (Address & 0x04);PinB = (bit) (Address & 0x02);PinA = (bit) (Address & 0x01);的意思是把 Address和后面的 0x04 0x02 0x01 进行“与...
  • 51单片机汇编语言的一个小问题
    答:就是对两位压缩BCD码进行调整 比如r1 = 17h a = 28h add a,r1 显然 a=3fh 但是 这不是我们想要的结果,因为我们用一个字节表示的是压缩的BCD码,而bcd码根据8421的标准码是么有f这个数字的,虽然里面存的数据是17h和28h 但是我们把他看成是bcd码,也就是说用4位数字表示一个数,17h+...
  • 求解释下边这段51单片机汇编程序存在的问题,为什么我不能得到想要的结果...
    答:【1】循环输出到P0,每次将P0口状态和A相‘与’后输出,可能得不到理想结果。意图是取A的高两位和P0口的低6位输出。MOV A, R1 ANL A,P0 改成:MOV A,P0; ORL A,#0C0H; ANL A,R1;MOV P0,A 【2】串口循环输出,是同步移位方式送LED显示,是吗?需要考虑发送的时间,考虑硬件移位...
  • 51单片机C程序编程问题
    答:初学者问的问题可能让你见笑,请见谅!第一个是 { TMOD=0x01;TH0=-(50000/256);TL0=-(50000%256);ET0=1;TR0=1;EA=1;} 为什么TH0要用负值?这些寄存器中其它值不用赋初值是不是默认是0.(如TCON,只是赋了TR0,)///答:负值,相当于满值减去相应的正值,比如int型变量n /// n=-1;...
  • 51单片机编程问题,为何程序只能执行键盘的第一次指令?以后的指令不执行...
    答:你编程大概是受C的影响,单片机中主程序要成一个循环,才能保证系统可靠运行。org 0000h main:mov a,p2 anl a,#0fh cjne a,#0fh,key mov a,#00h ajmp main key:cjne a,0eh,n1 mov p1,#10101010b ajmp main n1:cjne a,0dh,n2 mov p1,#10111010b ajmp main n2:cjne ...
  • 51单片机 C语言编程的疑问
    答:0空的,是3*4的矩阵键盘) key=key+0; else if(temp==4) //第二行 p1.2 被拉低 key=key+4; else if(temp==8) //第三行 p1.3 被拉低 key=key+8;else key = 16;您好!检测下来问题不大,但还是建议不要替换!
  • 51单片机的初学者 keil编程出现问题帮忙看看吧
    答:程序及仿真电路存在其他健壮性问题,这里不予表述及建议。主要问题:while(1)循环有问题。原因分析:你的main函数进来a=P1,只是给a附一个初值,然后一直循环while(1)里面。while(1)里面a的值一直是初值(0xff),switch函数根本侦测不到按键值。短期建议:while(1)内添加获取键值代码为 a=P1。
  • 51单片机的问题
    答:8051在执行程序时,PC每输出一次地址,就指向程序存储器的一个单元,CPU自动取出一个字节的指令代码而后执行。PC中内容一次次自动加1,指令就一条条被取出并执行。在编程中,作为编程人员,只有散转移指令(JMP @A+DPTR 或 JMP @A+PC)可以用到PC,其它指令是不能直接用PC,即使这里用PC,也有特殊...
  • 51单片机的问题
    答:你完全理解错误啦。单片机寄存器的地址是对应一个字节大小的寄存器的地址,而寄存器的每一位是没有地址的。TCON的地址是88H,这个88H只的是TCON这个寄存器的8位。就像你家有只有一个门牌号,而你家有几件房间一样的。而寄存器的地址就是这个寄存器的门牌号。每个寄存器有8个房间,每个房间只能住一个人(...