凌阳61单片机使用7段数码管显示数字时钟的程序
2006-06-18 18:31
477 查看
#include <SPCE061v004.h>
#include <unspmacro.h>
//中断函数定义
void IRQ1(void) __attribute__((ISR));
void IRQ5(void) __attribute__((ISR));
void IRQ6(void) __attribute__((ISR));
enum { RUN, CHGSECOND, CHGMINUTE, CHGHOUR } clock_status; //时钟的状态
unsigned int hour,minute,second;
unsigned int show_hour, show_minute, show_second;
enum { NOKEY, PRESSING, PRESSED } key_status; //键盘按下与否的状态
unsigned key_code;
// 7段LED数码管的字形码,采用高八位输出,决定显示的字形,如: '0'、'1'等
const unsigned int zhixingma[] = { 0x3f00, 0x0600, 0x5b00, 0x4f00,
0x6600, 0x6d00, 0x7c00, 0x0700,
0x7f00,0x6f00 };
// 数码管选择的"位段码",决定哪一位数码管显示
const unsigned int weiduanma[] = {0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040};
//数码管的两个DD引脚, 为时,中间的冒号亮
const unsigned int wei_DD = 0x0081;
void display(unsigned int wei, unsigned int number)
{
*P_IOA_Data = zhixingma[number];
//设置位段码时,不能改变冒号的状态
*P_IOB_Data = weiduanma[wei] | (*P_IOB_Buffer & wei_DD);
}
//取反数码管中间的冒号
void opposite_dots()
{
*P_IOB_Data = wei_DD ^ (*P_IOB_Buffer);
}
void delay(unsigned int howlong)
{
while(howlong--){
unsigned int temp = 0x00ff;
*P_Watchdog_Clear = 1;
while(temp--);
}
}
void init()
{
INT_OFF();
*P_IOA_Dir = 0xff00;
*P_IOA_Attrib = 0xff00;
*P_IOB_Dir = 0x00ff;
*P_IOB_Attrib = 0x00ff;
*P_TimerA_Data = 0xffff - 256;
*P_TimerA_Ctrl = C_SourceA_1 | C_SourceB_256Hz;
*P_INT_Ctrl = C_IRQ1_TMA | C_IRQ6_TMB2 | C_IRQ5_2Hz;
INT_IRQ();
}
void change_clock()
{
unsigned int key_code = get_key();
static unsigned int max;
switch(key_code){ // key_code == 0 will do nothing
case 1:
switch( clock_status ){
case CHGSECOND:
if(++second == 60) second = 0;
break;
case CHGMINUTE:
if(++minute == 60) minute = 0;
break;
case CHGHOUR:
if(++hour == 24) hour =0;
break;
default:
break;
}
break;
case 2:
switch( clock_status ){
case CHGSECOND:
if(--second == 0) second = 59;
break;
case CHGMINUTE:
if(--minute == 0) minute = 59;
break;
case CHGHOUR:
if(--hour == 0) hour = 23;
break;
default:
break;
}
break;
case 3:
switch( clock_status ){
case RUN:
clock_status = CHGSECOND;
break;
case CHGSECOND:
clock_status = CHGMINUTE;
break;
case CHGMINUTE:
clock_status = CHGHOUR;
break;
case CHGHOUR:
clock_status = RUN;
break;
}
break;
default:
break;
}
}
int main()
{
init();
while(1){
change_clock();
if(show_second){
display(5, second % 10);
delay(1);
display(4, second / 10);
delay(1);
}
if(show_minute){
display(3, minute % 10);
delay(1);
display(2, minute / 10);
delay(1);
}
if(show_hour){
display(1, hour % 10);
delay(1);
display(0, hour / 10);
delay(1);
}
}
}
void IRQ1()
{
//时钟计数中断
if( (C_IRQ1_TMA & *P_INT_Ctrl) != 0 )
{ if( clock_status == RUN )
{ second++;
if(second >= 60 ) second=0, minute++;
if(minute >= 60 ) minute=0, hour++;
if(hour >= 24 ) hour=0;
}
*P_INT_Clear = C_IRQ1_TMA;
}
}
void IRQ5()
{// 数码管闪烁
if( (C_IRQ5_2Hz & *P_INT_Ctrl) != 0)
{
switch(clock_status){
case RUN:
opposite_dots();
show_hour = show_minute = show_second = 0xffff;
break;
case CHGSECOND:
show_second ^= 0xffff;
show_minute = show_hour = 0xffff;
break;
case CHGMINUTE:
show_minute ^= 0xffff;
show_second = show_hour = 0xffff;
break;
case CHGHOUR:
show_hour ^= 0xffff;
show_second = show_minute = 0xffff;
break;
}
*P_INT_Clear = C_IRQ5_2Hz;
}
}
void IRQ6()
{ // 每10ms扫描一次键盘
static unsigned int old_key = 0;
static unsigned int key_count = 0;
unsigned int current_key;
if( (C_IRQ6_TMB2 & *P_INT_Ctrl) != 0)
{ current_key = *P_IOA_Data & 0x0007;
if( current_key != 0)
{ //有按键
if( key_status == NOKEY )
{ old_key = current_key;
key_count++;
key_status = PRESSING;
}else{
if( current_key == old_key) //不相等,抖动
{
if( ++key_count >= 5)
//有>5次扫描的值相等,说明不是抖动,判断按键值
{ if(current_key == 0x0001) key_code = 1;
if(current_key == 0x0002) key_code = 2;
if(current_key == 0x0004) key_code = 3;
}
}else{
// 抖动
old_key = 0;
key_count = 0;
key_status = NOKEY;
}
}
}else{ //无按键
old_key = 0;
key_count = 0;
if( key_status == PRESSING ) key_status = PRESSED; //按键释放了
}
*P_INT_Clear = C_IRQ6_TMB2;
}
}
#include <unspmacro.h>
//中断函数定义
void IRQ1(void) __attribute__((ISR));
void IRQ5(void) __attribute__((ISR));
void IRQ6(void) __attribute__((ISR));
enum { RUN, CHGSECOND, CHGMINUTE, CHGHOUR } clock_status; //时钟的状态
unsigned int hour,minute,second;
unsigned int show_hour, show_minute, show_second;
enum { NOKEY, PRESSING, PRESSED } key_status; //键盘按下与否的状态
unsigned key_code;
// 7段LED数码管的字形码,采用高八位输出,决定显示的字形,如: '0'、'1'等
const unsigned int zhixingma[] = { 0x3f00, 0x0600, 0x5b00, 0x4f00,
0x6600, 0x6d00, 0x7c00, 0x0700,
0x7f00,0x6f00 };
// 数码管选择的"位段码",决定哪一位数码管显示
const unsigned int weiduanma[] = {0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040};
//数码管的两个DD引脚, 为时,中间的冒号亮
const unsigned int wei_DD = 0x0081;
void display(unsigned int wei, unsigned int number)
{
*P_IOA_Data = zhixingma[number];
//设置位段码时,不能改变冒号的状态
*P_IOB_Data = weiduanma[wei] | (*P_IOB_Buffer & wei_DD);
}
//取反数码管中间的冒号
void opposite_dots()
{
*P_IOB_Data = wei_DD ^ (*P_IOB_Buffer);
}
void delay(unsigned int howlong)
{
while(howlong--){
unsigned int temp = 0x00ff;
*P_Watchdog_Clear = 1;
while(temp--);
}
}
void init()
{
INT_OFF();
*P_IOA_Dir = 0xff00;
*P_IOA_Attrib = 0xff00;
*P_IOB_Dir = 0x00ff;
*P_IOB_Attrib = 0x00ff;
*P_TimerA_Data = 0xffff - 256;
*P_TimerA_Ctrl = C_SourceA_1 | C_SourceB_256Hz;
*P_INT_Ctrl = C_IRQ1_TMA | C_IRQ6_TMB2 | C_IRQ5_2Hz;
INT_IRQ();
}
void change_clock()
{
unsigned int key_code = get_key();
static unsigned int max;
switch(key_code){ // key_code == 0 will do nothing
case 1:
switch( clock_status ){
case CHGSECOND:
if(++second == 60) second = 0;
break;
case CHGMINUTE:
if(++minute == 60) minute = 0;
break;
case CHGHOUR:
if(++hour == 24) hour =0;
break;
default:
break;
}
break;
case 2:
switch( clock_status ){
case CHGSECOND:
if(--second == 0) second = 59;
break;
case CHGMINUTE:
if(--minute == 0) minute = 59;
break;
case CHGHOUR:
if(--hour == 0) hour = 23;
break;
default:
break;
}
break;
case 3:
switch( clock_status ){
case RUN:
clock_status = CHGSECOND;
break;
case CHGSECOND:
clock_status = CHGMINUTE;
break;
case CHGMINUTE:
clock_status = CHGHOUR;
break;
case CHGHOUR:
clock_status = RUN;
break;
}
break;
default:
break;
}
}
int main()
{
init();
while(1){
change_clock();
if(show_second){
display(5, second % 10);
delay(1);
display(4, second / 10);
delay(1);
}
if(show_minute){
display(3, minute % 10);
delay(1);
display(2, minute / 10);
delay(1);
}
if(show_hour){
display(1, hour % 10);
delay(1);
display(0, hour / 10);
delay(1);
}
}
}
void IRQ1()
{
//时钟计数中断
if( (C_IRQ1_TMA & *P_INT_Ctrl) != 0 )
{ if( clock_status == RUN )
{ second++;
if(second >= 60 ) second=0, minute++;
if(minute >= 60 ) minute=0, hour++;
if(hour >= 24 ) hour=0;
}
*P_INT_Clear = C_IRQ1_TMA;
}
}
void IRQ5()
{// 数码管闪烁
if( (C_IRQ5_2Hz & *P_INT_Ctrl) != 0)
{
switch(clock_status){
case RUN:
opposite_dots();
show_hour = show_minute = show_second = 0xffff;
break;
case CHGSECOND:
show_second ^= 0xffff;
show_minute = show_hour = 0xffff;
break;
case CHGMINUTE:
show_minute ^= 0xffff;
show_second = show_hour = 0xffff;
break;
case CHGHOUR:
show_hour ^= 0xffff;
show_second = show_minute = 0xffff;
break;
}
*P_INT_Clear = C_IRQ5_2Hz;
}
}
void IRQ6()
{ // 每10ms扫描一次键盘
static unsigned int old_key = 0;
static unsigned int key_count = 0;
unsigned int current_key;
if( (C_IRQ6_TMB2 & *P_INT_Ctrl) != 0)
{ current_key = *P_IOA_Data & 0x0007;
if( current_key != 0)
{ //有按键
if( key_status == NOKEY )
{ old_key = current_key;
key_count++;
key_status = PRESSING;
}else{
if( current_key == old_key) //不相等,抖动
{
if( ++key_count >= 5)
//有>5次扫描的值相等,说明不是抖动,判断按键值
{ if(current_key == 0x0001) key_code = 1;
if(current_key == 0x0002) key_code = 2;
if(current_key == 0x0004) key_code = 3;
}
}else{
// 抖动
old_key = 0;
key_count = 0;
key_status = NOKEY;
}
}
}else{ //无按键
old_key = 0;
key_count = 0;
if( key_status == PRESSING ) key_status = PRESSED; //按键释放了
}
*P_INT_Clear = C_IRQ6_TMB2;
}
}
相关文章推荐
- 利用单片机的数码管模拟时钟的显示时间
- 52单片机控制数码管显示数字
- 使用JS显示倒计时数字时钟效果
- 【程序】STM32F103单片机使用定时器DMA进行全自动8位数码管动态扫描
- 单片机:按键(使用中断)控制数码管的数字加减(c语言实现)
- 基于proteus的51单片机仿真实例七十八、使用BCD译码器实现8位数码管显示应用实例
- FPGA 使用verilog 编写的AD tlc549 测试程序,数码管做显示,本程序已验证
- 80C51 单片机 数码管显示循环数字
- 使用黑金开发板做出的键盘边沿检测的用数码管显示的verilog hdl 程序
- 使用单片机的定时器0和中断实现9到0的倒计时功能,并用数码管显示
- 单片机数码管时钟显示
- 并行口实现数字0~9、A~F、L、U、P、n总共19个键盘,将按键的结果用7段数码管(例如:7SEG-MPX-CA-BLUE)显示(可选——按键控制移位)出来
- 整理2010年51单片机程序--4*4按键与数码管显示
- 4位共阳数码管 显示数字,调节亮度,时钟调时,控制LED巧妙编程
- 时钟一:51单片机用替换的方法在数码管上显示时钟
- 数字时钟(数码管显示)例如:23-59-23
- 一天:51单片机从入门到一个动态数码管显示数字控制
- 使用JS显示倒计时数字时钟效果
- n久前的51单片机4*4键盘加4数码管显示汇编程序
- VS2010 使用GDI+创建显示GIF的MFC程序