单片机原理实验报告
班级: 姓名: 分数:
实验一
实验目的:
实验内容:
电路连接:(若有参数,需要写计算过程;老师说第一次报告还需要画出震荡和复位电路哈)
程序代码:
实验感想:(实验过程中遇到的问题)
第二篇:单片机原理实验报告
单片机原理实验报告
实验一:仿真软件的使用以及跑马灯的设计
实验目的
1. 掌握仿真软件的使用方法
2. 掌握 MCS-51 单片机的 P0、P1、P2 口的使用方法
3. 掌握实现发光二极管的移动、闪烁程序的编写方法
实验仪器
1、计算机一台。
2、LJD-SY-5200 实验系统一套。
3、上位机端 Keil C51 编译系统。
实验内容及要求
1、掌握单片机仿真器的程序输入、调试和运行等方法。
2、P2 口作为输入口,接 8 个按键。所有按键的一端接通过上拉电阻接至+5V电源,另一端和电源地 GND 相连接。在没有按键被按下是 P2 的输入全为高电平,当有按键被按下时对应的 P2 的相应引脚被拉低,该引脚输入变成低电平。 P0、P1作输出,接 16 个发光二极管,以P2口的值为点亮发光二极管的个数进行循环点亮
实验线路:
实验内容:
实验程序(汇编):
ORG 0000H ;初始化地址
LJMP MAIN ;进入程序
MAIN: MOV A,P2 ;将P2口的状态送入A中
MOV R0,#8 ;将数值8送入R0
MOV R1,#8 ;将数值8 送入R1
LOOP3: MOV P0,A ;跑马灯循环开始处,并将A的数值送入P0口
LCALL DELAY ;亮灯延时
RL A ;将A中数值左移一位,即点亮下一个灯
DJNZ R0,LOOP3 ;若A中数值不等于8(即没完成一次循环)继续循环
MOV P0,#0FFH ;P0循环完成,将其全部熄灭
MOV A,#0FEH ;将使第一个灯点亮的值送入A中
LOOP4: MOV P1,A ;将A的数值送入P1口,开始循环第二排的灯
LCALL DELAY ;亮灯延时
RL A ;将A中数值左移一位,即点亮下一个灯
DJNZ R1,LOOP4 ;若A中数值不等于8(即没完成一次循环)继续循环
MOV P1,#0FFH ;P1循环完成,将其全部熄灭
LJMP MAIN ;进入下一个总循环
DELAY: MOV R5,#200 ;延时程序,借用R5,R4寄存器产生延时
LOOP2: MOV R4,#200
LOOP1: NOP
DJNZ R4,LOOP1
DJNZ R5,LOOP2
RET
END
实验流程图:
实验二 定时器及计数器的应用
实验目的:
一、熟悉 8051 的 T0 作为定时器的设置及使用方法
二、掌握 T0 作为计数器的软件设计方法。
三、掌握单脉冲发生电路的硬件线路连接方式。
实验内容及要求:
一、在液晶屏上显示定时、计数结果
1、利用定时器 T0 进行计时,并把计时结果通过液晶屏显示出来。以每秒为单位显示。
2、把 T0 作为计数器对 T0 引脚的输入脉冲进行计数,并通过液晶显示屏显示T0 计数结果。
3、我们给出液晶屏显示程序,同学自己用编写T0定时器程序(中断部分程序)及由 T0 引脚输入的外部脉冲进行计数的计数器程序(汇编或C语言均可)。将定时或计数结果付给液晶屏显示程序中的count即可显示。
实验线路:
二、利用定时器 T0 控制八个发光二极管
1、利用定时器 T0 进行计时,在程序运行2s后首先使得发光二极管顺序循环点亮三次,随后使用定时器T0使得发光二极管奇数位和偶数位循环点亮三次,并循环显示。以500ms为单位显示。
2、把 T0 作为计数器对 T0 引脚的输入脉冲进行计数,使用P2 口中的一位作为输入口,接 1 个按键。所有按键的一端接通过上拉电阻接至+5V电源,另一端和电源地 GND 相连接。在没有按键被按下时 P2 的输入为高电平,当有按键被按下时对应的 P2 的相应引脚被拉低,该引脚输入变成低电平。当按键次数达到3的整数倍时点亮P1口的一个发光二极管。
实验步骤:
一、进行实验线路连接。将串口线一端与计算机串口相连另一端与
LJD-SY-5200 实验系统上的串口相连接。
二、将仿真监控芯片正确(注意方向,谨防插反)地插到实验系统的 CPU 插座上。
三、取下JP5、JP6,其他的跳线连接方式采用默认的即可。
四、编写源程序添加进去,进行调试。
实验说明:
一、CH451 芯片的时钟和数据线用的分别是单片机的 T0,T1 引脚,所以请不要再尝试使用数码管去显示 T0 计数的结果。
二、T1 的实验方法同 T0,只是单脉冲发生电路的左边的插孔需要和 T1 而不是T0 连接起来。
三、完成本次实验后请取下两根直连导线。
实验内容及要求:
一、在液晶屏上显示定时、计数结果
1、利用定时器 T0 进行计时,并把计时结果通过液晶屏显示出来。以每秒为单位显示。
实验程序1.1
/******************************************************************************
* * T0定时器的应用中液晶屏显示部分(count为要显示的内容)
******************************************************************************/
#include
#include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
#define W_C_GLCD XBYTE[0xcfff]
#define W_D_GLCD XBYTE[0xdfff]
#define R_B_GLCD XBYTE[0xefff]
#define R_D_GLCD XBYTE[0xffff]
void command_GLCD(uchar ord);
void initial_GLCD(void);
void write_GLCD(uchar dat);
void chkbusy_GLCD();
void delay(void);
uchar pdata disp_num[10] = "0123456789";
uchar pdata disp_hz[12] = "T0计时:XXXXS";
sbit ACC7 = ACC^7;
sbit bflag = ACC^7;
uchar flag_count;
uint count;
/********************************************************************
函 数 名:initial_GLCD()
功 能:对12232液晶显示屏进行初始化
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void initial_GLCD()
{
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x06); /*显示器控制:游标不显示*/
delay();
command_GLCD(0x01); /*清屏幕*/
delay();
command_GLCD(0x0c); /*进入模式设定*/
delay();
}
/********************************************************************
函 数 名:conmmand_GLCD(uchar ord)
功 能:写命令到12232
说 明:
调 用:
入口参数:uchar ord
出口参数:
***********************************************************************/
void command_GLCD(uchar ord)
{
chkbusy_GLCD();
W_C_GLCD=ord;
}
/********************************************************************
函 数 名:write_GLCD(uchar dat)
功 能:写数据到12232
说 明:
调 用:
入口参数:uchar dat
出口参数:
***********************************************************************/
void write_GLCD(uchar dat)
{
chkbusy_GLCD();
W_D_GLCD=dat;
}
void chkbusy_GLCD()
{
do{ACC=R_B_GLCD;}
while(bflag==1);
}
/********************************************************************
函 数 名:delay()
功 能:延时25us
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void delay()
{
uchar i;
for(i=0;i<25;i++)
{;}
}
/********************************************************************
函 数 名:delay1()
功 能:延时mus
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void delay1(uint m)
{
while(m--);
}
main()
{
uchar i,j;
flag_count=0;
count=0;
j=0;
TMOD=0x51; /*设置T0的工作方式为16位定时器*/
TL0=(65536-10000)%256; /*给T0赋值,使其定时时间为10ms*/
TH0=(65536-10000)/256;
TR0=1; /*T0开始工作*/
initial_GLCD(); /*清屏*/
while(1)
{
if(TF0==1) /*若溢出,说明定时已经到了10ms*/
{
if(j<100) /*若总定时还未满1s*/
{
TF0=0; /*重置TF0*/
TH0=(65536-10000)/256; /*重置T0*/
TL0=(65536-10000)%256;
j++; /*继续累加j,直到1s*/
}
Else /*总定时已经达到1s*/
{
j=0; /*重置j*/
count++; /*显示当前已定时时间*/
}
}
command_GLCD(0x80);
for(i=0;i<7;i++)
{
write_GLCD(disp_hz[i]);
}
write_GLCD(disp_num[count/1000]); /*显示定时结果的千位*/
write_GLCD(disp_num[count%1000/100]); /*显示定时结果的百位*/
write_GLCD(disp_num[count%1000%100/10]); /*显示定时结果的十位*/
write_GLCD(disp_num[count%1000%100%10]); /*显示定时结果的个位*/
write_GLCD(disp_hz[11]);
delay1(1000);
}
}
实验流程图:
2、把 T0 作为计数器对 T0 引脚的输入脉冲进行计数,并通过液晶显示屏显示T0 计数结果。
1.2
/******************************************************************************
* T0计数器的应用中液晶屏显示部分(count为要显示的内容)
******************************************************************************/
#include
#include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
#define W_C_GLCD XBYTE[0xcfff]
#define W_D_GLCD XBYTE[0xdfff]
#define R_B_GLCD XBYTE[0xefff]
#define R_D_GLCD XBYTE[0xffff]
void command_GLCD(uchar ord);
void initial_GLCD(void);
void write_GLCD(uchar dat);
void chkbusy_GLCD();
void delay(void);
uchar pdata disp_num[10]="0123456789";
uchar pdata disp_hz[11] ="T0计数程序:";
uchar count;
sbit ACC7 = ACC^7;
sbit bflag = ACC^7;
/********************************************************************
函 数 名:initial_GLCD()
功 能:对12232液晶显示屏进行初始化
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void initial_GLCD()
{
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x30); /*功能设定*/
delay();
command_GLCD(0x06); /*显示器控制:游标不显示*/
delay();
command_GLCD(0x01); /*清屏幕*/
delay();
command_GLCD(0x0c); /*进入模式设定*/
delay();
}
/********************************************************************
函 数 名:conmmand_GLCD(uchar ord)
功 能:写命令到12232
说 明:
调 用:
入口参数:uchar ord
出口参数:
***********************************************************************/
void command_GLCD(uchar ord)
{
chkbusy_GLCD();
W_C_GLCD=ord;
}
/********************************************************************
函 数 名:write_GLCD(uchar dat)
功 能:写数据到12232
说 明:
调 用:
入口参数:uchar dat
出口参数:
***********************************************************************/
void write_GLCD(uchar dat)
{
chkbusy_GLCD();
W_D_GLCD=dat;
}
void chkbusy_GLCD()
{
do{ACC=R_B_GLCD;}
while(bflag==1);
}
/********************************************************************
函 数 名:delay()
功 能:延时25us
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void delay()
{
uchar i;
for(i=0;i<25;i++)
{;}
}
/********************************************************************
函 数 名:delay1()
功 能:延时mus
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void delay1(uint m)
{
while(m--);
}
void isr_t0(void)interrupt 1
{
TH0=0xFF; /*给T0赋值,有一次外部脉冲输入则立即产生中断*/
TL0=0xFF;
count++; /*T0值已为FFH,若有外部脉冲输入,则产生中断使count++*/
}
main()
{
uchar i;
TMOD=0x05; /*设置T0的工作方式为16位计数器*/
TH0=0xFF; /*给T0赋值,有一次外部脉冲输入则立即产生中断*/
TL0=0xFF;
EA=1; /*将总的中断允许开关打开*/
ET0=1; /* 将T0的中断允许开关打开*/
TR0=1; /*开始计数 */
initial_GLCD(); /*清屏*/
while(1)
{
command_GLCD(0x80);
for(i=0;i<11;i++)
{
write_GLCD(disp_hz[i]);
}
write_GLCD(disp_num[count/100]); /*显示计数结果的百位*/
write_GLCD(disp_num[count%100/10]); /*显示计数结果的十位*/
write_GLCD(disp_num[count%100%10]); /*显示计数结果的个位*/
delay1(1000);
}
}
实验流程图:
二、利用定时器 T0 控制八个发光二极管
1、利用定时器 T0 进行计时,在程序运行2s后首先使得发光二极管顺序循环点亮三次,随后使用定时器T0使得发光二极管奇数位和偶数位循环点亮三次,并循环显示。以100ms为单位显示。
2.1
#include
#include
int num;
char aa=0xfe; //11111110b
void timer0_init()
{
TMOD=0X01; /* 设置T0的工作方式为16位定时器*/
TH0=(65536-50000)/256; /* 晶振为12MHz*/
TL0=(65536-50000)%256; /*定时为50ms */
EA=1; /*开全局中断 */
ET0=1; /*开定时器0中断 */
TR0=1; /*启动定时器0 */
}
void Timer0() interrupt 1
{
num++;
if(num==341)
{
num=0;
}
TH0=(65536-500000)/256; /*晶振为12MHz */
TL0=(65536-500000)%256; /*定时为50ms */
switch(num) /*亮灯程序 ,间隔50ms*10=0.5s*/
{
case 40:
P2=aa; //11111110
aa=_crol_(aa,1); //循环右移
break;
case 50:
P2=aa; //11111101
aa=_crol_(aa,1);
break;
case 60:
P2=aa; //11111011
aa=_crol_(aa,1);
break;
case 70:
P2=aa; //11110111
aa=_crol_(aa,1);
break;
case 80: //11101111
P2=aa;
aa=_crol_(aa,1);
break;
case 90:
P2=aa; //11011111
aa=_crol_(aa,1);
break;
case 100:
P2=aa; //10111111
aa=_crol_(aa,1);
break;
case 110:
P2=aa; //01111111
aa=_crol_(aa,1);
break;
case 120:
P2=aa; //11111110
aa=_crol_(aa,1);
break;
case 130:
P2=aa; //11111101
aa=_crol_(aa,1);
break;
case 140:
P2=aa; //11111011
aa=_crol_(aa,1);
break;
case 150:
P2=aa; //11110111
aa=_crol_(aa,1);
break;
case 160:
P2=aa; //11101111
aa=_crol_(aa,1);
break;
case 170:
P2=aa; //11011111
aa=_crol_(aa,1);
break;
case 180:
P2=aa; //10111111
aa=_crol_(aa,1);
break;
case 190:
P2=aa; //01111111
aa=_crol_(aa,1);
break;
case 200:
P2=aa; //11111110
aa=_crol_(aa,1);
break;
case 210:
P2=aa;
aa=_crol_(aa,1);
break;
case 220:
P2=aa;
aa=_crol_(aa,1);
break;
case 230:
P2=aa;
aa=_crol_(aa,1);
break;
case 240:
P2=aa;
aa=_crol_(aa,1);
break;
case 250:
P2=aa;
aa=_crol_(aa,1);
break;
case 260:
P2=aa;
aa=_crol_(aa,1);
break;
case 270:
P2=aa; //01111111
aa=_crol_(aa,1); //三次完毕
break;
case 280:
P2=0x55; //01010101
break;
case 290:
P2=0xaa; //10101010
break;
case 300:
P2=0x55;
break;
case 310:
P2=0xaa;
break;
case 320:
P2=0x55;
break;
case 330:
P2=0xaa;
break;
case 340:
num=39; //两秒后继续开始
break;
}
}
void main()
{
timer0_init();
while(1);
}
2、把 T0 作为计数器对 T0 引脚的输入脉冲进行计数,使用P2 口中的一位作为输入口,接 1 个按键。所有按键的一端接通过上拉电阻接至+5V电源,另一端和电源地 GND 相连接。在没有按键被按下时 P2 的输入为高电平,当有按键被按下时对应的 P2 的相应引脚被拉低,该引脚输入变成低电平。当按键次数达到3的整数倍时点亮P1口的一个发光二极管。
2.2
#include
#include
#include
sbit P0_3= P0^3;
typedef unsigned char uchar;
typedef unsigned int uint;
unsigned int count=0;
/********************************************************************
函 数 名:delay1()
功 能:延时mus
说 明:
调 用:
入口参数:
出口参数:
***********************************************************************/
void delay1(uint m)
{
while(m--);
}
void main()
{ while (1){
TMOD=0x05; /*设置T0工作模式为16位计数器*/
TH0=0xFF; /*T0初值设置*/
TL0=0xFF;
ET0=1; /*开启T0中断*/
EA=1; /*开启总中断*/
TR0=1; /*开启T0*/
if( count==5 )
{
P0_3=0;
count=0;
while (count ==0) {delay1(1000);};
};
else {P0_3=1;};
}
}
void time0() interrupt 1
{
count++;
TH0=0xff; /*T0初值设置*/
TL0=0xff;
}
实验流程图:
实验三 模拟/数字(A/D,TLC549)实验
实验目的
一、了解 8 位串行输出 A/D 转换器 TLC549 的工作原理。
二、掌握 TLC549 的硬件线路连接方式。
三、掌握 A/D 转换器 TLC549 的编程方法。
实验内容及要求
一、仔细阅读 TLC549 的数据手册。
二、仔细阅读 CH451 的应用手册。
三、编写程序把 A/D 转换器的转换结果通过数码管显示出来。
实验线路:
实验步骤:
一、进行实验线路连接。将串口线一端与计算机串口相连另一端与
LJD-SY-5200 实验系统上的串口相连接。
二、将仿真监控芯片正确(注意方向,谨防插反)地插到实验系统的 CPU 插座上。
三、在跳线器 JP5、JP6 上插上跳线冒。
四、取下跳线器 JP4、JP7、JP8 上的跳线冒。
五、编译、下载程序至仿真监控芯片,
六、调节模拟转换参考电压(即电位器 W2),观察数码管上数值的变化情况。
实验程序:
#include
#include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
sbit ch451_din = P3^5;
sbit ch451_clk = P3^4;
sbit ch451_load = P1^2;
sbit P1_4 = P1^4;
sbit P1_3 = P1^3;
sbit tlc549_clk = P1^1;
sbit tlc549_d0 = P1^0;
sbit tlc549_cs = P1^5;
int i=0;
/*须主程序定义的参数*/
#define CH451_DIG0 0x0800 /*数码管位0显示*/
#define CH451_DIG1 0x0900 /*数码管位1显示*/
#define CH451_DIG2 0x0a00 /*数码管位2显示*/
#define CH451_DIG3 0x0b00 /*数码管位3显示*/
#define CH451_DIG4 0x0c00 /*数码管位4显示*/
#define CH451_DIG5 0x0d00 /*数码管位5显示*/
#define CH451_DIG6 0x0e00 /*数码管位6显示*/
#define CH451_DIG7 0x0f00 /*数码管位7显示*/
void delay(uint us)
{
while(us--);
}
/* */
/********************************************************************
函 数 名:ch451_init()
功 能:对ch451芯片进行初始化
说 明:
调 用:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void ch451_init(void)
{
ch451_din = 0; /*先低后高,选择4线输入*/
ch451_din = 1;
ch451_load = 1;
ch451_clk = 1;
_nop_();
}
/********************************************************************
函 数 名:ch451_write()
功 能:把12位的指令或数据写入ch451
说 明:12位数据或指令的写入顺序是低位
调 用:
入口参数:command
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void ch451_write(unsigned int command)
{
unsigned char i;
ch451_load=0; /*命令开始*/
for(i=0;i<12;i++)
{ /*送入12位数据,低位在前*/
ch451_din=command&1;
ch451_clk=0;
command>>=1;
ch451_clk=1; /*上升沿有效*/
}
ch451_load=1; /*加载数据*/
}
/********************************************************************
函 数 名:disp_ad()
功 能:把A/D转换结果通过数码管进行显示
说 明:
调 用:
入口参数:command
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void disp_ad(uint adc_result)
{
uchar A;
uchar B;
uchar C;
uchar D;
A = adc_result/1000;
B = adc_result%1000/100;
C = adc_result%1000%100/10;
D = adc_result%1000%100%10;
ch451_write(CH451_DIG4|A);
ch451_write(CH451_DIG5|B);
ch451_write(CH451_DIG6|C);
ch451_write(CH451_DIG7|D);
delay(10000);
delay(10000);
}
/********************************************************************
函 数 名:main()
功 能:主程序
设 计:蓝海微芯
***********************************************************************/
main()
{
ch451_init();
ch451_write(0x401);
ch451_write(0x580); /*以译码方式进行显示*/
P1_4=1;
P1_4=0;
P1_3=1;
while(1)
{
float temp=0; /*temp即电位器W2的值*/
tlc549_cs=1; /*CS开关,读取一次电位器的值*/
tlc549_cs=0;
for(i=0;i<8;i++) /*转换八位二进制数*/
{
tlc549_clk=0; /*CLK=0*/
temp*=2; /*temp左移一位*/
if(tlc549_d0) temp++; /*若d0=1则在最低位补1;若d0=0 则无需改变*/
tlc549_clk=1; /*回复CLK*/
}
delay(1000); /*产生延时*/
disp_ad(temp); /*显示结果*/
}
}
实验流程图:
实验心得体会及意见与建议:
通过本学期对单片机原理及可编程控制器的学习,我掌握了单片机及PLC的基本原理及使用方法。其两种控制方法都可以广泛地运用在各个控制领域,但也有些不同之处。
单片机是面向工业的微处理器,它是将CPU、RAM、ROM、定时计数器、I/O接口电路集成在一块芯片上,是一种单片计算机。因为体积小,可以植入任何仪器仪表当中或设备中,被广泛作为嵌入式控制器使用。一般使用汇编语言或高级语言编程。
可编程控制器是作为工业设备的通用控制器,代替原来的继电器-接触器的传统的硬件连接控制方式。它采用计算机软件的软连接技术来替代继电器-接触器的硬件连接,为了工程师编程方便一般采用图形编程方式,即使用梯形图作为编程语言。
掌握了这两种原理,将会对今后处理控制问题有非常大的帮助。
我觉得这门课的实践环节还是少了一些,安排给我们的实验时间挺紧张的。因为时间太短还有手生,基本来到实验室没做出什么就快下课了。我的建议是,在实验之前先给一些其他的实验题目并附上程序让我们大概了解流程和内部机理。这样可以让我们在相对熟悉这块内容的条件下更快地完成实验。