单片机实训报告
姓名:刘 腾
学号:1201497
班级:电信12304
指导教师:杨雁冰
日期:2013/12/22
一、 实训目的
单片机课程是一门实践性很强的专业技术课程,初学者只有通过大量的编程,实验,调试设计制作等一系列实践环节的训练,才能掌握单片机软件及硬件设计和调试的技巧,才能更灵活的运用单片机指令系统和各种开发调试工具,设计出高效,。可靠的单片机应用系统。
二、 实训器材;
SWK-51A单片机开发实验板;
单片机实训指导书;
Keil Uvision4软件
STC-ISP
三、 程序设计
这周实训,基于STC89C52单片机一共完成了10个单片机程序设计:
1. 点亮一个LED灯
#include <reg52.h>
sbit a=P0^0 ;
void main()
{
a=0;
}
2. LED灯左移
#include <reg52.h>
void delay (int ms);
void main()//主函数
{
while (1)
{
if (P1==0xff)P1=0xfe;
delay(100);
P1<<=1;
P1|=1;
}
}
void delay (int ms)
{
int i,j;
for (i=0;i<ms;i++)
for(j=0;j<120;j++);
}
3. 跑马灯
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define data P1
void delay(uint n);
void main()
{
uchar i;
data=0;
while(1)
{
for(i=0;i<8;i++)
{
data=(i==0)?0xfe:((data<<1)+1);//
delay(500);
}
}
}
void delay(uint n)
{
uchar i;
while(n--)
for(i=0;i<125;i++);
}
4. 蜂鸣器
#include<reg52.h>
sbit P3_6=P2^3;
{
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
EA=1;
ET0=1;
TR0=1;
while(1);
}
Void timer0(void) interrupt 1
{
P3_6=!P3_6;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
5. LED灯左移3右移3闪3(作业)
#include <reg52.h>
#include<intrins.h>
int a,b,c ;
void delay(int i);
void main()
{
P1=0xfe;
for(a=0;a<24;a++)
{
delay(200);
P1=_crol_(P1,1);
}
P1=0x7f;
for(b=0;b<24;b++)
{
delay(200);
P1=_cror_(P1,1);
}
P1=0x00;
for(c=0;c<5;c++)
{
delay(300);
P1=~P1;
delay(300);
}
while(1);
}
void delay(int i)
{
int m,n;
for(m=0;m<i;m++)
for(n=0;n<100;n++);
}
6. LED左移和右移
#include <reg52.h>
#include<intrins.h>
int a,b,c ;
void delay(int i);
void main()
{
P1=0xfe;
for(a=0;a<24;a++)
{
delay(200);
P1=_crol_(P1,1);
}
P1=0x7f;
for(b=0;b<24;b++)
{
delay(200);
P1=_cror_(P1,1);
}
P1=0x00;
for(c=0;c<5;c++)
{
delay(300);
P1=~P1;
delay(300);
}
while(1);
}
void delay(int i)
{
int m,n;
for(m=0;m<i;m++)
for(n=0;n<100;n++);
}
7. 数码管(静态显示6个字母A)
#include <reg52.h>
sbit led_en1=P0^0;
sbit led_en2=P0^1;
sbit led_en3=P0^2 ;
sbit led_en4=P0^3 ;
sbit led_en5=P0^4;
sbit led_en6=P0^5; //123456数码管的选通
sbit hc573_sg_le=P2^6;
sbit hc573_bit_le=P2^7;void main()
{
P0=0xff; //
hc573_bit_le=1;
hc573_bit_le=0;
while (1)
{
P0=0x77;
hc573_sg_le=1;
hc573_sg_le=0;
P0=0xff;
led_en1=0;
led_en2=0;
led_en3=0;
led_en4=0;
led_en5=0;
led_en6=0;
hc573_bit_le=1;
hc573_bit_le=0;
}
}
8. 数码管(动态显示12321)
#include <reg52.h>
sbit hc573_sg_le=P2^6;
sbit hc573_bit_le=P2^7;
unsigned char code diaplay_table[16]=
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x67,0x77,0x7c,
0x39,0x5e,0x79,0x71
} ;
Unsigned char code display_en[7]=
{
0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf
};
void display(unsigned char num,unsigned char i)
{
P0=num;//display_table[num];
hc573_sg_le=1;
hc573_sg_le=0;
P0=display_en[i];
hc573_bit_le=1;
hc573_bit_le=0;
}
void delay_ms(unsigned int t )
{
unsigned int a ,b;
for(a=0;a<t;a++)
for (b=0;b<113;b++);
}
void main ()
{
P0=0xff;
hc573_bit_le=1;
hc573_bit_le=0;
while (1)
{
display (0x06,1);
delay_ms(500);
display(0x5b,2);
delay_ms(500);
display(0x4f,3);
delay_ms(500);
display(0x4f,4);
delay_ms(500);
display(0x5b,5);
delay_ms(500);
display(0x06,6);
delay_ms (500);
}
}
动态效果展示:一次从右向左显示1 2 3 2 1
9. LCD屏幕显示(第一行:DZXX12304第二行:LTLOVEYOU)
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="DZXX12304";
uchar code table1[]="LTLOVEYOU";
sbit lcdrs=P2^0;
sbit lcdrw=P2^1;
sbit lcden=P2^5;
sbit dula=P0^6;
sbit wela=P0^7;
uchar num;
void init();
void write_com(uchar com);
void write_data(uchar dat);
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--) ;
}
void write_com(uchar com)
{
lcdrs=0;
lcdrw=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar dat)
{
lcdrs=1;
lcdrw=0;
P0=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void main()
{
init();
write_com(0x80);
for(num=0;num<11;num++)
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<11;num++)
{
write_data(table1[num]);
delay(5);
}
while(1);
}
四、 实训心得
短短的一周单片机实训结束了, 然而留给自己的是有太多美好的回忆!
记得在刚拿到单片机开发板的时候,我心情是那样的激动,因为觉得自己终于可以好好控制这块属于自己的板子了。
可是当自己打开keil软件的时候,发现自己完全蒙了,不知道怎么产生一个HEX文件,总是这个步骤出了问题,要不就是那个步骤忘记加“ .c”,经过几次的尝试,终于可以熟练的运用keil开发软件了,想想自己当时的心情是那么的充满着自豪感!
在接下来的几天里,借助指导手册的参考,渐渐可以从点亮一个LED灯到让LED灯按照自己的设计,随心所欲点亮和移动;在数码管上显示简单的字符,再到彩屏显示两行字符串,一切都是那么的充满着成就感,自己也感觉在这周收获了很多,学到了很多,从一个生疏的新手到可以懂一点的我。
最后,感谢这周实训帮助我的老师和同学,没有你们的帮助,我这周实训也不能学到如此之多,这种成就感也是无法有的,也通过这周实训,让我对单片机这门课程有能更加清楚的理解,也让我产生了浓厚的兴趣继续对单片机进行更加全面的学习!
2013/12/22
第二篇:单片机实训报告模板
项目一 万年历
班级: 学号: 姓名:
一、任务目的
通过对万年历的设计和制作,应用了单片机的数码管、键盘接口技术,以及定时/计数器、中断等程序设计技术,进一步训练了单片机并行I/O端口的应用能力、循环程序设计、键盘查询程序设计和调试能力,让同学们初步了解了作为单片机的重要输入设备——键盘接口技术和程序设计方法。
二、设计要求
用单片机设计一个在数码管能同时显示年月日时分秒,具体要求:根据提供的单片机,设计出万年历的硬件电路,编写软件,用Proteus进行仿真实验,然后进行实物的软硬件调试,并撰写符合要求的实训报告。
三、系统硬件电路设计
可分为最小系统、数码管显示、按键三个单元电路,要求画出各部分电路图,写出工作原理。
最小系统:
数码管显示:
按键:
四、软件设计
主流程图:
流程图:
软件设计有三部分:计时(区分大小月与平月)、显示、校时(使用按键)。
#include <reg51.h>
unsigned char msec,sec,min,hou,day=20,mon=3,ci;/*定义msec为50ms计数变量,sec为秒变量,min为分变量,hou为时变量,day为天变量,mon为月变量,ci为循环次数 */
int year=2013;/*定义year为年变量,定义起始年为20##年*/
sbit P30=P3^0;/*通过sbit定义可位寻址变量*/
sbit P32=P3^2;
sbit P33=P3^3;
sbit P34=P3^4;
void delay(unsigned char i)/*延时函数,当i=1时,延时255微秒*/
{ unsigned char j,k;
for(k=0;k<i;k++)
for(j=0;j<255;j++);}
//函数名:T0_INT
//函数功能:定时器0中断函数,50ms定时时间到,自动执行该函数,判断是否中断20次
//形式参数:无
//返回值:无
void T0_INT() interrupt 1//定时器0中断类型号为1
{TH0=0x3c; //50ms定时初值
TL0=0xb0;
msec++; //中断次数增1
if(msec==20) //中断次数为20次么?
{msec=0; //是,1s计时到,50ms计数变量清零
sec++; //秒变量加1
if(sec==60) //到60s么?
{sec=0; //是,1分计时到,秒变量清零
min++; //分变量加1
if(min==60) //到60分么?
{ min=0; //是,1小时计时到,分变量清零
hou++; //时变量加1
if(hou==24) //到24时么?
{ hou=0; //是,1天计时到,时变量清零
day++; //天变量加1
if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)//月是为1,3,5,7,8,10,12么?
{if(day==32){day=1;mon++;} } //是,天到32么?是,天变量复位为1,月变量加1
else if( mon==2) //月是为2么?
{if(day==29){day=1;mon++;}} //是,天到29么?是,天变量复位为1,月变量加1
else //月是为4,6,9,11么?
{if(day==31){day=1;mon++;}} //是,天到31么?是,天变量复位为1,月变量加1
if(mon==13) //月到13么?
{ mon=1; //是,1年计时到,月变量复位到1
year++;}}}}}} //年变量加1
void main() //主函数
{unsignedcharled[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//定义数字0~9字型显示码,数码管共阴
TMOD=0x01; //定时器0工作方式1
TR0=1; //启动定时器
TH0=0x3c; //50ms定时初值
TL0=0xb0;
EA=1; //开总中断
ET0=1; //定时器0中断
while(1)
{if(P30==1) //P3.0=1么?(开关是开启的么?)
{ for(ci=1;ci<=10;ci++) //for循环,ci的初值为1,判断ci<=10,若小于等于10循环,ci+1,若大于10跳出循环
{P2=0x00;P0=led[sec%10];delay(2); //选中P2为0x00时控制的数码管,显示秒个位
P2=0x01;P0=led[sec/10];delay(2); //选中P2为0x01时控制的数码管,显示秒十位
P2=0x02;P0=led[min%10];delay(2); //选中P2为0x02时控制的数码管,显示分个位
P2=0x03;P0=led[min/10];delay(2); //选中P2为0x03时控制的数码管,显示分十位
P2=0x04;P0=led[hou%10];delay(2); //选中P2为0x04时控制的数码管,显示时个位
P2=0x05;P0=led[hou/10];delay(2);} //选中P2为0x05时控制的数码管,显示时十位
if(P32==0) //P3.2=0么?按钮按下么?
{delay(55);if(P32==0) {sec++;}if(sec==60) {sec=0;}} //是,延时55*255um;P3.2=0么?是,秒变量加1;秒到60么?是,秒变量清零
if(P33==0) //P3.3=0么?按钮按下么?
{delay(55);if(P33==0) {min++;}if(min==60) {min=0;}} //是,延时55*255um;P3.3=0么?是,分变量加1;分到60么?是,分变量清零
if(P34==0) //P3.4=0么?按钮按下么?
{delay(55);if(P34==0) {hou++;}if(hou==24) {hou=0;}}} //是,延时55*255um;P3.4=0么?是,时变量加1;时到24么?是,时变量清零
else if(P30==0) //P3.0=0么?(开关是闭合的么?)
{for(ci=1;ci<=10;ci++) //for循环,ci的初值为1,判断ci<=10,若小于等于10循环,ci+1,若大于10跳出循环
{P2=0x00;P0=led[day%10];delay(2); //选中P2为0x00时控制的数码管,显示天个位
P2=0x01;P0=led[day/10];delay(2); //选中P2为0x01时控制的数码管,显示天十位
P2=0x02;P0=led[mon%10];delay(2); //选中P2为0x02时控制的数码管,显示月个位
P2=0x03;P0=led[mon/10];delay(2); //选中P2为0x03时控制的数码管,显示月十位
P2=0x04;P0=led[year%10];delay(2); //选中P2为0x04时控制的数码管,显示年个位
P2=0x05;P0=led[year/10%10];delay(2); //选中P2为0x05时控制的数码管,显示年十位
P2=0x06;P0=led[year/100%10];delay(2); //选中P2为0x06时控制的数码管,显示年百位
P2=0x07;P0=led[year/1000];delay(2);} //选中P2为0x07时控制的数码管,显示年千位
if(P32==0) //P3.2=0么?按钮按下么?
{delay(50);if(P32==0) {day++;}if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12) //是,延时50*255um;P3.2=0么?是,天变量加1;月是为1,3,5,7,8,10,12么?
{if(day==32){day=1;} } //是,天到32么?是,天变量复位为1
else if( mon==2) //月是为2么?
{if(day==29){day=1;}} //是,天到29么?是,天变量复位为1
else //月是为4,6,9,11么?
{if(day==31){day=1;}}} //是,天到31么?是,天变量复位为1
if(P33==0) //P3.3=0么?按钮按下么?
{delay(50);if(P33==0) {mon++;}if(mon==13) {mon=1;}} //是,延时50*255um;P3.3=0么?是,月变量加1;月到13么?是,月变量复位为1
if(P34==0) //P3.4=0么?按钮按下么?
{delay(50);if(P34==0) {year++;}}} //是,延时50*255um;P3.3=0么?是,年变量加1;
else {;}}}
五、系统调试
画proteus图,了解单片机最小系统,选用的元件有AT89C51,共阴的蓝色的8位数码管(7SEG-MPX8-CC-BLUE),三八译码器(74HC138),按钮(BUTTON),普通电容(CAP),极性电容(CAP-ELEC),晶体管(CRYSTAL),10K电阻(RES),排阻(RESPACK-8),单刀单匝开关(SWITCH),将电路连接完整。
编写程序。
编译程序并导入画好的proteus中,查看情况,调试。
在调试过程中,我们先编写的是时分秒的数字钟的显示,在最开始的时候数码管全部显示8,经后来查程序发现程序内少了计时器开启的命令,所以数码管没有时间跳动。在时分秒显示后,我们开始将年月日加进去,在P3.0口接入单刀单匝开关,当开关断开时显示的是时分秒,开关闭合时是显示年月日。然后调试时发现开关没用,后来问同学知道,P3.0是不能直接用的,所以要用sbit来定义可位寻址变量的,改正后可以变换了。最后编写校时的程序,在调试校时这部分时当我们按下按键的时候会跳掉好几个数,后来经老师解答知道那是抖动,所以要消抖,消抖后虽然好了点,但是还是会有数字跳动的,后来在课堂上知道了是所有的程序运作是要时间的,之前占用的时间太多会让后面的校时有错的,所以在显示的部分用了for的循环语句。最后是区分大小月和平月,这程序是在放在计时和校时的部分的。
六、心得体会
经过这次练习,我对单片机的应用有了更深的认识了,而且还记住了以前总是记不住的单片机的最小系统。从最开始的觉得C语言编万年历太难了,到后来觉得这个万年历也不是很难的。在编程序的时候必须要认真仔细,防止不必要的错误。