nios ii 之 使用自带LCD 16207驱动1602的问题

来源:互联网 发布:建筑网络计划图 编辑:程序博客网 时间:2024/05/21 11:01

上次成功用FPGA的PIO口模拟时序成功操控1602,今天就又试了下用nios ii自带的LCD 16207核驱动1602.网上关于这方面的程序大概有三种,我参考了它们都没成功。其实有两种方法给出代码的作者都自己说没有调试成功,其他说可以的大概只是转载,并没有亲身试验吧。

这两种方法都是直接用了LCD 1607核驱动1602,再用file文件操作方式进行显示,或设置STDOUT为lcd直接用printf函数显示。事实上,这两种方法都是行不通的,因为nios ii自带的LCD 16207核并不能直接驱动1602,它的初始化函数并不适合1602,所以这两种方法都不行。

第三种方法是用了LCD 16207核,但是自己写初始化函数和其他驱动函数。这种方法我也觉得理论上可以成功,但是至今没有成功。这里我引用网上写得较好的一个程序:

#include<system.h>#include<altera_avalon_lcd_16207_regs.h>#include<alt_types.h>alt_u8 lcd_string1[] = "HB_XFU__ELC__LAB";alt_u8 lcd_string2[] = "2009 xk";void check_busy()                                             //读液晶的忙标志位并检测{    alt_u8 status;    do    {        status="IORD"_ALTERA_AVALON_LCD_16207_STATUS(LCD_BASE);    }while(status&0x80);}void lcd_init()                                                 //液晶1602初始化{    IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0x38);       //功能设置    check_busy();    IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0x01);       //清屏    check_busy();    IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0x06);       //Y地址自动加1模式    check_busy();    IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0x0c);       //显示开,不显示光标}       void lcd_prints(alt_u8 *string)                                 //打印字符串{    while(*string!='\0')    {              check_busy();            IOWR_ALTERA_AVALON_LCD_16207_DATA(LCD_BASE, *string);               string++;               } }void select_xy(alt_u8 x,alt_u8 y)                               //选择屏幕坐标,x=0为第1行,x=1为第2行{                                                               //y=0~15,分别对应第1列到第16列    check_busy();    if(x%2==0)    {            IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0x80+y);       }    else    {           IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_BASE, 0xc0+y);    }}   int main (void) __attribute__ ((weak, alias ("alt_main")));     //将程序的入口改为alt_main(),可以使                                                                //很多驱动不会加载,可以大大减小代码长度void alt_main()                                                 {    lcd_init();                                     select_xy(0,0);    lcd_prints(lcd_string1);            select_xy(1,7);    lcd_prints(lcd_string2);}【本文来自】: IT在线(http://www.itolhome.cn)转载请注明出处! 【原文地址】:http://www.itolhome.cn/thread-9322-1-1.html
上面的程序还有些地方修改后可以更好,在初始化是最好先延时15ms以上再写三次不带忙检测的0x38指令,每次指令之间延时5ms,这是保证初始化成功,代码如下:
void lcd_init()                                                 //液晶1602初始化{usleep(400000);IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x38);usleep(5000);IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x38);usleep(5000);IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x38);usleep(5000);check_busy();        IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x38);       //功能设置        check_busy();IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x08);       //关屏        check_busy();        IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x01);       //清屏        check_busy();        IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x06);       //Y地址自动加1模式        check_busy();        IOWR_ALTERA_AVALON_LCD_16207_COMMAND(LCD_0_BASE, 0x0c);       //显示开,不显示光标}
以上方法照理应该可以,有作者确实也说亲试成功,但自己调了半天也没成功。我尝试着在代码间加延时,还采用了多次重复写指令,写数据的方法,发现偶尔可以出现些乱码,有时可以出现我写的字符,但坐标不对,其他坐标上出现了乱码,不知道为什么?后来我又用了逻辑分析仪signaltap检测了下,发现LCD 16207核的接口LCD_E一直为低电平,我不知道是为什么。难道自带的LCD 16207核的LCD_E本来就是一个低电平吗?如果是这样,那这个方法应该是行不通的啊!或者是因为其他原因导致的?我会继续测试,希望有经验的大虾们可以指点指点啊!

原创粉丝点击