文档库

最新最全的文档下载
当前位置:文档库 > 单片机C51习题库

单片机C51习题库

1 C51基础(软件实验)

1、用C51绝对地址访问实现内部RAM 30H和外部RAM 2000H内容交换。

#include

main()

{

unsigned char t;

DBYTE[0X30]=1;

XBYTE[0X2000]=2;

t=DBYTE[0X30];

DBYTE[0X30]=XBYTE[0X2000];

XBYTE[0X2000]=t;

while(1);

}

2、内部RAM 30H起始的16个单元求和,结果高8位放在40H、低8位放在41H中。#define uchar unsigned char

#define uint unsigned int

uchar data a[16] _at_ 0x30;

uchar data res[2] _at_ 0x40;

main()

{

uchar i;

uint sum = 0;

uchar ave = 0;

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

{ a[i]=16; }

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

{ sum += a[i];}

res[0]=sum/256;

res[1]=sum%256;

while(1);

}

3、外部RAM 2000H为起始地址的256个字节清零。

#define uchar unsigned char

#define uint unsigned int

uchar xdata a[256] _at_ 0x2000;

main()

{

uint i;

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

{

a[i]=0;

}

while(1);

}

4、取内部RAM 40H中数的百位、十位、个位分别放在30H、31H、32H中。#define uchar unsigned char

uchar res[3] _at_ 0x30;

uchar num _at_ 0x40;

main()

{

res[0] = num/100;

res[1] = num%100/10;

res[2] = num%10;

while(1);

}

5、标准输入输出函数的使用

#define uchar unsigned char

#define uint unsigned int

#include

#include //包含I/O函数库

void main(void) //主函数

{

int x,y; //定义整型变量x和y

SCON=0x52; //串口初始化

TMOD=0x20;

TH1=0XF3;

TR1=1;

printf("input x,y:\n"); //输出提示信息

scanf("%d%d",&x,&y); //输入x和y的值

printf("\n"); //输出换行

printf("%d+%d=%d",x,y,x+y); //按十进制形式输出

printf("\n"); //输出换行

printf("%xH+%xH=%XH",x,y,x+y); //按十六进制形式输出

while(1);

}

6、编写延时函数0-255毫秒

void delay_nms(uchar x)

{

uchar i;

while(x--)

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

}

2 内部资源应用

1、外部中断按键计数功能的实现,将计数结果输出到P2口二进制显示。#include

main()

{

IE = 0x81;

IT0 = 1; //下降沿触发方式

P2 = 0;

while(1);

}

void int0_isr(void) interrupt 0

{ P2++; }

2、按键控制指示灯状态取反,要求用外部中断设计实现。

单片机C51习题库

#include

sbit led = P3^0;

main()

{

IE = 0x81;

IT0 = 1; //下降沿触发方式

while(1);

}

void int0_isr(void) interrupt 0

{

led = !led;

}

3、用定时器设计实现流水灯功能,按1s时间间隔轮流点亮

typedef unsigned char uchar;

typedef unsigned int uint;

#include

#define LED_PORT P1

bit flag_1s;//1s时间到标志位

main()

{

uchar led_sta;

//定时初始化

TMOD = 0x01;//T0工作在方式1 定时0000 0001

IE = 0x82; //EA ET0

TH0 = 0x3c; //50ms 12Mhz

TL0 = 0xb0;

TR0 = 1;//启动计数

led_sta = 0x01;

LED_PORT = ~led_sta;

while(1)

{

if(flag_1s)

{

flag_1s = 0;

led_sta <<= 1;

if(led_sta == 0)led_sta = 0x01;

LED_PORT = ~led_sta;

}

}

}

//定时器T0中断服务程序

void T0_isr(void) interrupt 1

{

static uchar cnt;

TH0 = 0x3c; //50ms 12Mhz

TL0 = 0xb0;

cnt++;

if(cnt >= 20) //20*50ms = 1s

{

flag_1s = 1;

cnt = 0;

}

}

5、串口实现查询方式收发数据,接收到串口数据后原码回送. #include

typedef unsigned char uchar;

#define SYSCLK 11059200

#define BAUD 9600

void uart_init(void);//函数声明

uchar Rcv; //用于暂存接收的数据全局变量

main(void)

{

uart_init();

while (1)

{

if(RI) //等待接收数据

{

Rcv=SBUF; //读入数据

SBUF=Rcv; //发送数据

while(!TI){;}//等待数据发送完毕

TI=0;

RI=0;

}

}

}

void uart_init(void) //系统初始化11.2592m 9600波特率

{

TMOD=0X20;

TH1=-(SYSCLK/32/12/BAUD);

TL1=TH1;

SCON=0X50; //串口方式

TR1=1;

RI=0;

}

6、串口应用中断方式接收数据,接收到串口数据后原码回送. #include

typedef unsigned char uchar;

void uart_init(void);//函数声明

void SendOneByte(unsigned char c);

uchar Rcv;

bit T_flag;

main(void)

{

uart_init();

while (1)

{

if(T_flag)

{

T_flag=0;

SendOneByte(Rcv);

}

}

}

void uart_init(void) //系统初始化11.2592m 9600波特率

{

TMOD = 0x20;

SCON = 0x50;

TH1 = 0xFA;

TL1 = TH1;

PCON = 0x80; //波特率翻倍

EA = 1;

ES = 1;

TR1 = 1;

}

void SendOneByte(unsigned char c)

{

SBUF = c;

while(!TI);

TI = 0;

}

void UARTInterrupt(void) interrupt 4

{

if(RI)

{

RI = 0;

Rcv = SBUF;

T_flag = 1;//串口发送表示置1

}

If(TI)TI = 0;

}

7、频率输出,要求输出500HZ方波信号,用定时器设计实现。#define SYSCLK 12000000

#include

sbit FBOUT = P1^0;

main()

{

//定时器T0 1ms 中断初始化

TMOD = 0x01;

IE = 0x82;

TH0 = (-(SYSCLK/12/1000))>>8;

TL0 = -(SYSCLK/12/1000);

TR0 = 1;

while(1);

}

void t0_isr(void) interrupt 1

{

TH0 = (-(SYSCLK/12/1000))>>8;

TL0 = -(SYSCLK/12/1000);

FBOUT =!FBOUT;

}

8、频率测量,单片机P3.5引脚输入1000HZ左右频率信号,完成测量并将测量结果保存在整形变量freq中。

3 常用外设

1、单片机P2口接共阳极数码管段选,数码管单管显示0-9,时间间隔1s。

#include

//端口定义

#define OUTSEG P2

//定义7段码常量表

uchar code seg7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

//函数声明

void delay1s(void); //误差0us

//主程序

main()

{

uchar i;

while(1)

{

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

{

OUTSEG = seg7[i];

delay1s();

}

}

}

void delay1s(void) //误差0us

{

unsigned char a,b,c;

for(c=167;c>0;c--)

for(b=171;b>0;b--)

for(a=16;a>0;a--);

_nop_(); //if Keil,require use intrins.h

}

2、数码管单管显示9-0,时间间隔1s。要求用定时器实现

3、共阳极数码管如图连接单片机,用动态扫描设计显示“5678”。

单片机C51习题库

typedef unsigned char uchar;

typedef unsigned int uint;

#include

//端口

#define OUTSEG P0

#define OUTBIT P2

//定义7段码常量表

uchar code seg7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; uchar ledbuf[4];

void delay1ms(void); //误差0us

void displed4(void);

main()

{

ledbuf[0] = 5;

ledbuf[1] = 6;

ledbuf[2] = 7;

ledbuf[3] = 8;

while(1)

{

displed4();

}

}

void displed4(void)

{

uchar i,pos;

pos = 0x01;

OUTBIT = 0; //关所有数码管

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

{

OUTBIT = pos;

OUTSEG = seg7[ledbuf[i]];

delay1ms();

pos <<= 1;

}

OUTBIT = 0; //关所有数码管

}

void delay1ms(void) //误差0us

{

unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=142;b>0;b--)

for(a=2;a>0;a--);

}

4、六位数码管动态显示

5、无源蜂鸣器输出编程,要求输出500HZ频率鸣叫。#define uchar unsigned char

#define uint unsigned int

#define SYSCLK 12000000

#include

sbit beep_con = P3^0;

uint reload;

void tim0_init(void)

{

TMOD = 0X01;

IE = 0X82;

TH0 = reload>>8;

TL0 = reload;

TR0 = 1;

}

void tim0_isr(void) interrupt 1

{

TH0 = reload>>8;

TL0 = reload;

beep_con=!beep_con;

}

void set_feq(uint f)//设置频率

{

reload = -(SYSCLK/12/f/2);

}

void fout_con(bit on_off)//控制频率输出1 on 0 off

{

if(on_off)

{

ET0 = 1;

}

else

{

ET0 = 0;

beep_con =1;

}

}

main()

{

tim0_init();

set_feq(500);

fout_con(1);//关蜂鸣器

while(1);

}

6、用ADC0809通道0采集数字量实时显示在P2口上(二进制显示)。接口电路如图。

单片机C51习题库

#include

#include "inc/delay.h"

//端口定义

#define AD_DBPORT P1

sbit AD_CLK = P3^0;

sbit AD_OE = P3^1;

sbit AD_EOC = P3^2;

sbit AD_ST = P3^3;

//变量定义

void t0_init(void)

{

TMOD = 0X02;

IE = 0X82;

TH0 = 256-100; //100us中断

TL0 =TH0;

TR0 = 1;

}

void t0_isr() interrupt 1

{

AD_CLK = !AD_CLK;//周期200us 频率5k

}

uchar get_ad(void)

{

uchar tmp;

AD_OE = 0;

AD_ST = 1;

AD_ST = 0;

Delay_us(100);

while(AD_EOC==0);

AD_OE = 1;

tmp = AD_DBPORT;

AD_OE = 0;

return tmp;

}

main()

{

t0_init();

while(1)

{

P2 = get_ad();

}

}

7、ADC0809实现8通道巡回采集子程序设计,接口电路如图

单片机C51习题库

#define uchar unsigned char

#define uint unsigned int

//端口定义

#define AD_DBPORT P1

sbit AD_CLK = P3^0;

sbit AD_OE = P3^1;

sbit AD_EOC = P3^2;

sbit AD_ST = P3^3;

sbit AD_ADDA = P3^5;

sbit AD_ADDB = P3^6;

sbit AD_ADDC = P3^7;

//变量定义

uchar ad_res[8];//ad_res[0] -- IN0 .... ad_res[7] -- IN7 void get_ad(void)

{

uchar tmp,i;

AD_OE = 0;

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

{

//地址选择

AD_ADDC = i%8/4;

AD_ADDB = i%4/2;

AD_ADDA = i%2;

AD_ST = 1;

AD_ST = 0;

Delay_us(100);

while(AD_EOC==0);

AD_OE = 1;

tmp = AD_DBPORT;

AD_OE = 0;

ad_res[i] = tmp;

}

}

8、DAC0832输出方波、三角波、阶梯、锯齿波、正弦波参考电路与例程

单片机C51习题库

#define uchar unsigned char

#define uint unsigned int

#define SYSCLK 12000000

#include

#include

//端口定义

#define DA_DBPORT P1

main()

{

while(1)

{

DA_DBPORT=0;//0-255

Delay_ms(10);

DA_DBPORT=0x40;//0-255

Delay_ms(10);

DA_DBPORT=0x80;//0-255

Delay_ms(10);

DA_DBPORT=0xc0;//0-255

Delay_ms(10);

DA_DBPORT=0xff;//0-255

Delay_ms(10);

}

}

9、PWM占空比输出,要求P1.4口输出占空比30%方波信号,输出信号周期100ms。#define uchar unsigned char

#define uint unsigned int

#include

#include "delay.h"

//端口定义

sbit PWMOUT = P1^4;//脉冲输出

//变量定义

uchar t0cnt;

uchar plh_cnt;//高电平脉冲数

void t0_init()//100US定时中断

{

TMOD |= 0x02;

TH0 = 256-100;

TL0 = TH0;

ET0 = 1;

EA = 1;

TR0 = 1;

}

void t0_isr(void) interrupt 1

{

t0cnt++;

if(t0cnt>99) t0cnt=0;

if(t0cnt<=plh_cnt) PWMOUT = 1;

else PWMOUT = 0;

}

main()

{

t0_init();

plh_cnt = 30;

while(1);

}