LCD1602是一个很常用的LCD显示屏,搜了下网上居然没有nios上的实现程序,不知是专家觉得简单不想去弄吧,都是一些彩色的LCD液晶屏的程序,看得头晕了。。。也没有相应的面板,于是作为一个菜鸟就先用板子自带的LCD1602先编个小程序跑起来吧。O(∩_∩)O~
和我们的流水灯一样,配置上面的硬件结构
下面是程序:
#include "system.h" #include <stdio.h> #include "altera_avalon_pio_regs.h" #include "alt_types.h"
void delay(alt_u8 i) { volatile int k; //while(k<100*i) k++; while(k<50*i) k++; }
void delay_my(void) { alt_u8 i=0xff; while((i&0x80)!=0) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE,0); //CLR RS IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_BASE,1); //SETB RW IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,0); //CLR E
delay(1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,1); //SETB E
//D7~D0为双向口,需要先设置为输入口 IOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE,0x00); //设置为输入 i=IORD_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE); //JB P1.7,DELAY ;如果P1.7为高电平表示忙就循环等待 } IOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE,0xff); //恢复为输出 }
void enable(void) { //ENABLE IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE,0); //CLR RS ;写入控制命令的子程序 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_BASE,0); //CLR RW IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,0); //CLR E delay_my(); //ACALL DELAY IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,1); //SETB E }
void inintial_LCD(void) { IOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE,0xff);//双向口设置为输出 //00000001,清屏并光标复位 IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,0x01); enable(); //00111000,设置显示模式:8位2行5x7点阵 IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,0x38); enable(); //00001111,显示器开、光标开、光标允许闪烁 IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,0x0f); enable(); //00000110,文字不动,光标自动右移 IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,0x06); enable(); }
void dis_address(alt_u8 i) { i=i+0x80; //地址转化,加上80H IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,i); enable(); }
void dis_code(alt_u8 i) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE,i); }
void display(void) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE,1); //SETB RS ;RS=1 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_BASE,0); //CLR RW ;RW=0 ;准备写入数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,0); //CLR E ;E=0 ;执行显示命令 delay_my(); //ACALL DELAY IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_BASE,1); //SETB E ;E=1 ;显示完成,程序停车 }
int main() //alt_main() //这里也可以用它,有些不同 {
inintial_LCD();
dis_address(0x00); //写入显示起始地址 dis_code(0x4c); //写入字母A的代码 display(); //执行显示命令 dis_address(0x01); //写入显示起始地址 dis_code(0x43); //写入字母的代码 display(); //执行显示命令
return 0; } |
我是根据原来单片机的汇编程序改过来的,我觉得把单片机的程序移植到nios中是一种很好的思路,因为它们都是用C语言的,只需要改变延时的长度,基本上就没有问题了。
注意点:
双向PIO口的使用:
IOWR_ALTERA_AVALON_PIO_DIRECTION,设置方向,1出0入。
IOWR_ALTERA_AVALON_PIO_DATA,输出
IORD_ALTERA_AVALON_PIO_DATA,读入
上面的函数定义在altera_avalon_pio_regs.h中都有说明
#include "system.h"中有对于我们生成的硬件系统的说明,比如基址等
这里我卡住最久的地方是双向PIO口的使用,用了一天的时间才得以调通,呵呵,回头想想其实也没什么的,其实就是对新事物没有熟悉吧,熟悉了就都不怕了。