zoukankan      html  css  js  c++  java
  • NIOS II LCD上面显示时间

    本文转载至:http://www.cnblogs.com/Neddy/archive/2010/07/18/1780249.html,在此对原作者的辛勤劳作表示深深的敬意!

     P8062382

    在LCD1602上面显示时间、日期和星期

    因为用到了SDRAM,首先我们添加一个PLL

    输入时钟 50MHz

    输出时钟 C0 50MHz ,相位-75度,给SDRAM提供时钟,引脚命名为sd_clk

                 C1 50NHz , 相位  0 度,给NIOS提供时钟信号,与NIOS CLK相连

    1、打开SOPC,添加CPU,选择NIOS II/s即可

    2、添加SDRAM,Presets选择Custom,Data width:16,其他的不动,点击Finish……

    3、添加timer,Period:1s,Presets:Full-featured

    4、添加Character LCD,没有参数设置

    5、添加PIO,Width:4 ,INPUT

    第二张参数设定画面,下降沿capture,边沿中断

    更名为key

    6、CPU的Reset Vector和Exception vector都为sdram

    7、Auto-Assign Base Addresses和Auto-Assign IRQs,再Generate……

    8、在原理图里面添加SOPC,更改PIN名,如下图:

    9、引脚锁定,根据实际情况做

    10、Start Compilation and progammer

    11、NIOS II 代码:

    #include "system.h"                      //包含基本的硬件描述信息
    #include "altera_avalon_timer_regs.h"    //定义内核寄存器的映射,提供对底层硬件的符号化访问
    #include "altera_avalon_pio_regs.h"      //包含基本的I/O口信息 
    #include "alt_types.h"                   //Altera定义的数据类型
    #include "sys/alt_irq.h"                 
    #include "unistd.h"                      //延时函数usleep
    #include "stdio.h"
    //定义端口
    #define key  *(volatile unsigned char *) KEY_BASE

    //函数声明
    void Timer_Init();
    void Timer_ISR(void* context, alt_u32 id);
    void display();
    void KeyDown_ISR(void* context, alt_u32 id);
    void KeyDown_Init();

    //变量定义
    alt_u8 num_s[8] = {0,0,0xbf,0,0,0xbf,0,0};//时间每位显示
    alt_u8 num_d[8] = {0,0,0,0,0,0,0,0};//日期每位显示
    alt_u8 second,min,hour,day,month,weekday;
    alt_u16 year;

    char *week[]={"SUN","MON","TUE","WED","THU","FRI","SAT"}; //星期

    void init_value(void)
    {
        second=0;
        min=0;
        hour=12;
        day=1;
        month=1;
        year=2010;
        weekday=0;
    }

    //按键中断服务函数
    void KeyDown_ISR(void* context, alt_u32 id)
    {
         if(key == 0x06) { second = 0;  while(key == 0x06){display();} }                     //秒调设置
         if(key == 0x05) { min++; if(min==60) min = 0;  while(key == 0x05){display();} }     //分调设置
         if(key == 0x03) { hour++; if(hour == 24) hour = 0;  while(key == 0x03){display();} }//小时设置
         if(key == 0x0e)    //日期设置
         {
            day++;
            if(  ( month<=7 && month%2 ) || ( month>=8 && (!(month%2)) )  ) //大月31天
            {
                 if(day==32)  day=1;
            }
            else       //小月30
            {
                 if(month==2)  //2月 是28天还是29天
                 {
                     if( (!(year%4) && year%100) || (!(year%400) ) )// 闰年 29天
                       { if(day==30)  day=1; }
                     else if(day==29) day=1;  //平年 28天
                 }
                 else if(day==31) day=1;
             }
             while(key == 0x0e) display();
         }
         if(key == 0x0c) { weekday++; if(weekday == 7) weekday = 0;  while(key == 0x0c){display();} }//月份设置
         if(key == 0x0d) { month++; if(month == 13) month = 1;  while(key == 0x0d){display();} }//月份设置
         if(key == 0x0b) { year--; if(year == 1900) year = 2010;  while(key == 0x0b){display();} }//年份设置,递减
         if(key == 0x08) { year++; if(year == 2100) year = 2010;  while(key == 0x08){display();} }//年份设置,递加

         IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE, 0x00);   //清中断捕获寄存器
    }

    //按键中断初始化
    void KeyDown_Init()
    {
        IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE, 0x07);   //开KEY中断
        IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE, 0x00);   //清中断捕获寄存器
        alt_irq_register(KEY_IRQ,0,KeyDown_ISR);           //注册中断函数
    }

    //定时器初始化
    void Timer_Init()
    {
        alt_irq_register(TIMER_IRQ,0,Timer_ISR);          //注册中断函数
        IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);   //清状态标志
        IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 7);  //启动定时器允许中断,连续计数
    }

    //定时器中断服务函数
    void Timer_ISR(void* context, alt_u32 id)
    {
        second++;
        if(second == 60) { min++; second = 0;}
        if(min == 60) { hour++; min = 0;}
        if(hour == 24) { day++;weekday++;hour = 0;}
        if(weekday == 7) weekday = 0;
        if(  ( month<=7 && month%2 ) || ( month>=8 && (!(month%2)) )  )
        {
            if(day==32)
            {
                day=1;
                month++;
            }
        }
        else
        {
            if(month==2)
            {
                if( (!(year%4) && year%100) || (!(year%400) ) )
                 {
                    if(day==30)
                    {
                         day=1;
                         month++;
                    }
                 }
                else if(day==29)
                 {
                          day=1;
                          month++;               
                 }
            }
            else if(day==31)
            {
                day=1;
                month++;
            }
        }
        if(month==13) { month = 1; year ++; }
        if(year==2100) year = 2010;
        //if(second % 2) duan[10] = 0xff;
        //else duan[10] = 0xbf;              //秒闪烁
        IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);    //清状态寄存器
    }

    //数码管显示函数
    void display()
    {
        num_s[0] = second % 10;
        num_s[1] = second / 10;
        num_s[2] = 10;
        num_s[3] = min % 10;
        num_s[4] = min / 10;
        num_s[5] = 10;
        num_s[6] = hour % 10;
        num_s[7] = hour / 10;
        num_d[0] = day%10;
        num_d[1] = day/10;
        num_d[2] = month%10;
        num_d[3] = month/10;
        num_d[4] = year%10;
        num_d[5] = year/10%10;
        num_d[6] = year/100%10;
        num_d[7] = year/1000;
       printf("   %d%d%d%d-%d%d-%d%d\n  %d%d-%d%d-%d%d   %s\n",
           num_d[7],num_d[6],num_d[5],num_d[4],num_d[3],num_d[2],num_d[1],num_d[0],
           num_s[7],num_s[6],num_s[4],num_s[3],num_s[1],num_s[0],week[weekday]);
       //LCD6102显示
    }

    //主函数
    int main(void)
    {
        KeyDown_Init(); //按键中断初始化
        Timer_Init();        //定时器初始化
        init_value();
        while(1)
        {
            display();  //显示      
        }
        return 0;
    }

    按键复用写的不好,根据实际情况更改……

  • 相关阅读:
    UVALive 7141 BombX
    CodeForces 722D Generating Sets
    CodeForces 722C Destroying Array
    CodeForces 721D Maxim and Array
    CodeForces 721C Journey
    CodeForces 415D Mashmokh and ACM
    CodeForces 718C Sasha and Array
    CodeForces 635C XOR Equation
    CodeForces 631D Messenger
    田忌赛马问题
  • 原文地址:https://www.cnblogs.com/kingst/p/1795273.html
Copyright © 2011-2022 走看看