资源描述
微处理器与接口课程设计
设计题目:
可编程作息时间控制器
学 院:
年 级:
专 业:
姓 名:
学 号:
指导教师:
张明波 王积翔
2015 年 12 月 15 日
电子技术课程设计
目录
1.1 前言 2
1.2设计内容及意义 1
2.原理及工作过程说明 4
3.1系统电路图 6
3.2详细设计 7
3.31602LCD液晶显示器 7
4,心得与问题 8
5,具体程序 10
参考文献 32
1.1 前言
本课程既是一门专业基础课,又是一门实践性很强的课程,对培养学生解决工程问题的能力和其他后续课程的教学都具有重要意义。课程目标是通过理论和实验学习,使学生掌握单片机的工作原理、基本接口技术和使用单片机构成应用系统的基本方法、设计原理。为本课程实践环节打下基础,为传感器与检测技术、PLC,机电传动与控制、机电一体化系统设计等课程创造条件,为学生从事机电一体化专业技术工作打下基础。 本课程的教学,要求学生先行学习C语言程序设计、电子技术基础等,同时掌握程序编制与接口电路设计的基本知识,着力培养和提高学生运用各项基本理论和方法解决实际问题的分析能力和动手能力,增强学生工程素质和创新能力。
1.2 设计内容及意义
实验名称: 可编程作息时间控制器
实验要求:本项目利用单片机定时计数器及LCD接口实现实时时钟显示,并具有可调整的上下课打铃,灯光控制等功能的作息时间控制器。
实验涉及内容:定时器实验,LCD显示实验,8279键盘显示接口实验
具体原理说明:
1·定时器部分:定时器/计数器的工作原理
计数器输入的计数脉冲源
系统的时钟振荡器输出脉冲经12分频后产生;
T0或T1引脚输入的外部脉冲源。
计数过程
每来一个脉冲计数器加1,当加到计数器为全1(即FFFFH)时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时器/计数器中断允许时)。如果定时器/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
定时应用
用作定时器:此时设置为定时器模式,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t 。
计数运用
用作计数器:此时设置为计数器模式,外部事件计数脉冲由T0或T1引脚输入到计数器。每来一个外部脉冲,计数器加1。但单片机对外部脉冲有基本要求:脉冲的高低电平持续时间都必须大于1个机器周期。
2.LCD显示;液晶显示器(LCD)是一种功耗极低的显示器件,它广泛应用于便携式电子产品中,它不仅省电,而且能够显示大量的信息,如文字、曲线、图形等,其显示界面较之数码管有了质的提高。近年来液晶显示技术发展很快,LCD显示器已经成为仅次于显象管的第二大显示产业。LCD显示器由于类型、用途不同,其性能、结构不可能完全相同,但其基本形态和结构却是大同小异,通常可将LCD为笔段型、字符型和点阵图形型
3.8279键盘显示接口:INTEL 8279是一种可编程键盘、显示器接口芯片,它含有键盘输入和显示器输出两种功能。键盘输入时,它提供自动扫描,能与按键或传感器组成的矩阵相连,接受输入信息,它能自动消除开关抖动并能对多键同时按下提供保护。显示输出时,它有一个16*8位显示RAM,其内容通过自动扫描,可由8或16位LED数码管显示。
2.原理及工作过程说明
制作一个可编程作息时间控制器闹钟,当4路闹钟中的任一路到时,均会点亮灯、打铃。如有需求,可对程序进行调整,增加闹钟的路数及到时后的处理方式。
定时闹钟的基本功能如下。
(1)显示时钟时间,格式为“时时:分分”,并可重新设置。
(2)显示闹铃时间,格式为“时时:分分”,且显示闪烁以便与时钟时间相区分。闹铃时间可重新设置。
(3)程序执行后工作指示灯LED闪烁,表示时钟工作为时钟显示模式.LCD显示的初始时间为“23:58”。按下K2,闪烁显示的“00:00”为闹铃的时间,单击K3又返回时钟显示模式。时钟从“23:58”开始计时,定时时间“00:00”到时,继电器开关接通,控制电器的开启,且可发出声响(可控)。
时钟与闹铃时问的设置可通过4个功能按键Kl~K4实现,具体说明如下。
(1)时钟时间的设置:首先单击Kl进入时钟设置模式。此时每单击一下Kl,则小时增l,单击一下K2,则分钟增1,再单击K3则设置完成,返回时钟显示模式。此时小时和分钟均已发生变化。
(2)闹铃的时间设置:首先单击,K3进入闹铃的设置模式。此时每单击一下Kl,则小时增1,单击一下K2,则分钟增l,最后单击.K3则设置完成,返回闹铃显示模式。此时闹铃的小时和分钟均已发生变化。
(3) K4的功能:闹钟更换。
(4) K2单独的功能:显示闹铃时间。
3.1系统电路图实际图
3.2详细设计
程序部分主要采用了程序结构的模块化设计,避免了一些函数的不必要的重复书写,使程序变得单间易懂。程序在执行时,主程序要须通过调用子函数就可完成相应的功能 。主程序流程图如下
闹铃2时间到?
定时计数器
时间显示
日期显示
闹铃4时间到?
闹铃3时间到?
闹铃1时间到?
3.3 1602LCD液晶显示器
4 问题及心得:
问题:由于准备的不够充分对于灯光的控制并没有完美实现。
心得:通过自己的不懈努力,我终于完成了设计的任务要求。功能上基本达标:时钟的显示,日期显示,调时功能、校时功能、上课下课功能。。在本次设计的过程中,我发现很多的问题,虽然以前没有做过这样的设计但通过这次设计我学会了很多东西,单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,比如写一个程序看其功能很少认为编写程序简单,但到编程的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。
从这次的课程设计中,我们真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,,程序只有在经常的练习的过程中才能提高,我想这就是我在这次课程设计中的最大收获。
5具体程序图:#include <REG51.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
#define CON8279 0xCFE9
#define DATA8279 0xCFE8
#define s_site_x 6
#define s_site_y 0 //y为所在列
#define m_site_x 3
#define m_site_y 0 //y为所在列
#define h_site_x 0
#define h_site_y 0 //y为所在列
static uchar hour,min,scond; //计时时间
static uchar s_hour,s_min,s_scond; //上课时间设置
static uchar s_hour2,s_min2,s_scond2; //下课时间设置
static uchar set_ok; //设置标志位
static uchar set_ok2;
uchar count = 0; //用于记录定时器进入中断次数,以实现长时间定时
uchar code keyval[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x10,0x11,0x12,0x13,0x18,0x19,0x1a,0x1b};
uchar code SEG[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
uchar key;
sbit BUSY = P3^4;
sbit STOBE = P3^5;
void init();
void scan_tim();
void delay(uint tem);
void KbDisInit();
uchar ReadKey();
void Display(uchar y);
void time0_init();
void send(uint tem);
void lcd_init();
void lcd_disp_ascii(uint x,uint y,uchar dat);
void disp_time(uint x,uint y,uchar s);
void init() //初始化
{
set_ok = 0; //允许设定时间
set_ok2 = 0 ;
hour = 12; //设定时钟初值
min = 0;
scond = 0;
s_hour =12; //设定闹钟初值
s_min = 0;
s_scond = 0;
s_hour2 =12; //设定闹钟初值
s_min2 = 0;
s_scond2 = 0;
lcd_init();
KbDisInit();
disp_time(s_site_x,s_site_y,scond);
disp_time(m_site_x,m_site_y,min);
disp_time(h_site_x,h_site_y,hour);
disp_time(s_site_x+8,s_site_y+17,scond);
disp_time(m_site_x+8,m_site_y+17,min);
disp_time(h_site_x+8,h_site_y+17,hour);
disp_time(s_site_x+8,s_site_y+25,scond);
disp_time(m_site_x+8,m_site_y+25,min);
disp_time(h_site_x+8,h_site_y+25,hour);
lcd_disp_ascii(2,0,58);
lcd_disp_ascii(5,0,58);
time0_init();
}
uchar ReadKey()
{
if(XBYTE[0xCFE9]&0x07)
{
XBYTE[0xCFE9]=0x40;
key=XBYTE[0xCFE8];
}
return 0;
}
void Display(uchar y)
{
XBYTE[0xCFE9]=0x80;
XBYTE[0xCFE8]=SEG[y];
}
void lcd_disp_ascii(uint x,uint y,uchar dat) //
{
send(0xf1);
send(x);
send(y);
send(dat);
}
void lcd_disp_hanzhi(uint x,uint y,uchar dat1,uchar dat2) //
{
send(0xf0);
send(x);
send(y);
send(dat1);
send(dat2);
}
void disp_time(uint x,uint y,uchar s) //X为行 Y为列 s要显示的时间(s,m,h对应的x,y要区分)
{
uchar i,j;
i = s/10 + 48;
j = s%10 + 48;
lcd_disp_ascii(x+1,y,j);
lcd_disp_ascii(x,y,i);
}
void nokey()
{
}
void k0()
{
s_scond += 5 ; //秒加1
if(s_scond == 60)
{s_scond = 0;}
disp_time( s_site_x+8 ,s_site_y+17,s_scond);
delay(10);
delay(10);
}
void k1()
{
s_min += 5; //分加1
if (s_min == 60)
{s_min = 0;}
disp_time( m_site_x+8 ,m_site_y+17,s_min);
}
void k2()
{
s_hour++; //时加1
if (s_hour == 12)
{s_hour = 0;}
disp_time( h_site_x+8 ,h_site_y+17,s_hour);
}
void k3()
{
s_scond2 += 5 ; //秒加1
if(s_scond2 == 60)
{s_scond2 = 0;}
disp_time( s_site_x+8 ,s_site_y+25,s_scond2);
}
void k4()
{
s_min2 += 5; //分加1
if (s_min2 == 60)
{s_min2 = 0;}
disp_time( m_site_x+8 ,m_site_y+25,s_min2);
}
void k5()
{
s_hour2++; //时加1
if (s_hour2 == 12)
{s_hour2 = 0;}
disp_time( h_site_x+8 ,h_site_y+25,s_hour2);
}
void k6()
{
//确定
set_ok = 1 ;
set_ok2 = 1 ;
}
void k7()
{
//取消
set_ok = 0 ;
set_ok2 = 0 ;
}
//code void (code * keyproctab[])() = {nokey,k0,k1,k2,k3,k4,k5,k6,k7 }; //读取键值并执行对应函数
void send(uint tem)
{
while(BUSY);
P1 = tem;
STOBE = 1;
while(!BUSY);
STOBE = 0;
}
void key_work()
{
if(key == 0){ k0();}
if(key == 1){ k1();}
if(key == 2){ k2();}
if(key == 3){ k3();}
if(key == 4){ k4();}
if(key == 5){ k5();}
if(key == 6){ k6();}
if(key == 7){ k7();}
}
void main()
{
init(); //全部功能初始化
lcd_disp_hanzhi(4,0,33,85);
lcd_disp_hanzhi(5,0,28,50);
lcd_disp_hanzhi(6,0,19,41);
// lcd_disp_hanzhi(7,0,28,68);
while(1)
{
if(XBYTE[0xCFE9]&0x07)
{
ReadKey();
key=key-192;
Display(key);
// ( * keyproctab[ReadKey()])(); //执行按键对应的功能
key_work();
delay(10);
}
}
}
void Time0(void) interrupt 1 using 0 //中断函数服务子程序
{
count++;
if(count >= 20)
{
scan_tim();//一秒时间到
//显示时间
count = 0;
}
TH0=(65536-46083)/256;
TL0=(65536-46083)%256;
}
void scan_tim() //时间记录函数
{
scond++;
disp_time(s_site_x,s_site_y,scond);
if(scond == 60)
{
scond = 0;
min ++;
disp_time(s_site_x,s_site_y,scond);
disp_time(m_site_x,m_site_y,min);
if(min == 60)
{
min = 0;
hour ++;
disp_time(m_site_x,m_site_y,min);
disp_time(h_site_x,h_site_y,hour);
if(hour == 24)
{
hour = 0;
disp_time(h_site_x,h_site_y,hour);
}
}
}
if( (set_ok==1) && (scond==s_scond) && (hour == s_hour) && (s_min==min) )
{
//上课时间到
set_ok = 0; //关闭
lcd_disp_ascii(0,15,'>');
// lcd_disp_hanzhi(0,1,41,47);
// lcd_disp_hanzhi(1,1,31,46);
}
if( (set_ok2==1) && (scond==s_scond2) && (hour == s_hour2) && (s_min2==min) )
{
//下课时间到
set_ok2 = 0; //关闭
lcd_disp_ascii(0,25,'<');
// lcd_disp_hanzhi(0,1,47,34);
// lcd_disp_hanzhi(1,1,31,46);
}
}
void lcd_init()
{
STOBE = 0;
BUSY = 1;
send(0xf4);
delay(10);
}
void time0_init()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-46083)/256;
TL0=(65536-46083)%256;
TR0=1;
}
void KbDisInit()
{
XBYTE[0xCFE9]=0x00;
XBYTE[0xCFE9]=0xD1;
while (XBYTE[0xCFE9]&0x80);
XBYTE[0xCFE8]=0x34;
}
void delay(uint tem)
{
uint ii,jj;
for (ii = 0;ii < tem; ii ++)
{
for (jj = 0;jj < 100; jj++);
}
}
/*************************************************/
/**
ASCII 码说明:
48--74 对应 0--9
58 为 :
30 为 上课
31 为 下课
14 为 到点
**/
/*************************************************/
// uchar i = 0;
// time0_init();
// KbDisInit();
// Display(0);
//
// lcd_init();
// send(0xf0);
// send(00);
// send(00);
// send(26);
// send(58);
//
// send(0xf1);
// send(8);
// send(18);
// send(29);
//
// send(0xf1);
// send(10);
// send(18);
// send(29);
参考文献
《微处理器原理及接口实验指导书》黑龙江大学电子实验中心 王积翔,庄培栋 编
31
32
展开阅读全文