#include "LCD12864.h"
//********************************************************************
//LCD12864 忙 信号检测,读地址AC
//********************************************************************
void LCD12864_GPIO_INIT()
{
/*打开复用时钟,配置PA15,PB3,PB4做普通IO使用*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开复用时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
// AFIO->MAPR &= 0XF7FFFFFF;
// AFIO->MAPR |= 0X02000000;
My_GPIO_Init(GPIO_RS,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_RW,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_E,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_BK,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D0,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D1,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D2,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D3,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D4,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D5,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D6,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D7,GPIO_Mode_Out_PP);
}
//;配置成输入模式
void LCD12864_IO_OUT()
{
My_GPIO_Init(GPIO_D0,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D1,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D2,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D3,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D4,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D5,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D6,GPIO_Mode_Out_PP);
My_GPIO_Init(GPIO_D7,GPIO_Mode_Out_PP);
// GPIOC->CRH&=0XF0FFFFFF;
// GPIOC->CRH|=0x07000000;
// GPIOA->CRL&=0XF0000000;
// GPIOA->CRL|=0X07777777;//推挽输出
}
//向12864中的数据位传入数据
void LCD12864_wData(unsigned char dat)
{
LCD12864_IO_OUT();
if((dat&0x01))Set_D0();
else Clr_D0();
if((dat&0x02))Set_D1();
else Clr_D1();
if((dat&0x04)) Set_D2();
else Clr_D2();
if((dat&0x08))Set_D3();
else Clr_D3();
if((dat&0x10)) Set_D4();
else Clr_D4();
if((dat&0x20))Set_D5();
else Clr_D5();
if((dat&0x40))Set_D6();
else Clr_D6();
if((dat&0x80)) Set_D7();
else Clr_D7();
}
//;配置成输入模式
void LCD12864_IO_IN()
{
My_GPIO_Init(GPIO_D0,GPIO_Mode_IPD);//下拉输入
My_GPIO_Init(GPIO_D1,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D2,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D3,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D4,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D5,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D6,GPIO_Mode_IPD);
My_GPIO_Init(GPIO_D7,GPIO_Mode_IPD);
// //IO方向设置
// GPIOC->CRH&=0XF0FFFFFF;
// GPIOC->CRH|=0X04000000;
// GPIOA->CRL&=0XF0000000;
// GPIOA->CRL|=0X04444444; //浮空输入
}
//读数据位的数据
unsigned char LCD12864_rDat()
{
unsigned char dat = 0;
LCD12864_IO_IN();
if(Read_D0()) dat |= 0x01;
if(Read_D1()) dat |= 0x02;
if(Read_D2()) dat |= 0x04;
if(Read_D3()) dat |= 0x08;
if(Read_D4()) dat |= 0x10;
if(Read_D5()) dat |= 0x20;
if(Read_D6()) dat |= 0x40;
if(Read_D7()) dat |= 0x80;
return dat;
}
unsigned char LCD_readWait()
{
My_GPIO_Init(GPIO_D7,GPIO_Mode_IN_FLOATING);
return(Read_D7());
// GPIOA->CRL&=0XF0000000;GPIOA->CRL|=0X07777777; //浮空输入
// return(GPIOA->IDR & GPIO_Pin_3);
}
unsigned char LCD12864_WaitIdle()
{
unsigned char ac;
LCD12864_wData(0xff);
Clr_RS();
Set_RW();
Set_E();
// lcd_delay_us(1);
while(LCD_readWait()==1) /*等待BF 不为1*/
{};
ac = LCD12864_rDat();
Clr_E();
return (ac|0x80);
}
//********************************************************************
//检测忙信号写入命令字 com_da 为待写入的命令字
//********************************************************************
void LCD12864_COM_Write( unsigned char com_da)
{
LCD12864_WaitIdle();
Clr_RS();
Clr_RW();
Set_E();
//lcd_delay_us(1);
LCD12864_wData(com_da);
//lcd_delay_us(1);
Clr_E();
}
//********************************************************************
//LCD12864 从地址中读数据
//********************************************************************
unsigned char LCD12864_ReadOneDat()
{
unsigned char dat;
LCD12864_WaitIdle();
LCD12864_wData(0xff);
Set_RS();
Set_RW();
Set_E();
//lcd_delay_us(10);
dat = LCD12864_rDat();
Clr_E();
return (dat);
}
u16 LCD12864_ReadDAT(unsigned char addr)
{
u16 dat;
LCD12864_COM_Write(addr);
LCD12864_ReadOneDat();
dat = (u16)LCD12864_ReadOneDat()<<8;
dat |= LCD12864_ReadOneDat();
return (dat);
}
//********************************************************************
//不检测忙信号写入命令字 com_da 为待写入的命令字
//********************************************************************
void LCD12864_NoWaitIdle_COM_Write(unsigned char com_da)
{
Clr_RS();
Clr_RW();
Set_E();
//lcd_delay_us(1);
LCD12864_wData(com_da);
// lcd_delay_us(1);
Clr_E();
}
//********************************************************************
//数据写入 da 为待写入的8位数据
//********************************************************************
void LCD12864_Data_Write(unsigned char da)
{
LCD12864_WaitIdle(); /*检测忙信号*/
Set_RS();
Clr_RW();
Set_E();
//lcd_delay_us(1);
LCD12864_wData(da);
//lcd_delay_us(1);
Clr_E();
}
//*************************************************************************************
//写连续字符函数
//*************************************************************************************
void LCD12864_write_word(unsigned char *s)
{
for(;*s!=0;s++)
{
LCD12864_Data_Write(*s);
}
}
//********************************************************************
//LCD12864初始化
//********************************************************************
void LCD12864_Init()
{
lcd_delay_ms(10); /*适当延时待LCD自动复位完成*/
LCD12864_GPIO_INIT();
LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
lcd_delay_ms(1);
LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
lcd_delay_ms(1);
LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/
lcd_delay_ms(1);
LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/
lcd_delay_ms(3);
LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/
lcd_delay_ms(1);
// delay_init();
// LCD12864_GPIO_INIT();
// delay_ms(120); /*适当延时待LCD自动复位完成*/
// LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
// delay_ms(10);
// LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
// delay_ms(10);
// LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/
// delay_ms(10);
// LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/
// delay_ms(30);
// LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/
// delay_ms(30);
}
void LCD12864_Setposition(unsigned char xpos,unsigned char ypos)
{
unsigned char xy_pos;
if((xpos>=8)||(ypos>=4) ) return; /*X位置超出显示范围退出*/
if(ypos==0) xy_pos = 0x80 + xpos;
else if(ypos==1) xy_pos = 0x90 + xpos; /*计算转换地址*/
else if(ypos==2) xy_pos = 0x88 + xpos;
else if(ypos==3) xy_pos = 0x98 + xpos;
else if(ypos==4) xy_pos = LINE0_N + xpos; /*计算转换地址*/
else if(ypos==5) xy_pos = LINE1_N + xpos;
else if(ypos==6) xy_pos = LINE2_N + xpos;
else if(ypos==7) xy_pos = LINE3_N + xpos;
LCD12864_COM_Write(0x30);
LCD12864_COM_Write(xy_pos); /*写地址*/
}
void LCD12864_String(unsigned char x,unsigned char y,unsigned char* str)
{
//LCD12864_COM_Write(0x30);
LCD12864_Setposition(x,y);
// lcd_delay_ms(1);
LCD12864_write_word(str);
}
//