1 前提准备
1.1 准备工具
- Keil uVision4
- ISIS
2 实训
2.1 实训一
代码:
#include<reg51.h>
#define uint unsigned int // 宏定义,在后面的程序中用uint代替unsigned int
#define uchar unsigned char
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{ while(1)
{
P1=0x03;
delay(1000);
P1=0x9f;
delay(1000);
P1=0x25;
delay(1000);
P1=0x0D;
delay(1000);
P1=0x99;
delay(1000);
P1=0x49;
delay(1000);
P1=0x41;
delay(1000);
P1=0x1F;
delay(1000);
P1=0x01;
delay(1000);
P1=0x09;
delay(1000);
}
}
调试结果:
2.2 实训二
代码:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x03,0x9F,0x25,0x0D,0x99,//0-4
0x49,0x41,0x1F,0x01,0x09};
void display(uchar aa,uchar bb,uchar cc,uchar dd,uchar ee,uchar ff,uchar gg,uchar hh);
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
while(1)
{
display(1,2,3,4,5,6,7,8);
}
}
void display(uchar aa,uchar bb,uchar cc,uchar dd,uchar ee,uchar ff,uchar gg,uchar hh)
{ P2=0x00;
P2=0x01;
P1=table[aa];
delay(2);
P2=0x00;
P2=0x02;
P1=table[bb];
delay(2);
P2=0x00;
P2=0x04;
P1=table[cc];
delay(2);
P2=0x00;
P2=0x08;
P1=table[dd];
delay(2);
P2=0x00;
P2=0x10;
P1=table[ee];
delay(2);
P2=0x00;
P2=0x20;
P1=table[ff];
delay(2);
P2=0x00;
P2=0x40;
P1=table[gg];
delay(2);
P2=0x00;
P2=0x80;
P1=table[hh];
delay(2);
}
调试结果:
2.3 实训三
代码:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar bai,shi,ge,temp,aa;
void display(uchar bai,uchar shi,uchar ge);
uchar code table[]={
0x03,0x9F,0x25,0x0D,0x99,//0-4
0x49,0x41,0x1F,0x01,0x09};
void delay(uint z);
void init();
void main()
{
init();
aa=0;
while(1)
{
if(aa==20)
{
aa=0;
temp++;
if(temp==11)
{
temp=0;
}
bai=temp/100;
shi=temp%100/10;
ge=temp%10;
}
display(bai,shi,ge);
}
}
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
void display(uchar bai,uchar shi,uchar ge)
{
P2=0x00;
P2=0x01;
P1=table[bai];
delay(4);
P2=0x00;
P2=0x02;
P1=table[shi];
delay(4);
P2=0x00;
P2=0x04;
P1=table[ge];
delay(4);
}
调试结果:
2.4 实训四
代码:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar A1,A2,A3,A4,A5,A6,miao,shi,fen,aa;
void display(uchar b1,uchar b2,uchar b3,uchar b4,uchar b5,uchar b6);
uchar code table[]={
0x03,0x9F,0x25,0x0D,0x99,//0-4
0x49,0x41,0x1F,0x01,0x09};
void delay(uint z);
void init();
void main()
{
init();
aa=0;
while(1)
{
if(aa==2)
{
aa=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
shi=0;
}
}
A1=miao/10;
A2=miao%10;
A3=fen/10;
A4=fen%10;
A5=shi/10;
A6=shi%10;
}
display(A5,A6,A3,A4,A1,A2);
}
}
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
void display(uchar b1,uchar b2,uchar b3,uchar b4,uchar b5,uchar b6)
{
uchar yiwei=0x01;
P2=0x00;
P2=yiwei;
P1=table[b1];
delay(2);
P2=0x00;
yiwei<<=1;//把yiwei左移一位再赋值给yiwei。
P2=yiwei;
P1=table[b2];
delay(2);
P2=0x00;
P2=0x04;
P1=0xfd;//显示横杠
delay(2);
P2=0x00;
P2=0x08;
P1=table[b3];
delay(2);
P2=0x00;
P2=0x10;
P1=table[b4];
delay(2);
P2=0x00;
P2=0x20;
P1=0xfd;//显示横杠
delay(2);
P2=0x00;
P2=0x40;
P1=table[b5];
delay(2);
P2=0x00;
P2=0x80;
P1=table[b6];
delay(2);
}
调试结果:
2.5 实训五
代码:
#include"reg52.h"
#define uchar unsigned char
uchar code buf[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};
uchar i;
void delay()//延时子程序
{int i=20;
while(i--);
}
void main()
{
while(1)
{
for(i=0;i<9;i++)
//循环9次,八次是八位按钮的检测,一次是无按钮按下的情况
{
if(P3==buf[i]) //独立按键检测程序
{ delay(); //跳过杂波段,起到消抖作用
if(P3==buf[i])
P2=buf[i];
}
}
}
}
调试结果:
2.6 实训六
代码:
#include"reg52.h"
#define uchar unsigned char
sbit key=P3^2;
uchar code shu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar num;
void main()
{
EA=1; //允许全局中断
EX0=1; //允许外部中断0
while(1)
{
if(key==1)
EX0=1; //当按键松开时,允许外部中断0,等待按键下一次按下。
P2=shu[num];
}
}
void int0()interrupt 0//外部中断0设置程序,详见知识链接一
{
num++;
if(num>9)
num=0;
EX0=0;
}
调试结果:
2.7 实训七
代码:
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
uchar code shu[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
uchar keycn();//函数声明
uchar key; //全局变量
void main()
{
while(1)
{
key=keycn();//函数返回值,详见知识链接三
if(key<16)
P0=shu[key];
P2=0x01;
}
}
uchar keycn()//矩阵式键盘子程序,详见知识链接一
{
uchar temp;
uint k;
P3=0xf0;
if(P3!=0xf0) //若有按键按下,高四位必定有一位变为0;
{
k++;//防抖动
if(k==600) //检测键盘600次才执行程序,防止干扰
{
temp=P3;
P3=temp|0x0f;
temp=P3;
switch(temp) //选择语句switch,详见知识链接二
{
case 0xee: return 0;
case 0xde: return 1;
case 0xbe: return 2;
case 0x7e: return 3;
case 0xed: return 4;
case 0xdd: return 5;
case 0xbd: return 6;
case 0x7d: return 7;
case 0xeb: return 8;
case 0xdb: return 9;
case 0xbb: return 10;
case 0x7b: return 11;
case 0xe7: return 12;
case 0xd7: return 13;
case 0xb7: return 14;
case 0x77: return 15;
default: break;
}
}
}
else
k=0;
return 0xff;
}
调试结果:
2.8 实训八
代码:
#include"reg52.h"
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code shu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar code wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar buf[8]={10,10,10,10,10,10,10,10};
void delay(uint z);
void display();
uchar keycn();
uchar key,num,flag,i;
uint k;
long num1,num2,result;
void main()
{
while(1)
{
key=keycn();
if(key<10)
{
if(num<8)
buf[num]=key;
num++;
if(num>8)
num=8;
}
if(key==14)
{
flag=0;
num=0;
num1=0;
num2=0;
result=0;
}
if(flag==0)
{
if(key>=10&&key<14) //判定运算属于加、减、乘、除的哪一种。
{
if(key==10)
flag=1;
if(key==11)
flag=2;
if(key==12)
flag=3;
if(key==13)
flag=4;
for(i=0;i<num;i++)
num1=buf[i]+num1*10;
num=0;
}
}
else
{
if(key==15)
{
for(i=0;i<num;i++)
num2=buf[i]+num2*10;
num=8;
switch(flag)
{
case 1: result=num1+num2;break;
case 2: result=num1-num2;break;
case 3: result=num1*num2;break;
case 4: result=num1/num2;break;
default: break;
}
if(result>10000000) //将运算结构进行分离
buf[0]=result/10000000;
else buf[0]=10;
if(result>1000000)
buf[1]=result%10000000/1000000;
else buf[1]=10;
if(result>100000)
buf[2]=result%1000000/100000;
else
buf[2]=10;
if(result>10000)
buf[3]=result%100000/10000;
else
buf[3]=10;
if(result>1000)
buf[4]=result%10000/1000;
else
buf[4]=10;
if(result>100)
buf[5]=result%1000/100;
else
buf[5]=10;
if(result>=10)
buf[6]=result%100/10;
else
buf[6]=10;
buf[7]=result%10;
}
}
display();
}
}
void delay(uint z)
{
while(z--);
}
void display()//显示子程序
{
uchar i;
for(i=0;i<num;i++)
{
P0=shu[buf[i]];
P2=wei[i];
delay(200);
P2=0x00;
}
}
uchar keycn()//矩阵式键盘子程序
{
uchar temp;
P3=0xf0;
if(P3!=0xf0)
{
k++;
if(k==10)
{
temp=P3;
P3=temp|0x0f;
temp=P3;
switch(temp)
{
case 0xee: return 1;
case 0xde: return 2;
case 0xbe: return 3;
case 0x7e: return 10;
case 0xed: return 4;
case 0xdd: return 5;
case 0xbd: return 6;
case 0x7d: return 11;
case 0xeb: return 7;
case 0xdb: return 8;
case 0xbb: return 9;
case 0x7b: return 12;
case 0xe7: return 14;
case 0xd7: return 0;
case 0xb7: return 15;
case 0x77: return 13;
default: break;
}
}
}
else
k=0;
return 0xff;
}
调试结果:
2.9 实训九
代码:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit s1 =P1^0;
sbit s2 =P1^1;
sbit s3 =P1^2;
sbit p20 =P2^0;
sbit p21 =P2^1;
#define stop {p20=0;p21=0;} /*电机停止*/
#define MCW {p20=1;p21=0;} /*电机正转*/
#define MCCW {p20=0;p21=1;} /*电机反转*/
main()
{
uchar tp;
while(1)
{
if(s1==0) tp=0;
if(s2==0) tp=1;
if(s3==0) tp=2;
switch(tp)
{
case 0: stop; break; /*电机停止*/
case 1: MCW; break; /* 电机正转 */
case 2: MCCW; break; /*电机反转*/
}
}
}
调试结果:
2.10 实训十
代码:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit s1=P1^0;sbit s2=P1^1;sbit s3=P1^2;sbit s4=P1^3;
uchar R=5,f; //R用于调速控制,5为初值;f=0不转;f=1正转; f=2反转;
uchar CW[4]={0x0c,0x06,0x03,0x09}; //输出正转数据
uchar CCW[4]={0x09,0x03,0x06,0x0c}; //输出反转数据
void delay(uint i ) //延时子程序
{
while(i--);
}
main()
{
uchar i,j;
while(1)
{
if(s1==0) f=0;
if(s2==0) f=1;
if(s3==0) f=2;
if(f==0) P0=0xff; //停止不转
if(f==1) //正转
{
for(i=0;i<=3;i++)
{
P2=CW[i]; //输出正转数据
for(j=0;j<=R;j++) //控制延时次数,用延时时间调节转速
{delay(1000);}
}
}
if(f==2) // 反转
{
for(i=0;i<=3;i++)
{
P2=CCW[i]; //输出反转数据
for(j=0;j<=R;j++) //延时次数,控制延时时间
{delay(1000);} //延时
}
}
if(s4==0)
{ delay(50); //延时消抖
if(s4==0)
{
R=R+3; //改变延时次数
if(R>20) R=5;
}
while(s4==0);//松手检测
}
}
}
调试结果:
2.11 实训十一
代码:
#include <reg52.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^2; // ????
sbit KEY2 = P3^3; // ????
sbit PWM_OUT = P2^0;//??????
void delayms(uint);
uchar PWM_IN=15;
void main()
{
TMOD=0x10;
TH1=(65536-100)/256;
TL1=(65536-100)%256;
TR1 =1;
ET1 =1;
EA =1;
while(1)
{
if(!KEY1)//????+
{
delayms(5);
if(!KEY1)
{
if(PWM_IN<25)
{
while(!KEY1);
PWM_IN++;
}
}
}
if(!KEY2)
{
delayms(5);
if(!KEY2)
{
if(PWM_IN>5)
{
while(!KEY2);
PWM_IN--;
}
}
}
}
}
void timer0()interrupt 3 //???1?0.1ms????
{
static uchar count=0;
TH1=(65536-88)/256;
TL1=(65536-88)%256;
if(count<PWM_IN) //?????20ms,????0.1*PWM_IN
PWM_OUT=1;
else
PWM_OUT=0;
count++;
if(count>=200)count=0;
}
void delayms(uint j)//??????
{
uchar i;
for(;j>0;j--)
{
i=250;
while(--i);
i=249;
while(--i);
}
}
调试结果:
2.12 实训十二
代码:
#include<reg51.h>
sbit row0= P3^0;//控制U1的LE脚
sbit col0= P3^1;//控制U2的LE脚
unsigned char code led[][8]= //取字模
{ 0x0E,0x11,0x19,0x15,0x13,0x11,0x0E,0x00, // -0-
0x04,0x06,0x04,0x04,0x04,0x04,0x0E,0x00, // -1-
0x0E,0x11,0x10,0x0C,0x02,0x01,0x1F,0x00, // -2-
0x1F,0x10,0x08,0x0C,0x10,0x11,0x0E,0x00, // -3-
0x08,0x0C,0x0A,0x09,0x1F,0x08,0x08,0x00, // -4-
0x1F,0x01,0x0F,0x10,0x10,0x11,0x0E,0x00, // -5-
0x1C,0x02,0x01,0x0F,0x11,0x11,0x0E,0x00, // -6-
0x1F,0x10,0x08,0x04,0x02,0x02,0x02,0x00, // -7-
0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,0x00, // -8-
0x0E,0x11,0x11,0x1E,0x10,0x08,0x07,0x00, // -9-
};
void delay(unsigned int i)
{
while(i--);
}
void disp()
{
unsigned char x,h,i,k;//x显示数字,h行数据,i第几行,k重复显示次数
for(k=0;k<100;k++)
{
h=0x01; //显示第一行扫描数据
for(i=0;i<8;i++) //共8行
{
P0=0x00; row0=col0=1; row0=col0=0; //消屏
P0=h; row0=1; row0=0; // 控制行数据输出
P0=led[x][i]; // 相应字模数据输出到列
col0=1;col0=0;
delay(100); //显示延时
h=h<<1; // 移下一行
}
}
x=(x+1)%10; //取0~9数字显示
}
void main()
{
while(1)
{
disp(); //扫描显示
}
}
调试结果:
2.13 实训十三
代码:
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code dat[]={"0123456789"}; //0~9数字
uchar code str[12]={"The time is:"}; //字符串
uchar code mo[]={':'}; //冒号
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit RS=P2^0;
sbit E=P2^1;
uchar t,s;
char shi,fen,miao;
void delay(uint i)
{
while(i--);
}
void wrc(uchar com) //写指令
{
delay(2); //延时
RS=0; //RS=0写指令
P0=com;
E=1;
delay(2);
E=0;
}
void wrd(uchar d) //写数据
{
delay(2); //延时
RS=1; //RS=1写数据
P0=d;
E=1;
delay(2);
E=0;
}
void init(void) //初始化 /*常数定义*/
{
wrc(0x38); //写显示2行指令
wrc(0x0c); //写开显示指令
wrc(0x06); //写右移指令
wrc(0x01); //写清屏指令
}
void xianshi0(uchar x, y, shu) //显示1个字符
{ //位置,行,数
if(y==1)
x=x+0x40; //第2行+0x40,第1行挑过
x=x+0x80; //0x80为第0位地址
wrc(x); //写地址
wrd(shu); // 写数据
}
void xianshi2(uchar x, y, n, uchar *chan)//显示字符串
{ //位置,行,个数, 字符串
uchar i;
if(y==1)
x=x+0x40; //第2行+0x40,第1行挑过
x=x+0x80; //0x80为第0位地址
for(i=0;i<n;i++) //数个字符循环
{wrc(x+i); //地址+i
wrd(*chan++); //取字符代码,并写入数据
}
}
void key() //键盘设置调时功能
{
if(k1==0) // K1设置功能,按下为0
{
delay(200); // 延时消抖
if(k1==0) // 再测
{
TR0=0; // 停止计时
s++; //调时、分、秒功能设定
if(s==5) //5个功能
s=0;
}
}
while(k1==0); //检测K1是否松手
if(s==1) //功能1 调秒钟
{
if(k2==0) //K2为+1功能
{
delay(200);
if(k2==0)
miao++; //秒+1功能
if(miao==60)
miao=0;
}
while(k2==0); //检测K2是否松手
if(k3==0) //K3为-1功能
{
delay(200);
if(k3==0)
miao--; //秒-1功能
if(miao==-1)
miao=59;
}
while(k3==0);
}
if(s==2) //功能2 调分钟
{
if(k2==0) //分+1功能
{
delay(200);
if(k2==0)
fen++; //分+1
if(fen==60)
fen=0;
}
while(k2==0);
if(k3==0) // 分-1功能
{
delay(200);
if(k3==0)
fen--; //分-1
if(fen==-1)
fen=59;
}
while(k3==0);
}
if(s==3) //功能3 调整时钟
{
if(k2==0) //时+1功能
{
delay(200);
if(k2==0)
shi++; //时+1
if(shi==24)
shi=0;
}
while(k2==0);
if(k3==0) //时-1功能
{
delay(200);
if(k3==0)
shi--; //时-1
if(shi==-1)
shi=23;
}
while(k3==0);
}
if(s==4) //功能4 结束调整时间
TR0=1; //重新开始计时
}
void main()
{
TMOD=0x01; //定时器0,方式1
TH0=(65536-10000)/256; //定时10ms的初值高8位
TL0=(65536-10000)%256; //定时10ms的初值低8位
EA=1;ET0=1; //开定时器0中断
TR0=1; //启动计时
init(); //初始化
delay(200);
xianshi2(0,0,12,str); //第一行显示字符串"The time is:" ,共12个字符
while(1)
{
key(); //调用键盘子程序
xianshi0(3,1, dat[shi/10]); //显示时十位,第二行第3位开始
xianshi0(4,1, dat[shi%10]); //显示时个位
xianshi0(5,1,mo[0]); //显示冒号:
xianshi0(6,1, dat[fen/10]); //显示分十位
xianshi0(7,1, dat[fen%10]); //显示分个位
xianshi0(8,1,mo[0]); //显示冒号:
xianshi0(9,1, dat[miao/10]); //显示秒十位
xianshi0(10,1, dat[miao%10]); //显示秒个位
}
}
void time() interrupt 1 // 1为定时器0中断子函数
{
TH0=(65536-10000)/256; //重置初值
TL0=(65536-10000)%256;
t++;
if(t==100) //计定时t=100次为1秒钟
{
t=0; miao++; //秒加1
if(miao==60)
{
miao=0;fen++;//分加1
if(fen==60)
{
fen=0; shi++;//时加1
if(shi==24)
{
shi=0;
}
}
}
}
}
调试结果:
2.14 实训十四
代码:
#include "reg51.h"
#define uint unsigned int
#define uchar unsigned char
/**12864引脚及常数定义*/
sbit rs=P2^7; /* rs=1写数据,rs=0写指令 */
sbit rw=P2^6; /* rw=1读, rw=0写 */
sbit e=P2^5; /* 读,写使能,高电平有效,1→0下沿锁定数据 */
sbit cs1=P2^4; /* 左屏片选,高电平有效 */
sbit cs2=P2^3; /* 右屏片选,高电平有效 */
#define on 0x3f /* 开显示命令 */
#define x 0xb8 /* x地址(0页) */
#define y 0x40 /* y地址(0列) */
#define z 0xc0 /* Z地址(0行开始显示) */
uchar code zimo[][32]={
// 汉字字模表
// 汉字库: 宋体16×16 纵向取模下高位,数据排列:从左到右从上到下
/*-- 文字: 欢 --*/
0x14,0x24,0x44,0x84,0x64,0x1C,0x20,0x18,0x0F,0xE8,0x08,0x08,0x28,0x18,0x08,0x0,
0x20,0x10,0x4C,0x43,0x43,0x2C,0x20,0x10,0x0C,0x03,0x06,0x18,0x30,0x60,0x20,0x0,
/*-- 文字: 迎 --*/
0x40,0x41,0xCE,0x04,0x00,0xFC,0x04,0x02,0x02,0xFC,0x04,0x04,0x04,0xFC,0x00,0x0,
0x40,0x20,0x1F,0x20,0x40,0x47,0x42,0x41,0x40,0x5F,0x40,0x42,0x44,0x43,0x40,0x0,
/*-- 文字: 使 --*/
0x40,0x20,0xF0,0x1C,0x07,0xF2,0x94,0x94,0x94,0xFF,0x94,0x94,0x94,0xF4,0x04,0x0,
0x00,0x00,0x7F,0x00,0x40,0x41,0x22,0x14,0x0C,0x13,0x10,0x30,0x20,0x61,0x20,0x0,
/*-- 文字: 用 --*/
0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0xFE,0x00,0x0,
0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x42,0x82,0x7F,0x00,0x0,
};
void delay(uint i) //延时
{
while(i--);
}
void wrc(uchar com) /** 写命令 参数:com为要发送的命令 **/
{
delay(3); //忙等待(因ISIS仿真LCD没有忙信号)
rs=0; rw=0; //rs=0 , rw=0写命令
P0=com; //送出命令,
e=1; e=0; //1-0使之有效
}
void wrd(uchar d) /** 写数据 参数:d为要发送的数据 **/
{
delay(3); //忙等待(因ISIS仿真LCD没有忙信号)
rs=1;rw=0; //rs=1 ,rw=0写数据
P0=d; //送出数据
e=1; e=0; //1-0使之有效
}
void clr() //初始化清屏函数
{
uchar i,j;
wrc(on); //开显示
cs1=cs2=1; //同时选中左右屏
for(j=0;j<8;j++) //共8页
{
wrc(x+j); //光标到i页
wrc(y); //光标到0列
wrc(z); //光标到0行
for(i=0;i<64;i++) //共64列
wrd(0x00); //写0x00数字清屏
}
}
void shi(uchar H, L, zi, n, uchar *ma)
{ //显示: 页,列,字体,字数,字模地址
uchar i,j,m;
for(m=0;m<n;m++) //字个数n
{
for(j=0;j<2;j++) //一个字占2页
{
wrc(x+H+j); // 写起始页 + j页
wrc(y+L+zi*m); //写起始列+ 一个占的列数(zi*r)
for(i=0;i<zi;i++) //一个字的列数
wrd(*ma++); //取各个字模(写入字码数据)
}
}
}
void xian() // 显示函数
{
cs1=1;cs2=0; //选择左半屏
shi(3,32,16,2,zimo[0]); //从第3页32列取zimo第0个字开始2个字,显示"欢迎"
cs1=0;cs2=1; //选择右半屏
shi(3,0,16,2,zimo[2]); //从第3页0列取zimo第2个字开始2个字,显示"使用"
}
void main() //主函数
{
clr(); //初始化清屏
xian(); // 显示
while(1); //等待
}
调试结果:
2.15 实训十五
代码:
#include < reg51.h> //51芯片管脚定义头文件
#include < intrins.h> //内部包含延时函数
#define uchar unsigned char
#define uint unsigned int
sbit sh_cp=P1^0; //移位时钟脉冲
sbit ds=P1^1; // 串行数据输入
sbit st_cp=P1^2 ; //输出锁存器控制脉冲
uchar temp ;
uchar code DAT[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f} ;
/****延时子程序 ****/
void delay(uint ms)
{
uint k ;
while(ms--) for(k=0 ; k<300; k++) ;
}
/****将显示数据送入74HC595内部移位寄存器 ****/
void in_595()
{
uchar j ;
for (j=0 ;j<8 ;j++)
{
temp<<=1 ;
ds=CY ;
sh_cp=1 ; //上升沿发生移位
_nop_() ;
sh_cp=0 ;
}
}
/****将移位寄存器内的数据锁存到输出寄存器并显示 ****/
void OUT_595()
{
st_cp=0 ;
_nop_() ;
st_cp=1 ; //上升沿将数据送到输出锁存器
_nop_() ;
st_cp=0 ; //锁存显示数据
}
/**** 主程序 ****/
main()
{
sh_cp=0 ;
st_cp=1 ;
while(1)
{
uchar i ;
for (i=0 ; i<8 ; i++)
{
temp=DAT[ i ] ; //取显示数据
in_595() ; //temp中的一字节数据串行输入到74HC595
OUT_595() ; //74HC595移位寄存器传输到存储寄存器并出现在输出端
delay(150) ;
}
}
}
调试结果:
2.16 实训十六
代码:
#include<reg51.h> //包含单片机寄存器的头文件
unsigned char code Tab[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, 0x7F, 0x6F}; //数码管显示控制码
/****串行口发送一个字节数据****/
void Send(unsigned char dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
/****延时****/
void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++);
}
/****主函数****/
void main(void)
{
unsigned char i;
TMOD=0x20; //TMOD=0010 0000B,定时器T1工作于方式2
SCON=0xc0; //SCON=1100 0000B,串口工作方式3,
//SM2置0,不使用多机通信,TB8置0
PCON=0x00; //PCON=0000 0000B,波特率9600
TH1=0xfd; //根据规定给定时器T1赋初值
TL1=0xfd; //根据规定给定时器T1赋初值
TR1=1; //启动定时器T1
while(1)
{
for(i=0;i<10;i++) //模拟检测数据
{
Send(Tab[i]); //发送数据i
P0=Tab[i]; //发送数据i在P0口输出
delay(); //延时发送一次检测数据
}
}
}
调试结果:
2.17 实训十七
代码:
#include "reg51.h"
//****宏定义****//
#define uchar unsigned char
#define uint unsigned int
//****端口定义****//
sbit a1_82=P3^2;
sbit a0_82=P3^3;
sbit wr=P3^4;
sbit cs=P3^5;
//****变量定义****//
uchar time;
//**********写8255**********//
void w_8255(bit a1,bit a0,uchar com)
{
//片选开
cs=0;
//端口选择
a1_82=a1;
a0_82=a0;
//送指令
P1=com;
//送脉冲
wr=0;
wr=0;
wr=1;
//片选关
cs=1;
}
//********延时子程序*********//
void delay(uchar x)
{
uint i;
while (--x)
{
for (i=0;i<10000;i++);
}
}
//**********主程序***********//
void main()
{
//**8255工作方式控制字**//
// 10011000
// A口方式输入,PC7~PC4输入
// B口方式输入,PC3~PC0输出
//**********************//
w_8255(1,1,0x98);
while (1)
{
if(time==0)//A车道绿灯亮
w_8255(0,1,0x1e);
//黄灯闪烁//
if(time==5||time==15)//AB车道黄灯亮
w_8255(0,1,0x2d);
if(time==6||time==16)//AB车道黄灯灭
w_8255(0,1,0xff);
if(time==7||time==17)//AB车道黄灯亮
w_8255(0,1,0x2d);
if(time==8||time==18)//AB车道黄灯灭
w_8255(0,1,0xff);
if(time==9||time==19)//AB车道黄灯亮
w_8255(0,1,0x2d);
//*******//
if(time==10)//B车道绿灯亮,A_G=1,A_Y=1,A_R=0,B_G=0,B_Y=1,B_R=1
w_8255(0,1,0x33);
//计时,每秒变量+1
delay(5);
if(++time>=20) time=0;
}
}
调试结果:
2.18 实训十八
代码:
#define _1_C_
#include "reg51.h"
#include "1.h"
#include "intrins.h"
//*--------------宏定义---------------*//
#define uchar unsigned char
#define uint unsigned int
//*-------------小液晶端口------------*//
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
//--------------18B20端口-------------*//
sbit DQ=P1^7;
//--------------显示内容--------------*//
uchar code table[]="Temperature:";
//*---------------变量----------------*//
uint wen=100,wen_buf=123;
//*--------------初始化---------------*//
void init_sys()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x18;
EA=1;
ET0=1;
TR0=1;
}
//*-------------毫秒延时--------------*//
void delay(uchar x)
{
uchar j;
while (x--)
{
for(j=0;j<123;j++);
}
}
//*-------------微秒延时--------------*//
void delayus(uchar x)
{
uchar j;
for (j=x;j<100;j--);
}
//*--------------写命令---------------*//
void w_com(uchar com)
{
P0=com;
RW=0;
RS=0;//命令
EN=0;//上升沿有效
delay(5);
EN=1;
}
//*--------------写数据---------------*//
void w_dat(uchar dat)
{
P0=dat;
RW=0;
RS=1;//数据
EN=0;//上升沿有效
delay(5);
EN=1;
}
//*-------------写一串字----------------*//
void display()//zb--坐标,what--选择内容
{
uchar num=0;//选择写第几个字符的变量
w_com(0x80);
//循环写完一串字符
while(table[num] != '\0')
{
w_dat(table[num]);//第what内容的num个字符
num++;//写下一个字符
delay(3);
}
}
//*------------清屏初始化-------------*//
void init_LCD()
{
P0=0;
w_com(0x38);//显示模式设置,开始要求检测忙信号:8位、2行、5X7点阵
w_com(0x08);//关闭显示
w_com(0x01);//清屏
w_com(0x06);//显示光标移动设置:文字不动,光标自动右移
w_com(0x0c);//显示开及光标设置:光标关
}
void LCD()
{
display();
w_com(0xc0);
w_dat(wen/100+0x30);
w_dat(wen/10%10+0x30);
w_dat('.');
w_dat(wen%10+0x30);
w_dat(0xdf);
w_dat('C');
}
//....................ds18B20温度检测..........................//
void init18b20(void) //ds18b20初始化
{
uchar x;
DQ=1;
delayus(5);
DQ=0;
delayus(80);
DQ=1;
delayus(10);
x=DQ;
delayus(10);
}
void write18b20(uchar dat) //写数据
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delayus(5);
DQ=1;
dat>>=1;
}
delayus(5);
}
uchar read18b20(void) //读数据
{
uchar dat=0;
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
if(DQ) dat|=0x80;
delayus(5);
}
return(dat);
}
void readtmp(void) //读温度
{
uchar a,b,c;
init18b20();
write18b20(0xcc);//跳过读序列号
write18b20(0x44);//开始转换
init18b20();
write18b20(0xcc);//跳过读序列号
write18b20(0xbe);//读取温度
a=read18b20();
b=read18b20();
c=a&0x0f;//分离出小数部分
b=(b&0x0f)<<4;
b|=(a&0xf0)>>4;//b里放整数
wen=b;
wen=wen*10;
// xiaoshu=625*c;//可以直接用移位, 不用小数位可去掉
}
void main()
{
init_LCD();//清屏初始化
init_sys();
while (1)
{
}
}
void timer0() interrupt 1
{
static uint t1;
TH0=0xfc;
TL0=0x18;
//
if(wen!=wen_buf)//温度变化时才刷新一次
{
wen_buf=wen;
LCD();
}
//无需实时刷新
if(++t1>=500)
{
t1=0;
readtmp();
}
}
调试结果:
2.19 实训十九
代码:
#include<reg52.h>
unsigned char code tabled[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char disp[4]={0,0,0,0};
unsigned int results,getdata;
char j;
sbit ST=P3^0; // 定义端口
sbit OE=P3^1;
sbit EOC=P3^2;
sbit S1=P2^0;
sbit S2=P2^1;
sbit S3=P2^2;
sbit S4=P2^3;
sbit a = P2^5;
sbit b = P2^6;
sbit c = P2^7;
void delay(unsigned int);
void display();
void adc0809();
void main()
{
while(1)
{
adc0809();
display();
}
}
void delay(unsigned int z) //延时子程序
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void adc0809() //ADC0809转换子程序
{
a=1;
b=0;
c=0; //选择1通道
OE=0;
ST=0;
ST=1; // 启动A/D转换
ST=0;
while(EOC==0); //转换是否结束
OE=1; //打开输出端口
getdata=P0; //读取转换数据
OE=0;
results = getdata*196; //数据换算
disp[2] = results/10000;
disp[1] = (results/1000)%10;
disp[0] = (results/100)%10;
}
void display()
{
S1 = 1;
P1 = tabled[disp[2]]+0x80; //显示个位及小数点
S1 = 0;
delay(5);
S1 = 1;
S2 = 1;
P1 = tabled[disp[1]]; //显示十分位
S2 = 0;
delay(5);
S2 = 1;
S3 = 1;
P1 = tabled[disp[0]]; //显示百分位
S3 = 0;
delay(5);
S3 = 1;
}
调试结果:
2.20 实训二十
代码:
#include<reg51.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define DAC0832 XBYTE[0X7FFF] //DAC0832在系统中的地址为0X7FFF
sbit s1=P1^0; //方波按键
sbit s2=P1^1; //三角波按键
sbit s3=P1^2; //正弦波按键
uchar key1;
uchar keya;
uchar keyb;
uchar keyc;
uchar code ZXB_code[256]={
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,
0xa5,0xa8,0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,
0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,0xda,0xdc,0xde,0xe0,
0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,
0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf3,0xf2,
0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,
0xda,0xd8,0xd6,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,
0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,
0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,
0x73,0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,
0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,0x31,
0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,
0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,
0x3,0x3,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xc,0xd,
0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,
0x25,0x27,0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,
0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,
0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c
};
uchar code sanjiao[64]={
0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
};
void delay(uint z) //延时子程序
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void init()
{
TMOD=0x01;
TH0=(65536-400)/256;
TL0=(65536-400)%256;
EA=1;
ET0=1;
TR0=1;
}
void zhengxianbo()
{
uchar i;
while(1)
{ if(keya==1)
{for(i=0;i<255;i++) //产生正弦波
DAC0832=ZXB_code[i];
}
else break;
}
}
void sanjiaobo()
{
uchar i;
while(1)
{ if(keyb==1)
{for(i=0;i<255;i++) //产生三角波
DAC0832=i;
for(i=255;i>0;i--)
DAC0832=i;
}
else break;
}
}
void fangbo() //产生方波
{
while(1)
{
if(keyc==1)
{
DAC0832=0x00;
delay(10);
DAC0832=0xff;
delay(10);
}
else break;
}
}
void main()
{
init();
while(1)
{
switch(key1)
{
case 0x01: //按下S1,输出正弦波
zhengxianbo();
break;
case 0x02: //按下S2,输出三角波
sanjiaobo();
break;
case 0x03: //按下S3,输出方波
fangbo();
break;
}
}
}
void time1() interrupt 1
{
TH0=(65536-400)/256;
TL0=(65536-400)%256;
if(s1==0)
{key1=0x01;keya=1;keyb=0;keyc=0;}
if(s2==0)
{key1=0x02;keya=0;keyb=1;keyc=0;}
if(s3==0)
{key1=0x03;keya=0;keyb=0;keyc=1;}
}
调试结果 :