nios ii 之 LCD 1602
来源:互联网 发布:hp打印机端口设置 编辑:程序博客网 时间:2024/05/01 13:45
大家好!这是本人第一篇博文,写得不好,还请多多指教。
初学nios,发现它多少有点和51单片机不一样。自己也摸爬打滚,连碰带撞,走了不少弯路,所以希望可以分享自己的经验,让初学者少走些弯路,也作为交流手段,望前辈们指教。
LCD 1602是一款较常见的液晶显示屏,可以显示16*2个字符(不能显示汉字)。网上为单片机写的程序较多,为FPGA写的少。在此我提供自己写的基于nios ii的程序,所用的板子是DE0 Nano板,采用用IO口模拟时序。
一、硬件设计
1602有5v的和3.3v的,我的DE0 Nano板IO口是3.3v的。我手上有5v的1602,本来一直很担心3.3v的IO口驱动不了1602,还怕把自己的板子烧了。经过多次尝试,我发现这是可以实现的。因为担心烧坏引脚我在LCD_RS,LCD_RW,LCD_E,LCD_DB0-7和3.3Vio口之间串了一个100欧姆的电阻。电阻的大小并不是固定的,几百差不多,因为电阻不够,其实有部分电阻我是用50欧姆的。
在sopc中加入各个模块,其中要注意加入的8位宽的LCD_DATA是bidir类型的。
二、软件设计
1.时序约束
1602的时序并不复杂,直接用网上的单片机程序改编也可以,但要注意,不难是会出问题的。因为单片机的指令周期大都在us级,1602的时序约束是ns级的,所以大部分单片机程序都不需要太多延时。但对于FPGA这种高速器件,这些时序参数要格外注意。我之前一直没有成功就是因为没有注意到这一点。像对于DE0 Nano板tSP1就需要延时,否者不能满足,而单片机程序很多都不需要。tPW,tC也要去延时,其他的时间都可以直接满足了。
2.初始化
1602LCD的一般初始化(复位)过程
延时15mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
以后每次写指令、读/写数据操作均需要检测忙信号
写指令38H:显示模式设置
写指令08H:显示关闭
写指令01H:显示清屏
写指令06H:显示光标移动设置
写指令0CH:显示开及光标设置
初始化函数:
void InitLcd(){//clear the LCD_EIOWR_ALTERA_AVALON_PIO_DATA(LCD_E_BASE, 0x00);usleep(150000);//write third time 0x38 to LCD 1602,do not check busy,third time to ensure initial succeedLcdWrite(0x38,CMD);usleep(5000);LcdWrite(0x38,CMD);usleep(5000);LcdWrite(0x38,CMD);usleep(5000);//write 0x38 once more,set display mode(16*2,5*7,8bit)LcdWriteCmd(0x38);//close screenLcdWriteCmd(0x08);//clear screenLcdWriteCmd(0x01);//set cursor mode(N=1)LcdWriteCmd(0x06);//open the screenLcdWriteCmd(0x0c);}3、写函数
void LcdWrite(alt_u8 data,alt_u8 RS){//set LCD_DATA on write stateIOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE, 0xff);//set 1 to LCD_RS for writing data,0 for writing commandIOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, RS);//set 0 to LCD_RW for writing patternIOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_BASE, WRITE);//write dataIOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, data);//set LCD_Eusleep(1);IOWR_ALTERA_AVALON_PIO_DATA(LCD_E_BASE, 0x01);//clear LCD_Eusleep(3);IOWR_ALTERA_AVALON_PIO_DATA(LCD_E_BASE, 0x00);}4、读函数
alt_u8 LcdRead(alt_u8 RS){alt_u8 read_data;//set LCD_DATA on read stateIOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE, 0x00);//set 1 to LCD_RS for reading data,0 for reading commandIOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, RS);//set 1 to LCD_RW for reading patternIOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_BASE, READ);//set LCD_Eusleep(1);IOWR_ALTERA_AVALON_PIO_DATA(LCD_E_BASE, 0x01);//read datausleep(1);read_data = IORD_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE);//clear LCD_Eusleep(2);IOWR_ALTERA_AVALON_PIO_DATA(LCD_E_BASE, 0x00);return read_data;}5、写命令
void LcdCheckBusy(){while(LcdRead(CMD) & 0x80);}void LcdWriteCmd(alt_u8 command){LcdCheckBusy();LcdWrite(command,CMD);}6、写数据
void LcdWriteData(alt_u8 data){LcdCheckBusy();LcdWrite(data,DATA);}7、显示函数
void LocateXY(alt_u8 x,alt_u8 y){x &= 0x0f;//ensure the x between 0 and 31y &= 0x01;//ensure that the y is 1 or 0if(y){LcdCheckBusy();LcdWriteCmd(x | 0x40 | 0x80);}else{LcdCheckBusy();LcdWriteCmd(x | 0x80);}}void PutChar(char value,alt_u8 x,alt_u8 y){LocateXY(x,y);LcdWriteData(value);}alt_u8 PutStr(char *value,alt_u8 x,alt_u8 y){alt_u8 len = 0,i;while(value[len] > 31) len ++;for(i = 0;i < len;i ++){PutChar(value[i],x ++,y);if(x == 16)//Cyclic display{x = 0;y ^= 0x01;}}return len;//return the length of the string}8、头文件
#ifndef LCD_1602_SOLUTION_H_#define LCD_1602_SOLUTION_H_#define DATA 1#define CMD 0#define READ1#define WRITE0#include<system.h>#include<altera_avalon_pio_regs.h>#include<alt_types.h>#include<unistd.h>//check if the LCD 1602 is in busyvoid LcdCheckBusy();//set the beginning coordinate of the wordvoid LocateXY(alt_u8 x,alt_u8 y);//LCD writing function,the argument RS decide a data or a command to be writtenvoid LcdWrite(alt_u8 data,alt_u8 RS);//LCD reading function,the argument RS decide a data or a command to be readalt_u8 LcdRead(alt_u8 RS);//write a command to LCD 1602void LcdWriteCmd(alt_u8 command);//write a byte of data to LCD 1602void LcdWriteData(alt_u8 data);//read a command from LCD 1602alt_u8 LcdReadCmd();//read a data from LCD 1602alt_u8 LcdReadData();/*use the following function to initial the LCD 1602 and print words *///initial the LCD 1602void InitLcd();//print a charvoid PutChar(char value,alt_u8 x,alt_u8 y);//print a stringalt_u8 PutStr(char *value,alt_u8 x,alt_u8 y);//clear screenvoid LcdClearScreen();#endif /* LCD_1602_SOLUTION_H_ */9、主函数
#include"lcd_1602_solution.h"int main(){InitLcd();
PutStr("hello",0,1);PutChar('a',0,0);while(1);return 0;}因为整个工程太大,不可能在这里都说好,所以我把整个做好的工程放在我的CSDN资源里,大家可以免费下载 http://download.csdn.net/detail/ming1006/4036416
点击打开链接
- nios ii 之 LCD 1602
- nios ii之LCD 1602四线制
- nios ii 之 使用自带LCD 16207驱动1602的问题
- Nios II 开发之flash
- 初探NIOS ii 之hello_world
- 基于NIOS II嵌入式处理器实现LCD的控制
- Nios Ii葵花宝典-Nios II嵌入式系统设计教程 之Fedora 13的安装
- nios ii之Micro SD卡(TF卡)spi
- nios ii之流水灯两点注意(QSYS版)
- Nios II设备管理分析
- nios II参考网站
- NIOS II 常见问题总结
- NIOS II 常见问题总结
- Nios II 简介
- NIOS II 开发常见问题
- NIOS II 开发常见问题
- NIOS II 常见问题总结
- NIOS II 问题集锦
- 查看磁带内容 q cotent 和 request 请求执行
- Mastering Search Analytics [startup] [incomplete]
- android中 检查 网络连接状态的变化,无网络时跳转到设置界面
- 网站作业布置批改功能重写基本完成,记录一下
- jQuery 对象和 DOM 对象的相互转换
- nios ii 之 LCD 1602
- 【數列遞推】爭奪基友
- 测试经理能力要求
- 做完一个小任务的总结
- 由于嵌入式项目版本较多不好管理,于是笔者写了一个“版本小助手”,和大家分享一下,附上程序
- Windows程序设计__孙鑫C++Lesson10《图形绘制及各类对话框》
- Ultimate Pentesting VM
- where 1=1用处
- 多线程与WPF 4.5