单片机实验报告 实时时钟
单
片
机
实
验
报
告
姓名:姓名:学号:学号:
一、实验要求:
1. 设计一个实时时钟,四个八段数码管显示格式为:XX.XX(小时/分钟,24小时计时法);使用一个LED用来显示秒的状态,显示规则为:以1Hz频率闪烁,既亮灭一次为一秒钟,500毫秒亮、500毫秒灭。
2. 实时时钟可以通过3x4键盘设置初始值。数字键用于输入数值,sfb0键为设置键,sfb1键为开关键。
3. 设置初始值的流程:先按下sfb0键,四个数码管显示内容变为全“0”,并以1HZ频率开始闪烁并等待键盘输入小时、分钟数值(其中小时2位数,分钟2位数),输入完毕后,实时时钟开始以新输入的时间值开始计时。
4. 开关键的使用方法:在计时模式下按sfb1键一次,时钟停止计时,时间数值停留在按键那刻;在停止计时模式下,按sfb1键一次时钟开始继续计时。
5. 定时闹铃功能(加分功能,可选做):按sgp0_key键,进入闹铃值设置模式,四个数码管显示内容变为全“0”,并以1HZ频率开始闪烁并等待键盘输入小时、分钟数值(其中小时2位数,分钟2位数),此时计时仍然运行,输入完毕后,显示内容恢复为计时值。当时钟计时到达闹铃值,驱动蜂鸣器鸣响8次。
6. 增加通过RS232接口,更改时钟当前时间的功能。
二、实验程序说明:
对实验按键和存储位置的说明语句:
1.创建一个新工程,在该工程的器件编辑器(Device Editor)中选择定时器模块,然后将其按要求放置,如图所示。
图定时器模块放置图
2.配置全局资源。单击参数内容方框里的下拉箭头,选择合适的参数值,便可以更改工程中默认的全局资源。此实验配置的全局资源如图所示。
图全局资源配置
3.按图配置Timer8定时器模块的参数。
4.按图配置管脚驱动模式。
图管脚驱动模式的参数配置
5.程实现3×4矩阵键盘扫描功能,将按下键的键值显示在数码管上。相应的按键管脚配置如图如示。
按键管脚配置
实验程序:
//----------------------------------------------------------------------------
//文件名:main.c
//----------------------------------------------------------------------------
#include // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules #pragma interrupt_handler KeyScan
#pragma interrupt_handler timer1_ISR
//void KeyScan();
void delay10ms(unsigned char time);
void Dispaly(unsigned char k);
unsigned char key=1,temp, stopCount;
BYTE byte_Period,byte_Duty;
#define DATA PRT3DR
#define SEL PRT4DR
#define LED1 0b11111110
#define LED2 0b11111101
#define LED3 0b11111011
#define LED4 0b11110111
#define dp 0b11111110
#define sfb0 10
#define sfb1 11
#define STOP 12
#define RESET 13
#define CLOCK 14
#define sgp0_key 0
/*common anode LED,therefore the LED will light when the pin is low*/ unsigned char num[17] =
{0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x11,0xc1,
0x63,0x85 ,0x61,0x71,0xff};
unsigned char
reg[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x11,0xc1,0 x63,0x85,0x61,0x71,0xff};
unsigned char led1_dig=0,led2_dig=0,led3_dig=0,led4_dig=0;//分别是
1,2,3,4数码管现在的数
unsigned char led1=0,led2=0,led3=0,led4=0;
//当做缓存的数,设置的时候用到。
unsigned char led_count=1;
unsigned char led_dp=0, setnum=1;
//setnum表示当前设置的是第几位
unsigned char flag0, flag1, i, j;//flag0设置当前显示的是时钟还是设置的数,flag1设置时钟是停下来还是走
unsigned int count = 0, dpcount = 0;
//count就是一个计数的,dpcount是专门针对秒钟的点设置的计数的,根据实验的要求要分开
unsigned char clock1,clock2,clock3,clock4;
/******************************************************************* ***/
void timer1_ISR()
{
if(led_count==5)
led_count=1;//从第一位开始
dpcount++;
if( flag1 == 0 && count++ == 200)
/*频率是五十赫兹,要求四个数码管都显示一边,乘以四,就是200*/
{
count = 0;
if(led4_dig++ == 9)//if函数设置进制的问题,考虑时间不是十进制,所以对每位分别设置
{
led4_dig = 0;
if(led3_dig++ == 5)
{
led3_dig = 0;
if(led2_dig == 3 && led1_dig == 2 || led2_dig == 9)
{
led2_dig = 0;
if(led1_dig++ == 2)
led1_dig = 0;
}
else
led2_dig++;
}
}
}
if( flag0 == 0 )
{
led1 = led1_dig;
led2 = led2_dig;
led3 = led3_dig;
led4 = led4_dig;
}
switch(led_count)
{
case 1:
if(setnum==1 && dpcount %200 >99)//在设置的时候控制LED1灯的闪烁,半秒时间亮半秒时间灭
SEL=0xff&LED1,DATA=0xff;//LED1灯灭高电平熄灭,低电平点亮
else
SEL=0xff&LED1,DATA=reg[led1];//LED1灯亮,sel就是设置的地址,data就是置数
break;
case 2:
if(setnum==2 && dpcount %200 >99)
SEL=0xff&LED2,DATA=0xff;
else if(flag1 || led_dp==2 && dpcount % 200 < 100)
SEL=0xff&LED2,DATA=reg[led2]&dp;//秒钟的点额外分配, else
SEL=0xff&LED2,DATA=reg[led2];
break;
case 3:
if(setnum==3 && dpcount %200 >99)
SEL=0xff&LED3,DATA=0xff;
else
SEL=0xff&LED3,DATA=reg[led3];
break;
case 4:
if(setnum==4 && dpcount %200 >99)
SEL=0xff&LED4,DATA=0xff;
else
SEL=0xff&LED4,DATA=reg[led4];
break;
default:
break;
}
++led_count;//设置的时候第几位闪烁
}
void KeyScan() //键盘中断程序
{
PRT5DR=0b11111110;//assign p5[0]=0
temp=PRT5DR;
temp&=0xF0; //
if(temp !=0xF0)
{
delay10ms(1);
temp=PRT5DR;
temp&=0xF0;
if(temp !=0xF0)
{
temp=PRT5DR;
temp&=0xF0;
switch(temp)
{
case 0X70:
key=7;
break;
case 0XB0:
key=4;
break;
case 0XD0:
key=1;
break;
case 0XE0:
key=0;
break;
}
}
}
PRT5DR=0b11111101;//assign p5[1]=0 temp=PRT5DR;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=PRT5DR;
temp&=0xF0;
if(temp !=0xF0)
{
temp=PRT5DR;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=8;
break;
case 0b10110000:
key=5;
break;
case 0b11010000:
key=2;
break;
case 0b11100000:
key=sfb0;
break;
}
}
}
PRT5DR=0b11111011; //assign p5[2]=0
temp=PRT5DR;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=PRT5DR;
temp&=0xF0;
if(temp !=0xF0)
{
temp=PRT5DR;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=9;
break;
case 0b10110000:
key=6;
break;
case 0b11010000:
key=3;
break;
case 0b11100000:
key=sfb1;
break;
}
}
}
PRT5DR=0xf0;
}
void delay10ms( unsigned char time)//延时函数
{
unsigned char a,b,c;
for(a=0;a