基于NIOS II的电子钟设计

此设计为笔者实验课期末设计,仅供参考,博客贴出实现方法和C语言部分程序源代码,实现过程用时不长,故没有对代码进行优化,但功能已实现。工程文件提交到CSDN下载当中,需要可以下载,https://download.csdn.net/download/g_curry/10855434另外还有设计报告,如需要可私信博主获取。

要求必须使用Verilog和Sopc两项功能,故在硬件部分使用Verilog编写出数码管的驱动程序,使用NiOS II编写实现过程。

1.功能需求

    1)实现数字时钟准确实时的计时与显示功能;

    2)实现闹钟功能,即系统时间到达闹钟时间时闹铃响;

    3)实现时间和闹钟时间的调时功能;

    4)实现流水灯指示功能。

2.设计方案

    1)使用Qsys生成的定时器timer_1ms实现计时功能;

    2)使用8个数码管显示时间;

    3)使用3个按钮实现调时间和闹钟时间的功能。

按键1:更换模式(模式0:正常显示时间;模式1:调当前时间的小时;模式2;调当前时间的分钟;模式3:当前时间的秒;模式4:调闹钟时间的小时;模式5:调闹钟时间的分钟);

按键2:在非模式0下给需要调节的时间数加一,但不溢出;

按键3:在非模式0下给需要调节的时间数减一,但不小于零;

实现时间和闹钟时间的调时功能;

    4)加入闪烁标志,给正在调整的位闪烁,判断是哪一位在调整;

    5)按键按下时,对应一个led灯点亮;

    6)使用蜂鸣器实现闹钟功能,闹钟响时实现流水灯指示功能。

3.硬件规划

在硬件系统组织规划中系统需使用的外围器件包括:

    1)数码管:数子钟显示屏幕;

    2)按键:数子钟设置功能键;

    3)LED灯:8位LED灯做指示灯;

    4)蜂鸣器:闹钟响铃。存储软、硬件程序;

在SOPC Qsys中建立系统添加的模块包括:

    1)连接数码管的PIO;

    2)Interval Timer;

    3)按键PIO;

    4)On-Chip Memory RAM;

    5)On-Chip Memory ROM;

    6)System ID Peripheral;

#include <sys/unistd.h>
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "altera_avalon_timer_regs.h"
#include "sys/alt_irq.h"

int hour = 23,minute = 59,second = 50;
int hour1 = 0,minute1 = 0,n =0;
int segtab[12]={0x0,0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,0xf,0xe};
int model_flag = 0,S_flag = 0,BEEP = 0,beep_flag = 0,beep_flag1 = 0;
int key_set = 1,key_add = 1,key_sub = 1,key_rst = 1;
int a[8]={0,0,0,0,0,0,0,0};

void write_data()
{
	IOWR(DIG_1_BASE,0,a[7]);
	IOWR(DIG_2_BASE,0,a[6]);
	IOWR(DIG_3_BASE,0,a[5]);
	IOWR(DIG_4_BASE,0,a[4]);
	IOWR(DIG_5_BASE,0,a[3]);
	IOWR(DIG_6_BASE,0,a[2]);
	IOWR(DIG_7_BASE,0,a[1]);
	IOWR(DIG_8_BASE,0,a[0]);
}
void rst()
{
	 if(key_rst==0)
	 {
		key_rst =1;
		a[0]=2;
		a[1]=3;
		a[2]=segtab[10];
		a[3]=5;
		a[4]=9;
		a[5]=segtab[10];
		a[6]=5;
		a[7]=5;
		write_data();
	 }
}
void set_led(int led_flag, int state)
{
	if ( led_flag == 1) {
		IOWR(LED_BASE,0,0xff);
	}
	else if ( led_flag == 2){
		IOWR(LED_BASE,0,state);
	}
	else {
		IOWR(LED_BASE,0,0x00);
	}
}
void delay(int us)// 延时函数
{

	int i,j;
	for ( i = us; i > us; i--) {
		for ( j = 50; j > 0; j--);
	}}
int read_key()
{
	int status = 0;
	status = IORD(KEY_BASE,0);
	return status;
}
int tmp = 0;
void check_key()
{
	delay(10);
	int status = IORD(KEY_BASE,0);
  	if ( status) {
		tmp ++;
		if ( tmp == 50) {
			if ( status & 0x01) {
					key_set = 0;
					set_led(2,0x01);
				}
				else if ( status & 0x01 << 1) {
					key_add =0;
					set_led(2,0x02);
				}
				else if ( status & 0x01<< 2){
					key_sub = 0;
					set_led(2,0x04);
				}
				else if ( status & 0x01<< 3){
					key_rst = 0;
					set_led(2,0x08);
				}
				else
				{
					tmp = 0;
				}}}
	else {
		tmp = 0;
	}}
void delay(int us)// 延时函数
{
	int i,j;
	for ( i = us; i > us; i--) {
		for ( j = 50; j > 0; j--);
	}
}
int flag = 0,ss_add = 0;

void ISR_timer(void * context, alt_u32 id)
{
    IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_1S_BASE, 0);
    ss_add++;
    if(ss_add >= 500)
    {
    	ss_add = 0;
    	S_flag =! S_flag;	      //闪烁标志位
    }
    flag = 1;
}
void display()
{
	switch(model_flag)
	{
	case 0:
		{
			a[0]=segtab[hour/10];
			a[1]=segtab[hour%10];
			a[2]=segtab[10];
			a[3]=segtab[minute/10];
			a[4]=segtab[minute%10];
			a[5]=segtab[10];
			a[6]=segtab[second/10];
			a[7]=segtab[second%10];
			write_data();
		}break;
	case 1:
		{
			if(S_flag==1)
			{
				a[0]=segtab[hour/10];
				a[1]=segtab[hour%10];
			}
			else
			{
				a[0]=segtab[11];
				a[1]=segtab[11];
			}
			a[2]=segtab[10];		//横线-
			a[3]=segtab[minute/10];
			a[4]=segtab[minute%10];
			a[5]=segtab[10];
			a[6]=segtab[second/10];
			a[7]=segtab[second%10];
			write_data();
		}
		break;
	case 2:
		{
			a[0]=segtab[hour/10];
			a[1]=segtab[hour%10];
			a[2]=segtab[10];
			if(S_flag==1)
			{
				a[3]=segtab[minute/10];
				a[4]=segtab[minute%10];
			}
			else
			{
				a[3]=segtab[11];
				a[4]=segtab[11];
			}
			a[5]=segtab[10];
			a[6]=segtab[second/10];
			a[7]=segtab[second%10];
			write_data();
		}break;
	case 3:
		{
			a[0]=segtab[hour/10];
			a[1]=segtab[hour%10];
			a[2]=segtab[10];
			a[3]=segtab[minute/10];
			a[4]=segtab[minute%10];
			a[5]=segtab[10];
			if(S_flag==1)
			{
				a[6]=segtab[second/10];
				a[7]=segtab[second%10];
			}
			else
			{
				a[6]=segtab[11];
				a[7]=segtab[11];
			}
			write_data();
		}break;
	case 4:
		{
			if(S_flag==1)
			{
				a[0]=segtab[hour1/10];
				a[1]=segtab[hour1%10];
			}
			else
			{
				a[0]=segtab[11];
				a[1]=segtab[11];
			}
			a[2]=segtab[10];
			a[3]=segtab[minute1/10];
			a[4]=segtab[minute1%10];
			a[5]=segtab[10];
			a[6]=segtab[11];
			a[7]=segtab[11];
			write_data();
		}break;
	case 5:
		{
			a[0]=segtab[hour1/10];
			a[1]=segtab[hour1%10];
			a[2]=segtab[10];
			if(S_flag==1)
			{
				a[3]=segtab[minute1/10];
				a[4]=segtab[minute1%10];
			}
			else
			{
				a[3]=segtab[11];
				a[4]=segtab[11];
			}
			a[5]=segtab[10];
			a[6]=segtab[11];
			a[7]=segtab[11];
			write_data();
		}
	}
}
void key_model()
{
   if(key_set==0)
	 {
			key_set = 1;
			model_flag++;
			if(model_flag==6)
			model_flag=0;	 
}
   if(model_flag!=0)
   {
	 switch(model_flag)
	 {
		  case 1:		   //模式——调时
		  {
			if(key_add==0)
			{
					key_add = 1;
					if(hour<23) hour++;
					else hour=0;
			}
			if(key_sub==0)
			{
					key_sub = 1;
					if(hour> 0) hour--;
					else hour=23;
			}
		  } break;
		  case 2:		  //模式——调分
		  {
			if(key_add==0)
			{
					key_add = 1;
					if(minute<59) minute++;
					else minute=0;
			}
			if(key_sub==0)
			{
					key_sub = 1;
					if(minute>0) minute--;
					else minute=59;
			}
		} break;
		 case 3:		  //模式——调秒
		  {
			if(key_add==0)
			{
					key_add = 1;
					if(second<59) second++;
					else second=0;
			}
			if(key_sub==0)
			{
					key_sub = 1;
					if(second>0) second--;
					else second=59;
			}
		} break;
		 case 4:		  //模式——闹钟调时
		  {
			if(key_add==0)
				{
					key_add = 1;
					if(hour1<23)
					hour1++;
					else hour1=0;
				}
			 if(key_sub==0)
				{
					key_sub = 1;
					if(hour1>0)
					hour1--;
					else hour1=23;
				 }
		  }	 break;
		  case 5:		  //模式——闹钟调分
		   {
			 if(key_add==0)
				{
					key_add = 1;
					if(minute1<59)
					minute1++;
					else minute1=0;
				}
			if(key_sub==0)
				{
					key_sub = 1;
					if(minute1>0)
					minute1--;
					else minute1=59;
				}
			}  break;
		}
	}
}
void naozhong()
{
	if(hour1==hour&&minute1==minute&&second<10) //闹钟时间到
	{
		beep_flag = ~beep_flag;
		if (beep_flag == 0)
			IOWR(BEEP_BASE,0,0);
		else
			IOWR(BEEP_BASE,0,1);
		if(S_flag==1)
		{
			set_led(2,0x55);
		}
		else
		{
			set_led(2,~0x55);
		}
	}
}
int main()
{
	alt_irq_register(TIMER_1S_IRQ,0,ISR_timer);
	flag = 0;
    while(1)
    {
		check_key();
		key_model();
    	if (flag)
    	{
    		rst();
    		naozhong();
    		flag = 0;
    		n++;
			if(n == 1000)
			{
				n = 0;
				second++;
				if(second >= 60)
				{
					minute++;
					second = 0;
				}
				if(minute >= 60)
				{
					hour++;
					minute = 0;
				}
				if(hour >= 24)
				{
					hour = 0;
				}
			}
			display();
    	}
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/g_curry/article/details/85047700
今日推荐