基于DE0的数字钟【SOPC+NIOS】

http://www.ceet.hbnu.edu.cn/bbs/viewthread.php?tid=7281&extra=page%3D2

写在前面的话:最近两天在写这个东西,一直没写出来,最终在一个FPGA研究群里受人指点:
     #define seg1  *(volatile unsigned char *) SEG_1_BASE
     这种寄存器映射如果CPU等级选在F型的话,就不能映射,所以我改为S型的。
     至于为什么,我也没弄清楚,一会把原因发给大家,我把C程序给大家看。

  1. #include "system.h" //包含基本的硬件描述信息
  2. #include "altera_avalon_timer_regs.h" //定义内核寄存器的映射,提供对底层硬件的符号化访问
  3. #include "altera_avalon_pio_regs.h" //包含基本的I/O口信息
  4. #include "alt_types.h" //Altera定义的数据类型
  5. #include "sys/alt_irq.h"
  6. //#include "sys/alt_alarm.h" //系统时钟服务头文件
  7. #include "unistd.h" //延时函数usleep
  8. //定义端口
  9. #define seg1 *(volatile unsigned char *) SEG_1_BASE
  10. #define seg2 *(volatile unsigned char *) SEG_2_BASE
  11. #define seg3 *(volatile unsigned char *) SEG_3_BASE
  12. #define seg4 *(volatile unsigned char *) SEG_4_BASE
  13. #define key *(volatile unsigned char *) KEY_BASE
  14. //函数声明
  15. void Timer_Init();
  16. void Timer_ISR(void* context, alt_u32 id);
  17. void display();
  18. void KeyDown_ISR(void* context, alt_u32 id);
  19. void KeyDown_Init();
  20. //变量定义
  21. alt_u8 duan[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF};
  22. alt_u8 num[8] = {0,0,0,0,0,0,0,0};
  23. alt_u8 second,min,hour;
  24. //按键中断服务函数
  25. void KeyDown_ISR(void* context, alt_u32 id)
  26. {
  27. if(key == 0x06) { second = 0; while(key == 0x06){display();} } //秒调设置
  28. if(key == 0x05) { min++; if(min==60) min = 0; while(key == 0x05){display();} } //分调设置
  29. if(key == 0x03) { hour++; if(hour == 24) hour = 0; while(key == 0x03){display();} }//小时设置
  30. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE, 0x00); //清中断捕获寄存器
  31. }
  32. //按键中断初始化
  33. void KeyDown_Init()
  34. {
  35. IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE, 0x07); //开KEY中断
  36. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE, 0x00); //清中断捕获寄存器
  37. alt_irq_register(KEY_IRQ,0,KeyDown_ISR); //注册中断函数
  38. }
  39. //定时器初始化
  40. void Timer_Init()
  41. {
  42. IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE, 0); //清状态标志
  43. //1S的定时
  44. IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER1_BASE, 50000000>>16);
  45. IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER1_BASE, 50000000&0xffff);//修改定时时间1s
  46. IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE, 0x07); //启动定时器允许中断,连续计数
  47. alt_irq_register(TIMER1_IRQ,0,Timer_ISR); //注册中断函数
  48. }
  49. //定时器中断服务函数
  50. void Timer_ISR(void* context, alt_u32 id)
  51. {
  52. second++;
  53. if(second == 60) { min++; second = 0;}
  54. if(min == 60) { hour++; min = 0;}
  55. if(hour == 24) { hour = 0;}
  56. if(second % 2) duan[10] = 0xff;
  57. else duan[10] = 0xbf; //秒闪烁
  58. IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE, 0); //清状态寄存器
  59. }
  60. //数码管显示函数
  61. void display()
  62. {
  63. //alt_u8 j;
  64. num[0] = second % 10;
  65. num[1] = second / 10;
  66. num[2] = 10;
  67. num[3] = min % 10;
  68. num[4] = min / 10;
  69. num[5] = 10;
  70. num[6] = hour % 10;
  71. num[7] = hour / 10;
  72. seg1 = duan[num[0]];
  73. seg2 = duan[num[1]];
  74. seg3 = duan[num[3]];
  75. seg4 = duan[num[4]];
  76. usleep(500);
  77. }
  78. //主函数
  79. int main(void)
  80. {
  81. KeyDown_Init(); //按键中断初始化
  82. Timer_Init(); //定时器初始化
  83. while(1)
  84. {
  85. display(); //显示
  86. }
  87. return 0;
  88. }
复制代码

此程序在DE0上完美显示
按键可调

转载于:https://www.cnblogs.com/GL-BBL/archive/2012/08/23/2651752.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值