(原創) 如何在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
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)