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

上次成功用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本来就是一个低电平吗?如果是这样,那这个方法应该是行不通的啊!或者是因为其他原因导致的?我会继续测试,希望有经验的大虾们可以指点指点啊!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值