(原創) 如何在Console控制LED顯示? (SOC) (Nios II) (DE2)

Abstract
本文介紹如何在Nios II EDS console輸入數字控制DE2的LED顯示。

Introduction
使用環境:Quartus II 8.0 + DE2(Cyclone II EP2C35F627C6)

有網友問到如何在Nios II EDS的console輸入數字控制LED顯示,如輸入0則LEDG0亮,輸入1則LEDG1亮,以此類推。這是一個初學者熟悉Nios II與DE2很好的練習。

硬體部分
硬體部分我直接使用(原創) DE2_NIOS_Lite 1.1 (SOC) (Nios II) (SOPC Builder) (μC/OS-II) (DE2)所提供的Nios II,這已經驅動了DE2上最常用的周邊,很適合初學者學習。

軟體部分

hello_world.c / C

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : hello_world.c
5 Compiler    : Nios II EDS 8.0 / ANSI C
6 Description : Demo how to use control LEDG by console
7 Release     : 10/02/2008 1.0
8 */
9 
10 #include <stdio.h>
11 #include "system.h"
12 #include "io.h"
13 
14 int main() {
15   unsigned int led, ledg;
16    
17   printf("Please type 0 to 7 to control LEDG!\n");
18  
19   while(1) {
20     scanf("%d",&led);
21    
22     switch(led) {
23       case 0:
24         ledg = 0x01;
25         break;
26      
27       case 1:
28         ledg = 0x02;
29         break;
30        
31       case 2:
32         ledg = 0x04;
33         break;
34        
35       case 3:
36         ledg = 0x08;
37         break;
38        
39       case 4:
40         ledg = 0x10;
41         break;
42        
43       case 5:
44         ledg = 0x20;
45         break;
46        
47       case 6:
48         ledg = 0x40;
49         break;
50        
51       case 7:
52         ledg = 0x80;
53         break;
54      
55       default:
56         ledg = 0x01;
57         break;
58     } 
59      
60     IOWR(LEDG_PIO_BASE, 0, ledg);
61   }
62   
63   return 0;
64 }


10行

#include <stdio.h>
#include
"system.h"
#include
"io.h"


stdio.h為ANSI C的standard library, printf()與scanf()使用。
system.h記載著Nios II各周邊資訊,稍後會介紹。
io.h定義了IOWR(),負責寫入資料到指定位址。

22行

switch(led) {
 
case 0:
    ledg
= 0x01;
   
break;
     
 
case 1:
    ledg
= 0x02;
   
break;
       
 
case 2:
    ledg
= 0x04;
   
break;
       
 
case 3:
    ledg
= 0x08;
   
break;
       
 
case 4:
    ledg
= 0x10;
   
break;
       
 
case 5:
    ledg
= 0x20;
   
break;
       
 
case 6:
    ledg
= 0x40;
   
break;
       
 
case 7:
    ledg
= 0x80;
   
break;
     
 
default:
    ledg
= 0x01;
   
break;


根據定義, 如輸入0則LEDG0亮,輸入1則LEDG1亮,以此類推...。但LEDG用的是二進位顯示,也就是說,若要LEDG[0]亮,要輸入Verilog的8'b0000_0001(相當於C的0x01),若要LEDG[1]亮,要輸入8'b0000_0010(相當於C的0x02),若要LEDG[2]亮,要輸入8'b0000_0100(相當於C的0x04),所以這個switch提供了這樣的轉換。

60行

IOWR(LEDG_PIO_BASE, 0, ledg);


將轉換後的ledg透過IOWR() macro寫入LED_PIO_BASE位址,這個位址正是LEDG所在的位址。

或許你會問,為什麼我知道LEDG_PIO_BASE呢?

因為在\DE2_NIOS_Lite_11_led\software\hello_world_0_syslib\Debug\system_description\system.h的265行

#define LEDG_PIO_NAME "/dev/ledg_pio"
#define LEDG_PIO_TYPE "altera_avalon_pio"
#define LEDG_PIO_BASE 0x01921040
#define LEDG_PIO_SPAN 16
#define LEDG_PIO_DO_TEST_BENCH_WIRING 0
#define LEDG_PIO_DRIVEN_SIM_VALUE 0
#define LEDG_PIO_HAS_TRI 0
#define LEDG_PIO_HAS_OUT 1
#define LEDG_PIO_HAS_IN 0
#define LEDG_PIO_CAPTURE 0
#define LEDG_PIO_DATA_WIDTH 9
#define LEDG_PIO_RESET_VALUE 0
#define LEDG_PIO_EDGE_TYPE "NONE"
#define LEDG_PIO_IRQ_TYPE "NONE"
#define LEDG_PIO_BIT_CLEARING_EDGE_REGISTER 0
#define LEDG_PIO_FREQ 100000000
#define ALT_MODULE_CLASS_ledg_pio altera_avalon_pio


定義了LEDG_PIO_BASE,這個位址正是SOPC Builder所替我們規畫的位址。也因此我們能利用IOWR()去控制LED。

ledg_pio

完整程式碼下載
DE2_NIOS_Lite_11_led.7z

Conclusion
雖然是個小小的範例,卻包含很多知識值得學習,適合初學者拿來當DE2與Nios II的tutorial練習。

See Also
(原創) DE2_NIOS_Lite 1.1 (SOC) (Nios II) (SOPC Builder) (μC/OS-II) (DE2)

posted on 2008-10-02 19:08  真 OO无双  阅读(4750)  评论(22编辑  收藏  举报

导航