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
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 " system.h "
#include " io.h "
stdio.h為ANSI C的standard library, printf()與scanf()使用。
system.h記載著Nios II各周邊資訊,稍後會介紹。
io.h定義了IOWR(),負責寫入資料到指定位址。
22行
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行
將轉換後的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_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。
完整程式碼下載
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)