閱讀532 返回首頁    go 外匯


怎樣製作一個簡單ip,以方便在Quartus II和Nios II中使用?.[Nios II][中]

2 軟件部分

表2.1 Amy_S_lcd12864 IP的C源代碼模塊介紹

文件名稱 功能描述
Amy_S_lcd12864.h Amy_S_lcd12864 的C頭文件
Amy_S_lcd12864.c Amy_S_lcd12864 的C源文件

2.1 C頭文件

2.1.1 Amy_S_lcd12864.h
01 /*-----版權聲明-----
02  *     艾米電子工作室——讓開發變得更簡單
03  *     網站:https://www.amy-studio.com
04  *     淘寶:https://amy-studio.taobao.com
05  *     QQ(郵箱):amy-studio@qq.com
06  *-----文件信息-----
07  *     文件名稱:Amy_S_lcd12864.h
08  *     最後修改日期:3.20, 2009
09  *     描述:Lcd12864驅動宏文件
10  *------------------
11  *     創建者:張亞峰
12  *     創建日期:3.20, 2009
13  *     版本:1.0
14  *     描述:原始版本
15  *------------------
16  *     修改者:
17  *     修改日期:
18  *     版本:
19  *     描述:
20  *-------------------
21  */
22  
23  
24 #ifndef __Amy_S_LCD12864_H__
25 #define __Amy_S_LCD12864_H__
26  
27  
28 //++++++++++++++++++++++++++++++++++++++
29 // 基地址 開始
30 // 根據SOPC Builder設置編寫
31 //++++++++++++++++++++++++++++++++++++++
32 #include "system.h"
33  
34 #define lcd12864_addr LCD12864_BASE
35 //--------------------------------------
36 // 基地址 開始
37 //--------------------------------------
38  
39  
40 //++++++++++++++++++++++++++++++++++++++
41 // 寄存器映射 開始
42 // 根據HDL編寫
43 //++++++++++++++++++++++++++++++++++++++
44 #include <io.h>
45  
46 #define IOWR_LCD12864_E(base, data)     IOWR(base, 0, data)
47 #define IOWR_LCD12864_RW(base, data)    IOWR(base, 1, data)
48 #define IOWR_LCD12864_RS(base, data)    IOWR(base, 2, data)
49 #define IOWR_LCD12864_DATA(base, data)  IOWR(base, 3, data)
50 #define IORD_LCD12864_DATA(base)        IORD(base, 3)
51 //--------------------------------------
52 // 寄存器映射 結束
53 //--------------------------------------
54  
55  
56 //++++++++++++++++++++++++++++++++++++++
57 // 管腳操作 開始
58 //++++++++++++++++++++++++++++++++++++++
59 #define SET_E         IOWR_LCD12864_E(lcd12864_addr, 1)
60 #define CLR_E         IOWR_LCD12864_E(lcd12864_addr, 0)
61 #define SET_RW        IOWR_LCD12864_RW(lcd12864_addr, 1)
62 #define CLR_RW        IOWR_LCD12864_RW(lcd12864_addr, 0)
63 #define SET_RS        IOWR_LCD12864_RS(lcd12864_addr, 1)
64 #define CLR_RS        IOWR_LCD12864_RS(lcd12864_addr, 0)
65 #define WR_DATA(data) IOWR_LCD12864_DATA(lcd12864_addr, data)
66 #define RD_DATA       IORD_LCD12864_DATA(lcd12864_addr)
67 //--------------------------------------
68 // 管腳操作 結束
69 //--------------------------------------
70  
71  
72 //++++++++++++++++++++++++++++++++++++++
73 // 函數聲明 開始
74 //++++++++++++++++++++++++++++++++++++++
75 extern void LCD12864_CheckBusy(void);
76 extern void Lcd12864_WrCmd(alt_u8 cmd);
77 extern void Lcd12864_WrData(alt_u8 data);
78 extern void Lcd12864_Init(void);
79 extern void Lcd12864_WrChar(alt_u8 row, alt_u8 col, alt_u8 *pCN, alt_u8 n);
80 //--------------------------------------
81 // 函數聲明 結束
82 //--------------------------------------
83  
84  
85 #endif /* __Amy_S_LCD12864_H__ */</io.h>
2.1.2 一些說明

最後麵的那個</io.h>是發布博客的時候帶出來的,不屬於頭文件。

從28行到37行,是根據SOPC Builder設置編寫的lcd12864的基地址,需要system.h的支持。注:system.h就是和SOPC Builder設置一一對應的;當在NII中建立工程時,system.h就根據sopcinfo(Nios II  9.1 Software Build Tools for Eclipse使用,不是Nios II 9.1 IDE)文件自動生產。

第40行到第53行,是自己編寫的一些宏,這個叫Register Map(寄存器映射),以前都是單獨放在一個頭文件裏(如xxx_regs.h)。由於NII 9.1貌似不支持HAL的自動初始化(我研究的結果是不行,不知道Altera公司有沒有相關的變動聲明),因此就沒有向8.1那樣書寫HAL。注意,0、1~3是OFFSET(偏移地址),請參考HDL代碼編寫。

從56行到69行,是一些管腳操作的宏,這樣寫,主要是方便移植。大家也可以不寫寄存器映射,直接寫管腳操作的宏也行,注意替換喲。

實際上大家也可以使用ARM方式的寄存器訪問方式,譬如

1 #define CS  *(volatile unsigned *) CS_BASE  // 片選信號 --低有效

這種貌似更好操作。由於我沒有深入研究這種寄存器訪問方式,這裏就不多說了。

下麵的幾行和各種MCU大同小異。

2.2 C源文件

2.2.1 Amy_S_lcd12864.c
01 /*-----版權聲明-----
02  *     艾米電子工作室——讓開發變得更簡單
03  *     網站:https://www.amy-studio.com
04  *     淘寶:https://amy-studio.taobao.com
05  *     QQ(郵箱):amy-studio@qq.com
06  *-----文件信息-----
07  *     文件名稱:Amy_S_lcd12864.c
08  *     最後修改日期:3.20, 2009
09  *     描述:Lcd12864驅動源文件
10  *------------------
11  *     創建者:張亞峰
12  *     創建日期:3.20, 2009
13  *     版本:1.0
14  *     描述:原始版本
15  *------------------
16  *     修改者:
17  *     修改日期:
18  *     版本:
19  *     描述:
20  *-------------------
21  */
22  
23 #include "Amy_S_lcd12864.h"
24 #include "alt_types.h"
25 #include "unistd.h"
26  
27 void LCD12864_CheckBusy(void)
28 {
29   CLR_RS;                               // 指令
30   SET_RW;                               // 讀
31   SET_E;
32   while((RD_DATA&0x80) == 0x80);        // 檢測busy flag
33   CLR_E;
34   usleep(72);                           // 72us
35 }
36  
37 void Lcd12864_WrCmd(alt_u8 cmd)
38 {
39   LCD12864_CheckBusy();
40   CLR_RS;                               // 指令
41   CLR_RW;                               // 寫
42   SET_E;
43   WR_DATA(cmd);
44   CLR_E;
45   usleep(72);                           // 72us
46 }
47  
48 void Lcd12864_WrData(alt_u8 data)
49 {
50   LCD12864_CheckBusy();
51   SET_RS;                               // 數據
52   CLR_RW;                               // 寫
53   SET_E;
54   WR_DATA(data);
55   CLR_E;
56   usleep(72);                           // 72us
57 }
58  
59 void Lcd12864_Init(void)
60 {
61   usleep(40*1000);
62   Lcd12864_WrCmd(0x30);                 // 8bit
63   usleep(100);
64   Lcd12864_WrCmd(0x30);                 // basic function
65   usleep(37);
66   Lcd12864_WrCmd(0x0F);                 // 整體顯示開 遊標開 反白
67   usleep(100);
68   Lcd12864_WrCmd(0x10);                 // 遊標左移
69   usleep(100);
70   Lcd12864_WrCmd(0x01);
71   usleep(10*1000);
72   Lcd12864_WrCmd(0x06);                 // 畫麵整體右移
73 }
74  
75 void Lcd12864_WrChar(alt_u8 row, alt_u8 col, alt_u8 *pCN, alt_u8 n)
76 {
77   alt_u8 i, addr;
78   row &= 0x03;                          // row < 4
79   col &= 0x07;                          // col < 8
80   switch(row)
81   {
82     case 0: addr = 0x80; break;
83     case 1: addr = 0x90; break;
84     case 2: addr = 0x88; break;
85     case 3: addr = 0x98; break;
86   }
87   addr += col;
88   Lcd12864_WrCmd(addr);
89   for(i=0; i<2*n; i++)
90   {
91     Lcd12864_WrData(pCN[i]);            // 寫字符數據
92   }
93 }
2.2.2 一些說明

嗬嗬,這個就不說明了,大家自己看。

最後更新:2017-04-04 02:25:10

  上一篇:go 今天的你,配不上昨天的夢想
  下一篇:go 人世間就是這樣!