A. c51单片机程序实例
#include<reg51.h>
#defineucharunsignedchar
uchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//0到9
ucharnum,cnt,disn;
ucharkeyval,disk;
ucharled[]={1,2,3,4};
voiddealdat(uchara)
{
led[0]=0;
led[1]=0;
led[2]=0;
led[3]=0;
led[a]=disk;
}
voiddelay(unsignedinta)
{
unsignedinti,j;
for(i=0;i<a;i++)
for(j=0;j<1000;j++);
}
voidt0isr()interrupt1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
switch(num)
{
case0:P2=0x01;break;
case1:P2=0x02;break;
case2:P2=0x04;break;
case3:P2=0x08;break;
default:break;
}
P0=~tab[led[num]];
num++;
num&=0x03;
cnt++;
if(cnt>100)
{
cnt=0;
disn++;
disn%=4;
dealdat(disn);
}
}
ucharkbscan(void)
{
unsignedcharsccode,recode;
P3=0x0f;//发0扫描,列线输入
if((P3&0x0f)!=0x0f)//有键按下
{
// delay(20);//延时去抖动
if((P3&0x0f)!=0x0f)
{
sccode=0xef;//逐行扫描初值
while((sccode&0x01)!=0)
{
P3=sccode;
if((P3&0x0f)!=0x0f)
{
recode=(P3&0x0f)|0xf0;
return((~sccode)+(~recode));
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return0;//无键按下,返回0
}
voidgetkey(void)
{
unsignedcharkey;
key=kbscan();
if(key==0){keyval=0xff;return;}
switch(key)
{
case0x11:keyval=7;break;
case0x12:keyval=4;break;
case0x14:keyval=1;break;
case0x18:keyval=10;break;
case0x21:keyval=8;break;
case0x22:keyval=5;break;
case0x24:keyval=2;break;
case0x28:keyval=0;break;
case0x41:keyval=9;break;
case0x42:keyval=6;break;
case0x44:keyval=3;break;
case0x48:keyval=11;break;
case0x81:keyval=12;break;
case0x82:keyval=13;break;
case0x84:keyval=14;break;
case0x88:keyval=15;break;
default:keyval=0xff;break;
}
}
main()
{
TMOD=0x11;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
getkey();
if(keyval!=0xff)disk=keyval;
delay(10);
}
}
B. c51单片机编程
一位共阳数码管接在P0口,为静态显示。P3口接有8个独立式按键,按键为K1~K8,按键8个按键中的任意一个,数码管则显示出按键编号。仿真图如下,这是按下K6时显示6。
C. 简述c51程序开发流程
C51开发流程:
第一:必须对C51单片机内部外设和内部寄存器了解,因为写程序需要控制单片机内部寄存器,再去控制外设。
第二:设计单片机的硬件,单片机IO控制你的硬件
第三:画出流程图执行大概的框架
下面就是按照你的流程图去设计程序。
D. C51单片机入门编程问题
1、你不要想它怎么关联的,它就是一种固定的写法,语法就这样。你只能这样写,也当你写成这样的时候,编译器会认得出来它代表什么的,写成其它的话,编译就会报错了。所以不要再纠结这个问题。语法这样定的,遵守就行了。
2、0xfe不是什么地址,就是个简单的赋值,OutData就是等于0xfe。
OutData要是指一个端口的话,最前面是要有宏定义的,比如
#define OutData P0
上面表示用OutData这个词代替P0。
为什么要么定义,而不直接用P0就好了,你去查一下宏定义的好处就知道为什么会有这种用法了~
E. 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的值被函数使用了,编程者不必恢复调用前的值。
F. C51单片机编程,按键控制流水灯
#include "reg51.h"
unsigned char led[]={0xfe,0xfd,0xfb,0xf7}; //LED灯的花样数据
void delay(unsigned char time){ //延时函数
unsigned int j=15000;
for(;time>0;time--)
for(;j>0;j--);
}
void main(){
bit dir=0,run=0; //标志位定义及初始化
char i;
while(1){
switch (P0 & 0x0f){ //读取键值
case 0x0e:run=1;break; //K1动作,设run=1
case 0x0d:run=0,dir=0;break; // K2动作,设run=dir=0
case 0x0b:dir=1;break; //K3动作,设dir=1
case 0x07:dir=0;break; //K4动作,设dir=0
}
if (run) //若run=dir=1,自上而下流动
if(dir)
for(i=0;i<=3;i++){
P2=led[i];
delay(200);
}
else
for(i=3;i>=0;i--){ //run=1,dir=0,自下而上流动
P2=led[i];
delay(200);
}
else P2=0xff; //若run=0,全部灯灭
}
}
G. 单片机C51编程两个问题(里面详细,欢迎高手)
12个晶振周期为一个机器周期,在单片机里面的指令都以机器周期来计算的,所以要乘以12,至于那个2^16-计数初值那就是定时器的溢出计算式,也就是从计数初值到溢出所占用的机器周期来计算的!~
那个延时的问题,我看有问题。也不知道你用的是多少的晶振。
不过大致的计算式是:震荡周期*12*125*500=延时时间。这个是大致的,有一定的误差,如果你真要精确算,那你得用外部高精度晶振,然后用汇编语言取算。
H. 编写一个完整的单片机C51程序
#include<reg51.h>
sbit led=P1^0; //单片机管脚位声明
void main()
{
TMOD=0x01; //定时器TO工作在方式1
TH0=(65536-5000)/256; //装初值,12M晶振 1为1us; 5000为5000us=5ms;
TL0=(65536-5000)%256;
EA =1; //开总中断
ET0=1; //开定时器TO中断
TR0=1; //启动定时器
P1=0; //初始化P1口
while(1) ; //程序在这里等待中断发生
}
void T0_time() interrupt 1
{
unsigned char num;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
num++;
if(num==100) //0.5S (1s闪烁1次==0.5S亮0.5S灭)
{
num=0;
led=~led; //led状态取反
}
}
I. 设单片机系统如何编写一个完整的C51程序使P1.6和P1
设单片机系统编写一个完整的C51程序使P1.6和P1,可以使用正确编码加上解压即可。
J. C51单片机编程
51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。