学习NUC120助学板好多天了,把LCD驱动 移植到NUC120助学板了
用杜邦线把NUC120助学板LCD接口和T6963C连接,
源程序是网上找的 ,端口部分修改了,
具体看下面端口定义。
#include "LCD.H"
#include "biaoge.h"
#define LCD_WR E_GPC,14 /* PC14 = V0 */
#define LCD_RD E_GPC,15 /* PC15 = RS */
#define LCD_CE E_GPC, 6 /* PC6 = RW */
#define LCD_CD E_GPC, 7 /* PD7 = EN */
#define yanshi 3//延时常量
//#define POWER_LCD1602 DrvGPIO_ClrBit(LCD_PW) //模块供电低电平有效
#define CLR_WR DrvGPIO_ClrBit(LCD_WR) //数据线强制拉低
#define SET_WR DrvGPIO_SetBit(LCD_WR) //数据线强制拉高,上拉
#define CLR_RD DrvGPIO_ClrBit(LCD_RD) //数据线强制拉低
#define SET_RD DrvGPIO_SetBit(LCD_RD) //数据线强制拉高,上拉
#define CLR_CE DrvGPIO_ClrBit(LCD_CE) //数据线强制拉低
#define SET_CE DrvGPIO_SetBit(LCD_CE) //数据线强制拉高,上拉
#define CLR_CD DrvGPIO_ClrBit(LCD_CD) //数据线强制拉低
#define SET_CD DrvGPIO_SetBit(LCD_CD) //数据线强制拉高,上拉
#define LCD_IO0 E_GPA, 2 /* PD0 = I/O0 */
#define LCD_IO1 E_GPA, 3 /* PD1 = I/O1 */
#define LCD_IO2 E_GPA, 4 /* PD2 = I/O2 */
#define LCD_IO3 E_GPA, 5 /* PD3 = I/O3 */
#define LCD_IO4 E_GPA, 6 /* PB4 = I/O4 */
#define LCD_IO5 E_GPA, 7 /* PB5 = I/O5 */
#define LCD_IO6 E_GPA, 8 /* PB6 = I/O6 */
#define LCD_IO7 E_GPA, 9 /* PB7 = I/O7 */
#define LCD_Data_Port GPIOA //LCD BUS
/*************************************************
* 函数说明:初始化接口引脚 *
* 输出参数:
**************************************************/
void GPIO_LCD_Init(void)
{
DrvGPIO_Open(LCD_IO0, E_IO_QUASI); //DB0~7带上拉的准双向接口
DrvGPIO_Open(LCD_IO1, E_IO_QUASI);
DrvGPIO_Open(LCD_IO2, E_IO_QUASI);
DrvGPIO_Open(LCD_IO3, E_IO_QUASI);
DrvGPIO_Open(LCD_IO4, E_IO_QUASI);
DrvGPIO_Open(LCD_IO5, E_IO_QUASI);
DrvGPIO_Open(LCD_IO6, E_IO_QUASI);
DrvGPIO_Open(LCD_IO7, E_IO_QUASI);
DrvGPIO_Open(LCD_WR, E_IO_QUASI);
DrvGPIO_Open(LCD_RD, E_IO_QUASI); //
DrvGPIO_Open(LCD_CE, E_IO_QUASI); //
DrvGPIO_Open(LCD_CD, E_IO_QUASI); //
}
/******* 延时子程序***********/
///#pragma interrupt_level 1
void delay(uint i)
{
while(i--);//CLRWDT();
}
//-----------LCD子程序---------------------
//----读取LCD状态字--------------------
uchar read_data(void)
{
uchar i;
CLR_CE; //LCD_Data_Port->DMASK=0xFC03;
SET_CD ;
delay(yanshi);
CLR_RD ;
delay(yanshi);
i=LCD_Data_Port->PIN >>2;
delay(yanshi);
SET_RD ;
return i;
}
//-----判断指令(数据)读写状态--------
void st01(void)
{uchar i;
for(i=10;i>0;i--)
{
if((read_data()&0x03)==3)
break;
}
}
//----------判断数据自动读状态------------
void st2(void)
{uchar i;
for(i=10;i>0;i--)
{
if((read_data()&0x04)==4)
break;
}
}
//---------判断数据自动写状态-------------
void st3(void)
{uchar i;
for(i=10;i>0;i--)
{
if((read_data()&0x08)==8)
break;
}
}
//----------数据写入函数------------------
void write_data(uchar data_d)
{
st01();
CLR_CD ;
delay(yanshi);
LCD_Data_Port->DOUT = (data_d<<2) ;
delay(yanshi);
CLR_WR ;
delay(yanshi);
SET_WR;
}
//-------------指令写入函数-----------------
void write_contr(uchar data_c)
{
st01();
SET_CD ;
delay(yanshi);
LCD_Data_Port->DOUT =(data_c<<2) ; // (LCD_Data_Port->PIN &0XFC03)|
delay(yanshi);
CLR_WR ;
delay(yanshi);
SET_WR ;
}
//-------------数据自动写入函数--------------
void writeauto(uchar onedata)
{
st3();
CLR_CD ;
delay(yanshi);
LCD_Data_Port->DOUT = (onedata<<2);//&0x3fc
delay(yanshi);
CLR_WR ;
delay(yanshi);
SET_WR ;
}
//---------双字节参数 指令写入----------------------------
void lcd_double_operator(uchar data1,uchar data2,uchar com)
{
write_data(data1); ///-参数1-/
write_data(data2); ///-参数2-/
write_contr(com); ///-指令-//
}
//----------单字节参数 指令写入---------------------
void lcd_single_operator(uchar data1,uchar com)
{
write_data(data1); ////-参数1-/
write_contr(com); ////-指令-/
}
//------------无参数 指令写入----------------------
void lcd_none_operator(uchar com)
{
write_contr(com); ///-指令-/
}
//------------内置T6963C控制器液晶初始化函数---------
void lcd_ini(void)
{ //双字节参数 指令写入
lcd_double_operator(0x00,0x00,0x40);//文本显示区域首地址0x0000
lcd_double_operator(0x1e,0x00,0x41);//文本区宽度(字节数/行)30
lcd_double_operator(0x00,0x08,0x42);//图形区首址 0x800
lcd_double_operator(0x1e,0x00,0x43);//图形区宽度(字节数/行)30
lcd_none_operator(0xa0); //A7 A0无参数 指令写入 光标形状选择
lcd_none_operator(0x81); //81 80 82//--显示方式设置逻辑"或"合成//
lcd_none_operator(0x9c);//9c 9F//--显示开关设置 开文本和图形显示。光标显示闪烁//
}
//---------------建立CGRAM子程序-------------------------------------------
void creat_cgram(uchar count,uchar a)// creat_cgram(32,1); //建立CGRAM子程序//插除 公司名称
{
uint i,x;
x=count<<2; //*4
x=x<<3;//*8
lcd_double_operator(0x3,0x00,0x22); //CGRAM偏置地址设置
lcd_double_operator(0x00,0x1c,0x24); //地址指针位置
for (i=0;i<x;i++)
{//CLRWDT();
if(!a)
lcd_single_operator(font[i] ,0xc0); //单字节参数 指令写入
}
}
//-----------------清除屏幕(清所有8K存储空间)------------------------
void lcd_clear(void)
{
uint i;
lcd_double_operator(0x00,0x00,0x24); //首地址//设置显示存储器首地址
lcd_none_operator(0xb0); //设置自动写状态
for(i=8200;i>0;i--)
{writeauto(0x00 );} //CLRWDT();
//无参数 指令写入
lcd_none_operator(0xb2); //关闭自动写状态
}
//---------------------清除屏幕(清0x800存储空间)----------------------------
void lcd_clear1(void)
{
uint i;
lcd_double_operator(0x00,0x08,0x24); //首地址//设置显示存储器首地址
lcd_none_operator(0xb0); //设置自动写状态
for(i=3840;i>0;i--)//3683 //15*8*32
{writeauto(0x00 );} //CLRWDT();
//无参数 指令写入
lcd_none_operator(0xb2); //关闭自动写状态
}
/********************************************************
西文字符,汉字,点阵显示函数
********************************************************/
//********西文字符写入函数******
void write_english(uchar cursor_x,uchar cursor_y,uchar c_code,uchar attr)
{
uint x;
//if(diaodian_bit) return;
x=cursor_y*30;
x=x+cursor_x; //y=cursor_y*30+cursor_x
lcd_double_operator((uchar)(x),(uchar)(x>>8),0x24);
lcd_single_operator(c_code,0xc4);
lcd_double_operator((x&0x00ff),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
}
//********汉字写入函数****16x16******
void write_chinese(uchar cursor_x,uchar cursor_y,uchar ct_code,uchar attr)
{
uint x;
// if(diaodian_bit) return;
x=cursor_y*30;
x=x+cursor_x; //y=cursor_y*30+cursor_x
lcd_double_operator((uchar)(x),(x>>8),0x24);
lcd_single_operator(ct_code,0xc4);
lcd_double_operator((uchar)(x),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
lcd_double_operator(((uchar)(x)+1),(x>>8),0x24);
lcd_single_operator(ct_code+2,0xc4);
lcd_double_operator(((uchar)(x)+1),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
x+=30;
lcd_double_operator((uchar)(x),(x>>8),0x24);
lcd_single_operator(ct_code+1,0xc4);
lcd_double_operator((uchar)(x),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
lcd_double_operator(((uchar)(x)+1),(x>>8),0x24);
lcd_single_operator(ct_code+3,0xc4);
lcd_double_operator(((uchar)(x)+1),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
}
//*******************汉字写入(图形方式)函数******************************************/
//汉字写入函数
//x_hz:0~29; y_hz:0~127
void writehz(uchar x_hz,uchar y_hz,uchar code_hz)
{
uchar i_hz;
uint address,addr_hz;
//if(diaodian_bit) return;
address=y_hz*30+x_hz+0x0800; //计算显示存储器地址
addr_hz=code_hz<<5;//*32; //计算汉字字模地址(cctab的下标)
for(i_hz=0;i_hz<16;i_hz++) //计数值16
{
lcd_double_operator((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
lcd_single_operator(font[addr_hz],0xc0); //写入汉字字模左部
lcd_single_operator((font[16+addr_hz++]),0xc0); //写入汉字字模右部
address+=30; //修改显示存储器地址,显示下一列(共16列)
}
}
//************************字写入函数16x8*********************************************
void write_chinese8(uchar cursor_x,uchar cursor_y,uchar ct_code,uchar attr)
{
uint x;
// if(diaodian_bit) return;
x=cursor_y*30;
x=x+cursor_x; //y=cursor_y*30+cursor_x
lcd_double_operator((uchar)(x),(x>>8),0x24);
lcd_single_operator(ct_code,0xc4);
lcd_double_operator((uchar)(x),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
x+=30;
lcd_double_operator((uchar)(x),(x>>8),0x24);
lcd_single_operator(ct_code+1,0xc4);
lcd_double_operator((uchar)(x),(x>>8)+0x0c,0x24);
lcd_single_operator(attr,0xc4);
}
这里 要 感谢 菜农的鼓励和支持,感谢John Lee老师的帮助。
请大家拍砖。不好地方狠狠的拍。 |