单片机考试编程题.docx
- 文档编号:7036279
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:23
- 大小:36.93KB
单片机考试编程题.docx
《单片机考试编程题.docx》由会员分享,可在线阅读,更多相关《单片机考试编程题.docx(23页珍藏版)》请在冰豆网上搜索。
单片机考试编程题
一、C语言编程实现单片机I/0口控制数码管的显示
1.用定时0的方式1实现数码管两位59S循环计时(计时器)
思路方案:
利用单片机的定时器/计数器定时和计数的原理,通过proteus仿真软件来实现模拟实现。
模拟利用AT89C51单片机、LED数码管实现秒表的计时。
其中一个两位数码管用来显示数据,一位用来显示个位秒,另一位用来显示十位秒。
当计数超过范围时所有数码管全部清零重新计数。
程序代码如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharnum,count,ge,shi;
voiddelay(uint);
voiddisplay(uchar,uchar);
ucharSEG[]={0xc0,0xf9,0xa4,0xb0,0x99,//显示数码管0-9数字
0x92,0x83,0xf8,0x80,0x98};
voidmain()
{
TMOD=0x01;//设置定时器工作方式T0的工作方式为1
TH0=(65536-45872)/256;//装初值11.0592M晶振定时50ms数为45872
TL0=(65536-45872)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
while
(1)//程序在这里不停的对数码管动态扫描同时等待中断发生
{
display(shi,ge);
}
}
/*以下是设计中断服务程序的时间和显示*/
voidT0_time()interrupt1
{
TH0=(65536-45872)/256;//重装初值
TL0=(65536-45872)%256;
if(++num==20)//如果到了20次,说明1秒时间到
{
num=0;//然后把num清0重新再记20次
if(++count==60)//这个数用来送数码管显示,到60后归0
count=0;
shi=count/10;//把一个2位数分离后分别送数码管显示,十位和个位
ge=count%10;
}
}
/*以下为延迟函数*/
voiddelay(uintxms)
{
uinti,j;
for(i=xms;i>0;i--)//延迟时间为xms乘以50ms
for(j=110;j>0;j--);
}
/*以下为显示数码管的子函数*/
voiddisplay(ucharshi,ucharge)
{
P3=0xfe;//打开P3.0,及打开数码管1引脚
P2=SEG[ge];
delay(20);
P3=0xfd;//打开P3.1,及打开数码管2引脚
P2=SEG[shi];
delay(20);
}
2.基于单片机V1或V2实验系统,编写一个程序,实现以下功能:
1)首先在数码管上显示“P___”4个字符;2)等待按键,如按了任何一个键,则将这4个字符清除,改为显示“0000”4个字符(为数字的0)。
#include
unsignedcharcodeDig[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//gongyang数码管0-F代码
unsignedchark;//设置全局变量k为键盘的键值
/************************************键盘延时函数****************************/
voidkey_delay(void)//延时函数
{
intt;
for(t=0;t<500;t++);
}
/************************************键盘扫描函数******************************/
voidkeyscan(void)//键盘扫描函数
{
unsignedchara;
P2=0xf0;//键盘初始化
if(P2!
=0xf0)//有键按下?
{
key_delay();//延时
if(P2!
=0xf0)//确认真的有键按下?
{
P2=0xfe;//使行线P2.4为低电平,其余行为高电平
key_delay();
a=P2;//a作为缓存
switch(a)//开始执行行列扫描
{
case0xee:
k=15;break;
case0xde:
k=11;break;
case0xbe:
k=7;break;
case0x7e:
k=3;break;
default:
P2=0xfd;//使行线P2.5为低电平,其余行为高电平
a=P2;
switch(a)
{
case0xed:
k=14;break;
case0xdd:
k=10;break;
case0xbd:
k=6;break;
case0x7d:
k=2;break;
default:
P2=0xfb;//使行线P2.6为低电平,其余行为高电平
a=P2;
switch(a)
{
case0xeb:
k=13;break;
case0xdb:
k=9;break;
case0xbb:
k=5;break;
case0x7b:
k=1;break;
default:
P2=0xf7;//使行线P2.7为低电平,其余行为高电平
a=P2;
switch(a)
{
case0xe7:
k=12;break;
case0xd7:
k=8;break;
case0xb7:
k=4;break;
case0x77:
k=0;break;
default:
break;
}
}
}
break;
}
}
}
}
/*********************************主函数*************************************/
voidmain(void)
{
while
(1)
{
keyscan();//调用键盘扫描函数
switch(k)//查找按键对应的数码管显示代码
{
case0:
P0=Dig[0];break;
case1:
P0=Dig[1];break;
case2:
P0=Dig[2];break;
case3:
P0=Dig[3];break;
case4:
P0=Dig[4];break;
case5:
P0=Dig[5];break;
case6:
P0=Dig[6];break;
case7:
P0=Dig[7];break;
case8:
P0=Dig[8];break;
case9:
P0=Dig[9];break;
case10:
P0=Dig[10];break;
case11:
P0=Dig[11];break;
case12:
P0=Dig[12];break;
case13:
P0=Dig[13];break;
case14:
P0=Dig[14];break;
case15:
P0=Dig[15];break;
default:
break;//退出
}
}
}/**********************************end***************************************/
3.利用AT89S52单片机来制作一个0~99计时器,并且通过两个共阴数码管显示计数结果,数码管显示采用静态显示方式。
#include
/*定义0~9十个数字的字型码表*/
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharCount;//定义变量放置计数数值
voiddelay10ms(void)//定义10ms延时函数
{
unsignedchari,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
voidmain(void)
{
Count=0;//计数变量初始为0
For(Count=0;Count<10;Count++)
{
P0=table[Count/10];//显示十位数
P2=table[Count%10];//显示个位数
delay10ms();
}
while
(1)//等待
}
4.将单片机与数码管接成图4-2所示静态显示方式,编程实现数码管每隔0.5s的0-9数字显示。
#include
#defineucharunsignedchar
sbita=P0^5;
sbitb=P0^6;
sbitc=P0^7;
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedchardispcount;
voiddelay02s(void)
{unsignedchari,j,k;
for(i=10;i>0;i--)
for(j=200;j>0;j--)
for(k=248;k>0;k--);
}
voidmain(void)
{while
(1)
{for(dispcount=0;dispcount<10;dispcount++)
{
a=0;
b=0;
c=0;
P1=table[dispcount];
delay02s();
}
}
}
5.单片机与数码管接成动态显示方式,编程实现数码管的0-7数字显示。
#include
#defineucharunsignedchar
unsignedcharcodetabledu[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodetablewe[]={0x1f,0x3f,0x5f,0x7f,0x9f,
0xbf,0xdf,0xff};
unsignedchardispcount;
voiddelay02s(void)
{unsignedchari,j,k;
for(i=10;i>0;i--)
for(j=200;j>0;j--)
for(k=248;k>0;k--);}
voidmain(void)
{while
(1)
{for(dispcount=0;dispcount<8;dispcount++)
{P0=tablewe[dispcount];
P1=tabledu[dispcount];
delay02s();}
}
}
6.本任务是实现0~999的加1S计数显示。
#include
#defineucharunsignedchar
sbita=P0^5;
sbitb=P0^6;
sbitc=P0^7;
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedchardispcount,bai,shi,ge;
unsignedinttemp,aa;
voiddisplay();
voiddelay02s(void)
{unsignedchari,j,k;
for(i=1;i>0;i--)
for(j=100;j>0;j--)
for(k=200;k>0;k--);}
voiddelay05s(void)
{unsignedchars,m,t;
for(s=2;s>0;s--)
{for(m=200;m>0;m--)
{for(t=250;t>0;t--)
{;}
}
}
}
voidmain(void)
{temp=0;
while
(1){delay05s();
delay05s();
temp++;
display();}}
voiddisplay()
{if(temp==999)
{temp=0;}
bai=temp/100;
shi=temp%100/10;
ge=temp%10;
a=0;b=1;c=0;
P1=table[bai];
delay02s();
a=1;b=0;c=0;
P1=table[shi];
delay02s();
a=0;b=0;c=0;
P1=table[ge];
delay02s();}
7.采用数码管进行数字时钟显示时间,并通过按键调整时间。
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitkey3=P0^3;//时调整
sbitkey2=P0^2;//分调整
sbitkey1=P0^1;//秒调整
sbitkey0=P0^0;//全部清零键
ucharcodetab1[]=
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x80};//共阳0~9/-段码/点
ucharcodetab2[]={0x1f,0x3f,0x5f,0x7f,0x9f,0xbf,0xdf,0xff};//0~7依次位码表
ucharsec,min,hour,count;//定义秒,分,时,中断计数
voiddelay(uintz)//延时子函数
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//--------------------------------------------------------------
voidinit()//初始化T0函数
{
TMOD=0x01;//T0-方式1-16位计时器
TH0=(65536-50000)/256;//50MS
TL0=(65536-50000)%256;//晶振:
12M计算
EA=1;//开总中断
ET0=1;//允许T0中断
TR0=1;//启动T0中断
}
voidtimer0()interrupt1//定时器函数
{
TH0=(65536-50000)/256;//50MS
TL0=(65536-50000)%256;//晶振:
12M计算
count++;//50毫秒中断一次count便加1
if(count>=20)//中断了20次?
(20*50=1秒)
{count=0;sec++;}//计数清零/秒加1
if(sec==60)//满了60秒?
{sec=0;min++;}//秒清零/分加1
if(min==60)//满了60分钟?
{min=0;hour++;}//分清零/时加1
if(hour==24)//满了24小时?
{hour=0;}//时清零
}
voiddisplay()//数码管显示子函数
{
uchars;
for(s=0;s<=10;s++)//扫描//控制显示刷新和按键速度
{
P1=tab1[hour/10];
P0=tab2[7];delay
(2);//时十位
P1=tab1[hour%10];
P0=tab2[6];delay
(2);//时个位
P1=tab1[11];
P0=tab2[5];delay
(2);//横
P1=tab1[min/10];
P0=tab2[4];delay
(2);//分十位
P1=tab1[min%10];
P0=tab2[3];delay
(2);//分个位
P1=tab1[11];
P0=tab2[2];delay
(2);//横
P1=tab1[sec/10];
P0=tab2[1];delay
(2);//秒十位
P1=tab1[sec%10];
P0=tab2[0];delay
(2);//秒个位
}
}
voidkey()//按键调整子函数
{
if(key1==0)//秒调整
{delay(10);
if(key1==0){sec++;if(sec==60)sec=0;}//调到了60?
}
if(key2==0)//分调整
{delay(10);
if(key2==0){min++;if(min==60)min=0;}//调到了60?
}
if(key3==0)//时调整
{delay(10);
if(key3==0){hour++;if(hour==24)hour=0;}//调到了24?
}
if(key0==0)//全部归清零按
{delay(10);
if(key0==0){sec=min=hour=0;}//秒/分/时清零
}
}
voidmain()//主函数
{
init();//T0初始化
while
(1)//死循环
{
key();//调整函数
display();//显示函数
}
}
8.在8个LED数码管上,按从左到右的顺序,循环滚动显示数字“5”,每次滚动延时500ms
#include
unsignedcharLED;
voidDelay(unsignedintmilisec)//延时1ms
{
unsignedinti,j;
for(i=milisec;i>0;i--)//双重for循环实现延时1ms
for(j=110;j>0;j--);
}
voidMain(void)
{
P0=0x6d;//显示数字“5”
while
(1)
{
for(LED=0;LED<=7;LED++)
{
P2=LED;//选择LED,实现滚动显示
Delay(500);//延时500ms
}
}
}
9.在8个LED上稳定地显示“01234567”
#include
unsignedcharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodeLED[8]={0,1,2,3,4,5,6,7};
voidDelay(unsignedintmilisec)//延时1ms
{
unsignedinti,j;
for(i=milisec;i>0;i--)
for(j=110;j>0;j--);
}
voidMain(void)
{
unsignedchari=0;
while
(1)
{
P0=table[i];//取一个数的段位码
P2=LED[i];//点亮一个数码管
Delay
(2);//延时2ms
i++;//移位
if(i==8)i=0;//重新开始
}
}
unsignedcharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
10.在8个LED上显示计算机教研室的电话号码“68752219”
#include
unsignedcharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodeNumber[8]={6,8,7,5,2,2,1,9};
voidDelay(unsignedintmilisec)//延时1ms
{
unsignedinti,j;
for(i=milisec;i>0;i--)
for(j=110;j>0;j--);
}
voidMain(void)
{
unsignedchari=0,j;
while
(1)
{
j=Number[i];//取一个待显示的数
P0=table[j];//取一个数的段位码
P2=i;//点亮一个数码管
Delay
(2);//延时2ms
i++;//移位
if(i==8)i=0;//重新开始
}
}
二.串行数据的发送和接收
1.用89C52串行口外接164串入/并出移位寄存器扩展8位并行输出口,外接165并入/串出移位寄存器扩展8位并行输入口。
8位并行输出口的每位都接一个发光二极管,要求从8位并行输入口读入开关的状态值,使闭合开关对应的发光二极管点亮。
解:
数据的输入输出通过RXD接收和发送,移位时钟通过TXD送出,74HC164用于串/并转换,74HC165用于并/串转换。
C语言程序清单:
#include
sbitP1_0=P1^0;
sbitP1_1=P1^1;
unsignedchardata1;
voidmain()
{
SCON=0x10;//串行口方式0,允许接收
ES=1;
EA=1;//允许串行口中断
P1_0=0;//关闭并行输出
P1_1=1;//并行置入数据
P1_1=0;//开始串行移位
SBUF=0;//送入串行数据
while
(1);//等待中断
}
voids_srv()interrupt4//中断服务程序
{
if(TI)//发送中断
{TI=0;
P1_0=1;//打开并行输出
}
else//接收中断
{RI=0;
data1=SBUF;//读取接收的数据
P1_0=0;//关
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 考试 编程