单片机经典试题及答案

1.循环显示学号,循环起点为学号后四位,最大值为9999.

2.利用三位数码管显示电路,显示学号的后三位;

要求使用定时器中断进行三位数码管扫描显示。

所有文件放置在一个文件夹中,文件夹名称为学号+姓名;(如:20102814***###,)电路图和程序工程文件用学号命名。

3.利用298驱动一个直流电机;

利用定时计数器的计数方式,在计数引脚上接一个按键,按键按下2次,电机更换旋转方向,循环往复。

所有文件放置在一个文件夹中,文件夹名称为学号+姓名;(如:20102814***###,)电路图和程序工程文件用学号命名。

4.利用一个L298驱动一个直流电机;

利用定时器中断实现该直流电机,正转6秒然后翻转六秒循环往复。

所有文件放置在一个文件夹中,文件夹名称为学号+姓名;(如:20102814***###,)电路图和程序工程文件用学号命名。

5.设计电路有上下(或左右排列)的四个发光二极管和2*2的矩阵键盘;

扫描按键,当按下某个按键时,与之对应的发光二极管点亮。

所有文件放置在一个文件夹中,文件夹名称为学号+姓名;(如:20102814***###,)电路图和程序工程文件用学号命名。

6.利用一位数码管显示学号后三位;

将一个开关接到外部中断引脚上,每进一次中断更换所显示的学号位数。

所有文件放置在一个文件夹中,文件夹名称为学号+姓名;(如:20102814***###,)电路图和程序工程文件用学号命名。

循环显示学号

#include

#define unit unsigned int

#define uchar unsigned char

sbit P20=P2^0;

sbit P21=P2^1;

sbit P22=P2^2;

sbit P23=P2^3;

unit count=4425,i,j,a;

unit ge,shi,bai,qian;

const uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00}; void delay()

{

for(i=0;i<256;i++);

}

void time0(void) interrupt 1 using 1

{

TH0=0x3c;

TL0=0xb0;

j++;

if(j==10)

{

j=0;

a++;

}

if(a==4)

{

a=0;

}

}

void main(void)

{

P2=0x00;

a=0;

count=425;

TMOD=0x01;

TH0=0x3c;

TL0=0xb0;

EA=1;

ET0=1;

TR0=1;

while(1)

{

ge=count%10;

shi=count/10%10;

bai=count/100%10;

if(a==0)

{

P1=tab[ge];

P23=1;

delay();

P23=0;

}

if(a==1)

{

P1=tab[shi];

P22=1;

delay();

P22=0;

}

if(a==2)

{

P1=tab[bai];

P21=1;

delay();

P21=0;

}

}

}

两次按键电机反转

#include

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

#define CLK_WISE 0

#define INVERSE 1

sbit CTRL0=P2^0;

sbit CTRL1=P2^1;

uchar levelflag=0,i;

bit direction=CLK_WISE;

uchar highcount;

/****改变转向标志*****/

void int1_srv (void) interrupt 2 using 2 {

if(INT1==0)

{

i++;

if(i==2)

{

i=0;

while(!INT1);

direction=!direction;

}

}

}

/****延时****/

void delay(uchar i)

{

while(i--)

;

}

/*****改变转向*****/

void run(void)

{

if(direction==CLK_WISE) //顺时针转

{

CTRL1=0;

CTRL0=1;

}

if(direction==INVERSE) //逆时针转

{

CTRL0=0;

CTRL1=1;

}

}

void main()

{

EA=1;

EX1=1;

IT1=1;//外部中断1

while(1)

{

run();

}

}

六秒反转

#include

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

#define CLK_WISE 0

#define INVERSE 1

sbit CTRL0=P2^0;

sbit CTRL1=P2^1;

uchar levelflag=0;

bit direction=CLK_WISE;

uchar i;

/***定时器t0***/

void time0(void) interrupt 1 using 1 {

TH0=0x3c;

TL0=0xB0;

i++;

if(i==120)

{

i=0;

direction=!direction;

}

}

/****延时****/

void delay(uchar i)

{

while(i--)

;

}

/*****改变转向*****/

void run(void)

{

if(direction==CLK_WISE) //顺时针转

{

CTRL1=0;

CTRL0=1;

}

if(direction==INVERSE) //逆时针转

{

CTRL0=0;

CTRL1=1;

}

}

void main()

{

EA=1;

TMOD=0x01;

ET0=1;//定时器0初始化

TR0=1;

TH0=0x3c;

TL0=0xB0;

while(1)

{

run();

}

}

键盘led

#include

extern void Timer0_Init(void);

extern void Delay(unsigned int n);

extern void Scan_Key(void);

unsigned char ptr,m;

sbit P20=P2^0;

sbit P21=P2^1;

sbit P22=P2^2;

sbit P23=P2^3;

void main(void)

{

while(1)

{

Scan_Key(); //扫描键盘

}

}

void Delay(unsigned int n) //延时

{

unsigned int i,j;

for(i=0;i

{

for(j=0;j<80;j++);

}

}

void Scan_Key(void) // 键盘扫描程序{

char a1,i;

bit FLAG0=0;

a1=0xfd; //列扫描初值ptr=0;

for(i=0;i<2;i++) //键盘4个扫描列

{ P1=a1;

Delay(10);

m=P1;

switch(m&0xd0) //取行的高4位,侦测哪一行有按键被按下

{

case 0x50: ptr=i*2;

if(ptr==0)

P20=!P20;

else

P22=!P22;

break;

case 0x90: ptr=i*2+1;

if(ptr==1)

P21=!P21;

else

P23=!P23;

break;

}

a1=a1>>1 | 0x80; //高位补1,由于P1.4~P1.7未接+5V,

//通过指令加载高电平

}

}

学号单位显示

#include

#define uint unsigned int

#define uchar unsigned char

sbit P20=P2^0;

uchar count;

uchar GE,SHI,BAI;

uint XUEHAO=425;

const uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,}; /*显示0~9*/ void delay()

{

uint i,j;

for(i=0;i<256;i++);

for(j=0;j<256;j++);

}

void int0() interrupt 0 using 1

{

count++;

if (count==3)

count=0;

}

void main(void)

{

IT0=1;

EX0=1;

EA=1;

while(1)

{

GE=XUEHAO%10;

SHI=XUEHAO/10%10;

BAI=XUEHAO/100;

if(count==0)

{

P1=tab[BAI];

P20=1;

delay();

P20=0;

}

if(count==1)

{

P1=tab[SHI];

P20=1;

delay();

P20=0;

}

if(count==2)

{

P1=tab[GE];

P20=1;

delay();

P20=0;

}

}

}

自加循环

#include

#define unit unsigned int

#define uchar unsigned char

sbit P20=P2^0;

sbit P21=P2^1;

sbit P22=P2^2;

sbit P23=P2^3;

unit count=425,i,j;

unit ge,shi,bai,qian,wan ;

const uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,}; void delay()

{

for(i=0;i<256;i++);

}

void time0(void) interrupt 1 using 1

{

TH0=0x3c;

TL0=0xb0;

j++;

if(j==10)

{

j=0;

count++;

}

if(count==9999)

{

count=425;

}

}

void main(void)

{

count=425;

TMOD=0x01;

TH0=0x3c;

TL0=0xb0;

EA=1;

ET0=1;

TR0=1;

while(1)

{

ge=count%10;

shi=count/10%10;

bai=count/100%10;

qian=count/1000;

P1=tab[ge];

P23=1;

delay();

P23=0;

P1=tab[shi];

P22=1;

delay();

P22=0;

P1=tab[bai];

P21=1;

delay();

P21=0;

P1=tab[qian];

P20=1;

delay();

P20=0;

}

}

串口

程序一#include

//初始化串行口void csh()

{

SM0=0;

SM1=1;

REN=1;

TI=0;

RI=0;

PCON=0;

TH1=0xF3;

TL1=0XF3;

TMOD=0X20;

EA=1;

ET1=0;

ES=1;

TR1=1;

}

void main()

{

int i,j;

char c=0;

csh();

while(1)

{

ES=0;

TI=0;

P0=c;

SBUF=c;

while(!TI);

TI=0;

ES=1;

for(j=0;j<50;j++)

for(i=0;i<5000;i++);

c++;

if (c>9)

c=0;

}

}

void intrr() interrupt 4

{

char temp;

temp=SBUF;

P2=temp;

RI=0;

}

程序二

#include

//初始化串行口

void csh()

{

SM0=0;

SM1=1;

REN=1;

TI=0;

RI=0;

PCON=0;

TH1=0xF3;

TL1=0XF3;

TMOD=0X20;

EA=1;

ET1=0;

ES=1;

TR1=1;

}

void main()

{

csh();

while(1)

{;}

}

void intrr() interrupt 4

{

char temp;

temp=SBUF;

P2=temp;

RI=0;

temp++;

if (temp>9)

temp=0;

ES=0;

TI=0;

P0=temp;

SBUF=temp;

while(!TI);

TI=0;

ES=1;

}

简单电机

#include

#include

#define unit unsigned int

#define uchar unsigned char

#define AD XBYTE [0x7FF8]

#define CLK_WISE 0 //顺时针方向转动

#define INVERSE 1 //逆时针方向转动

#define HIGH 2 //高电平

#define LOW 1 //低电平

#define NULL 0 //低电平

sbit CTRL0=P3^0; //CTRL0为高电平,CTRL1为低电平时顺时针方向转动

sbit CTRL1=P3^1; //CTRL0为低电平,CTRL1为高电平时逆时针方向转动uchar levelflag=0; //高低电平标志,取值为HIGH或LOW,分别代表高电平和低电平,或为NULL

bit direction=CLK_WISE; /***方向标志,取值为CLK_WISE 或INVERSE*/

int i;

sbit ad_busy=P3^2; //P3.2用于检测EOC信号,判断是否转换结束

static uchar speedcount=0; //加速标志,越大转速越快,最大到10,然后回归到0,循环。

//程序中可以依据它来改变占空比

uchar highcount=0; //记录高电平定时次数

unsigned char ad_data;

/***定时器t0***/

void time0(void) interrupt 1 using 1

{

TH0=0xff;

TL0=0xCE;

highcount++; //记录一出次数

//频率为固定的2kHZ左右,只是占空比发生变化if(highcount<=ad_data)

levelflag=HIGH; //高电平次数

if((highcount>ad_data)&&(highcount<=255))

levelflag=LOW; //低电平次数

if(highcount==255) //最大为10,然后从0开始循环。

highcount=0;

}

/****改变转向标志*****/

void int1_srv (void) interrupt 2 using 2

{

if(INT1==0)

{

while(!INT1);

direction=!direction;

}

}

/*****改变转向*****/

void run(void)

{

if(direction==CLK_WISE) //顺时针转

{

CTRL1=1;

if(levelflag==HIGH) //高电平

{

levelflag=NULL;

CTRL0=0;

}

if(levelflag==LOW) //低电平

{

levelflag=NULL;

CTRL0=1;

}

}

if(direction==INVERSE) //逆时针转

{

CTRL0=1;

if(levelflag==HIGH) //高电平

{

levelflag=NULL;

CTRL1=0;

}

if(levelflag==LOW) //低电平

{

levelflag=NULL;

CTRL1=1;

}

}

}

void delay(unsigned int i)

{

while( i )

{

i--;

}

}

void ad0808(void) interrupt 0 //中断0响应函数

{

EA=0;

EX0=0;

ad_data=AD; //将AD转换数据送给变量ad_data EA=1;

EX0=1;

}

void main(void)

{

EA=1; //中断总允许

EX0=1; //打开外部中断0

PT0=1;

PX1=1;

TMOD=0x01;

ET0=1; //定时器0初始化TR0=1;

TH0=0xff;

TL0=0xCE; //定时器0初始值

//外部中断1

EX1=1;

IT1=1;

highcount=0;

ad_data=0;

ad_busy=0;

while(1)

{

P2=0xff;

delay(40);

run();

AD=0;

}

}

相关文档
最新文档