51单片机的编程问题? 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单片机编程问题?~

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

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

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

P0<<=1 单片机编程中这个什么意思啊?
答:P0对应他这组的8个引脚,即 P0^0--P0^7 这句话的意思是右移 加入P0开始是00000001 经过P0<<=1(即P0=P0<<1)就变成了00000010 这个右移8次就把1移出去了,就会变成00000000即十进制的0

C语言对单片机编程的问题(一道题)
答:P3 = 0xff; //按键接口置为高电平 if(key1 == 0) //有键按下 { num++; //数字疯长 wei = 1;P0 = 0xfe; //P0.0 = 0 ,仅一位发光 wei = 0;duan = 1;P0 = table[num]; // num如果超过9,table[num]越界 duan = 0;} else //无键按下 --- 缺少按...

关于单片机的C编程问题。我是在64位win7安装的keilC51-uVision3.这个...
答:系统不兼容,我认为是这样的 include <reg52.h> include <stdio.h> void main(void){ SCON=0X52;TMOD=0X20;TH1=0XF3;TR1=1;printf("hello i am kell." \n); 我觉得加上双引号比较好 printf("i will be your friend." \n);while(1);} 最好这样写 但是也报错了 Build target '...

KEIL 单片机编程问题,好多错误。求大神帮改一下。万分感激
答:include<reg51.h>#define unchar unsigned char#define uint unsigned intsbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit wela1=P3^0 ;sbit wela2=P3^1;unchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void delayms(uint);void display(unchar...

单片机,C语言编程的问题,编一个程序。
答:void Timer0() interrupt 1{ uchar tmp;static uchar Count=0;TH0=(65536-3000)/256;TL0=(65536-3000)%256; //定时时间为3000个周期 P2=P2|0xfc; //P2高6为置1 P2=BitTab[Count]; //设置第几位显示 tmp=DispBuf[Count];P0=DispTab[tmp]; //设置显示的字符,即送出字形...

单片机编程?做一下题目
答:如果在执行中断服务时不是按上述方法进行现场保护和恢复现场,就会是程序运行紊乱,程序跑飞,自然使单片机不能正常工作。关于IO口 1.每个端口都具有输入/输出功能,可作为通用I/O口使用。作输出时数据可以锁存,作输入时数据可以缓冲。4个端口的每一位都可独立使用。2.P0口和P2口可用于与外部存储器的...

单片机与相位计的RS232串口通信编程问题。 硬件已经没有问题,c程序存 ...
答:/ 如果你的相位计只需要在初始的时候发送p0 c0 l0 这三个的话,也就是说后继的数据都是由相位计发送,单片机接收的话,初始化部分没有大问题,但接收数据的部分 ReceStr()有问题,应该是收不到数据吧?1、串口初始化程序先确定TH1的值和单片机晶振匹配不?0xfd是用于11.0592M晶振的波特率不...

问一个汇编单片机混合编程的问题
答:以下几个作用:1)通过nop指令产生一定的延迟,但是对于快速的CPU来说效果不明显,可以使用rep前缀,多延迟几个时钟:);2)i/o传输时,也会用一下nop,等待缓冲区清空,总线恢复;3)清除由上一个算术逻辑指令设置的flag位;

单片机问题,求教高手下面一段程序原理,希望能逐句给出解释,非常感谢...
答:include<reg51.h>//头文件 include<intrins.h> define uint unsigned int define uchar unsigned char void DelayMS(uint ms)//延时函数 { uchar t;while(ms--)for(t=0;t<120;t++);} void main(void)//主函数 { uchar i;P1=0xfe;//将P1口的八个管脚拉电平11111110,即P1.0为低,...

51单片机编程错误 1.C(20): error C141: syntax error near 'void...
答:首先就是上面说的【你把main函数中的延时函数调用前的void去掉】其次 把【 sbit D1=P1^0; //位操作】放到函数声明【 void yanshi(); 】前面 所有的变量定义、位定义,都不能出现在中间,要放在最前面