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;
    }

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

  • 相关阅读:
    Linux sort -n 与 -g 排序对比
    shell中IF的用法介绍
    Firewalld 用法解析
    Centos7最小化安装后再安装图形界面
    PXE无人值守部署centos7.4操作系统
    kali之获取靶机的图片和看的url
    Kali的源得数字验证问题
    kali之Nmap (Network Mapper(网络映射器)
    kali之EtterCap学习
    Kali linux查看局域网内其他用户的输入信息
  • 原文地址:https://www.cnblogs.com/kingst/p/1795273.html
Copyright © 2011-2022 走看看