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 | * 网站:http://www.amy-studio.com |
04 | * 淘宝:http://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 | * 网站:http://www.amy-studio.com |
04 | * 淘宝:http://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 一些说明
呵呵,这个就不说明了,大家自己看。