集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1189|回复: 2

LCD12864 并口和串口通用程序

[复制链接]
fpga_feixiang 发表于 2020-1-17 22:36:13 | 显示全部楼层 |阅读模式
#if 0 //并口

/*****等待LCD空闲*****/
void WaitBusy(void)
{
     uint32_t i=500;
     while(i--);
}
void Lcd_WriteData(uint8_t dispdata)
{

           LCD_RS_1;
     LCD_RW_0;
     LCD_EN_1;
     WaitBusy();
       

               
        (dispdata&0x01) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_14): GPIO_ResetBits(GPIOE, GPIO_Pin_14);
        (dispdata&0x02) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_13): GPIO_ResetBits(GPIOE, GPIO_Pin_13);
        (dispdata&0x04) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_12): GPIO_ResetBits(GPIOE, GPIO_Pin_12);
        (dispdata&0x08) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_11): GPIO_ResetBits(GPIOE, GPIO_Pin_11);
        (dispdata&0x10) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_10): GPIO_ResetBits(GPIOE, GPIO_Pin_10);
        (dispdata&0x20) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_9 ): GPIO_ResetBits(GPIOE, GPIO_Pin_9 );
        (dispdata&0x40) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_8 ): GPIO_ResetBits(GPIOE, GPIO_Pin_8 );
        (dispdata&0x80) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_7 ): GPIO_ResetBits(GPIOE, GPIO_Pin_7 );
                                                       
          LCD_EN_0;
}

/*****写指令代码*****/
void Lcd_WriteCmd(uint8_t cmdcode)
{
       

         LCD_RS_0;
         LCD_RW_0;
         LCD_EN_1;
         WaitBusy();
        (cmdcode&0x01) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_14): GPIO_ResetBits(GPIOE, GPIO_Pin_14);
        (cmdcode&0x02) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_13): GPIO_ResetBits(GPIOE, GPIO_Pin_13);
        (cmdcode&0x04) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_12): GPIO_ResetBits(GPIOE, GPIO_Pin_12);
        (cmdcode&0x08) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_11): GPIO_ResetBits(GPIOE, GPIO_Pin_11);
        (cmdcode&0x10) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_10): GPIO_ResetBits(GPIOE, GPIO_Pin_10);
        (cmdcode&0x20) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_9 ): GPIO_ResetBits(GPIOE, GPIO_Pin_9 );
        (cmdcode&0x40) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_8 ): GPIO_ResetBits(GPIOE, GPIO_Pin_8 );
        (cmdcode&0x80) >0 ?        GPIO_SetBits(GPIOE, GPIO_Pin_7 ): GPIO_ResetBits(GPIOE, GPIO_Pin_7 );
               
    LCD_EN_0;
}
void LCD_Clean(void)
{
         Lcd_WriteCmd(0x01);
   delayms(20);
}

/*****写数据*****/


/*****初始化LCD*****/
void Lcd_Init(void)
{
       
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE, ENABLE);
       
       
                //LCD - DATA
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
         //LCD - RS RW EN
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOC, &GPIO_InitStructure);
       
       

     delayms(50);
     Lcd_WriteCmd(0x30);//扩充指令操作                 
     delayms(1);
     Lcd_WriteCmd(0x30);//基本指令操作
     delayms(1);
     Lcd_WriteCmd(0x0c); //显示开,关光标
           delayms(1);
     Lcd_WriteCmd(0x01); //清除LCD的显示内容
                 delayms(20);
}




/*****显示汉字*****/
void hanzi_Disp(uint8_t x,uint8_t y,const uint8_t  *s)
{
     Lcd_WriteCmd(addr_tab[8*x+y]);
     while(*s>0)
     {
     Lcd_WriteData(*s);
     s++;
     }
                 
}
/***************************************************************/

/***************************************************************/
void OrigiNumToDisNum(uint8_t x,uint8_t y,unsigned long int OriginNum)
{
        unsigned char i;
        unsigned char j;
        DisNum1[0] =  OriginNum/10000000+0x30;
        DisNum1[1] = (OriginNum%10000000)/1000000+0x30;
        DisNum1[2] = (OriginNum%1000000)/100000+0x30;
        DisNum1[3] = (OriginNum%100000)/10000+0x30;
        DisNum1[4] = (OriginNum%10000)/1000+0x30;
        DisNum1[5] = (OriginNum%1000)/100+0x30;
        DisNum1[6] = (OriginNum%100)/10+0x30;
        DisNum1[7] = (OriginNum%10)+0x30;

        for(j=0;j<8;j++)
        {
                if(DisNum1[j]!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab[8*x+y]);
        for(i=j;i<8;i++)
        {
                Lcd_WriteData(DisNum1[i]);
        }
}

void OrigiNumToDisNumPhone(uint8_t x,uint8_t y,uint64_t OriginNum)
{
        unsigned char i;
        unsigned char j;


       
                        DisNum1[11]=OriginNum%10+'0';
            DisNum1[10]=OriginNum/10%10+'0';
            DisNum1[9]=OriginNum/100%10+'0';
                        DisNum1[8]=OriginNum/1000%10+'0';
                        DisNum1[7]=OriginNum/10000%10+'0';
                        DisNum1[6]=OriginNum/100000%10+'0';
                        DisNum1[5]=OriginNum/1000000%10+'0';                       
                        DisNum1[4]=OriginNum/10000000%10+'0';
                        DisNum1[3]=OriginNum/100000000%10+'0';
                        DisNum1[2]=OriginNum/1000000000%10+'0';
                        DisNum1[1]=OriginNum/10000000000%10+'0';
                        DisNum1[0]=OriginNum/100000000000%10+'0';
       
       
       
       
       
       
       
        for(j=0;j<12;j++)
        {
                if(DisNum1[j]!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab[8*x+y]);
        for(i=j;i<12;i++)
        {
                Lcd_WriteData(DisNum1[i]);
        }
}

void shuzi_Disp(uint8_t x,uint8_t y,uint8_t s)
{
     Lcd_WriteCmd(addr_tab[8*x+y]);

     Lcd_WriteData(s);

}

#else //串口
/***********************************************************************
12864液晶的4线串行驱动模式
引脚定义:RS(CS)=====>PA0
          RW(SID)====>PA1
          EN(SCLK)===>PA2
                  RST=====>PA3
    PSB为硬件控制,接高电平为8位或4位的并行模式,接低电平为串行模式
************************************************************************/

void LCD12864_Send(unsigned char Data_Command)
{
        unsigned char i;
       
        Set_CS();    //CS为高电平,使能CS
       
        for(i=0;i<8;i++)
        {
                if((Data_Command & 0x80)!=0)        //发送的是1
                        Set_SID();              //SID为高电平
                else
                        if(((Data_Command & 0x80)==0))  //发送的是0
                                Clr_SID();         //SID为低电平
               
               
                Set_SCLK();                  //SCLK为高电平
                Clr_SCLK();                  //SCLK为低电平
               
                Data_Command<<=1;                   //完成一次发送后数据左移一位,等待第二次发送       
        }
       
        Clr_CS();     //CS为低电平,失能CS
}


//LCD12864写数据函数
//入口参数:Data(要写入的数据)

void Lcd_WriteData(unsigned char Data)
{
        unsigned char Save_Data_1,Save_Data_2;
       
        Save_Data_1=Data & 0xf0;        //数据前四位
        Save_Data_2=(Data & 0x0f)<<4;   //数据后四位
       
        LCD12864_Send(0xfa);            // 发送第一固定字节数据指令
        LCD12864_Send(Save_Data_1);     // 发送数据前四位
        LCD12864_Send(Save_Data_2);     // 发送数据后四位       
}


//LCD12864写命令函数
//入口参数:Command(要写入的命令)

void Lcd_WriteCmd(unsigned char Command)
{
        unsigned char Save_Command_1,Save_Command_2;
       
        Save_Command_1=Command & 0xf0;        //命令前四位
        Save_Command_2=(Command & 0x0f)<<4;   //命令后四位
       
        LCD12864_Send(0xf8);                  // 发送第一固定字节命令指令
        LCD12864_Send(Save_Command_1);        // 发送命令前四位
        LCD12864_Send(Save_Command_2);        // 发送命令后四位       
}


//LCD12864送显示函数
//入口参数:x表示行;y表示列;*p表示要写入的数据

void LCD12864_Display(unsigned char x,unsigned char y,unsigned char *p)
{
        if(x==1)
                x=0;
        else
                if(x==2)
                        x=2;
                else
                        if(x==3)
                                x=1;
                        else
                                if(x==4)
                                        x=3;
                                       
        Lcd_WriteCmd(0x80+8*x+(y-1));
       
        while(*p)
        {
                Lcd_WriteData(*p);
                p++;
        }       
}


//LCD12864初始化函数
//入口参数:无

void Lcd_Init()
{       
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE, ENABLE);
       

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;                //        PB口全部设置成 推挽输出 GPIO_Pin_None表示无引脚被选中
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //        GPIO_Speed_10MHz        GPIO_Speed_2MHz
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //  GPIO_Mode_Out_OD 开漏输出        GPIO_Mode_AF_OD 复用开漏输出        GPIO_Mode_AF_PP 复用推挽输出
        GPIO_Init(GPIOC,&GPIO_InitStructure);                        //指定哪个端口

        Clr_RST();
        delayms(10);
        Set_RST();

        Lcd_WriteCmd(0x01);      //清屏指令
        delayms(1);                      //1us*参数,1ms
        Lcd_WriteCmd(0x06);      //进入设定点,游标右移指令
        delayms(70);                        //1us*参数,70us
        Lcd_WriteCmd(0x0c);      //显示开指令
        delayms(70);                       //1us*参数,70us
       
}

void LCD12864_Cls()
{
        Lcd_WriteCmd(0x01);      //清屏指令;
}

void LCD12864()
{
        LCD12864_Display(1,1,"Good!           ");

}
void LCD_Clean(void)
{
         Lcd_WriteCmd(0x01);
   delayms(20);
}

/*****显示汉字*****/
void hanzi_Disp(uint8_t x,uint8_t y,const uint8_t  *s)
{
     Lcd_WriteCmd(addr_tab[8*x+y]);
     while(*s>0)
     {
     Lcd_WriteData(*s);                       
     s++;
     }
                 
}
/***************************************************************/

/***************************************************************/
void OrigiNumToDisNum(uint8_t x,uint8_t y,unsigned long int OriginNum)
{
        unsigned char i;
        unsigned char j;
        DisNum1[0] =  OriginNum/10000000+0x30;
        DisNum1[1] = (OriginNum%10000000)/1000000+0x30;
        DisNum1[2] = (OriginNum%1000000)/100000+0x30;
        DisNum1[3] = (OriginNum%100000)/10000+0x30;
        DisNum1[4] = (OriginNum%10000)/1000+0x30;
        DisNum1[5] = (OriginNum%1000)/100+0x30;
        DisNum1[6] = (OriginNum%100)/10+0x30;
        DisNum1[7] = (OriginNum%10)+0x30;

        for(j=0;j<8;j++)
        {
                if(DisNum1[j]!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab[8*x+y]);
        for(i=j;i<8;i++)
        {
                Lcd_WriteData(DisNum1[i]);
        }
}

void OrigiNumToDisNumPhone(uint8_t x,uint8_t y,uint64_t OriginNum)
{
        unsigned char i;
        unsigned char j;


       
                        DisNum1[11]=OriginNum%10+'0';
            DisNum1[10]=OriginNum/10%10+'0';
            DisNum1[9]=OriginNum/100%10+'0';
                        DisNum1[8]=OriginNum/1000%10+'0';
                        DisNum1[7]=OriginNum/10000%10+'0';
                        DisNum1[6]=OriginNum/100000%10+'0';
                        DisNum1[5]=OriginNum/1000000%10+'0';                       
                        DisNum1[4]=OriginNum/10000000%10+'0';
                        DisNum1[3]=OriginNum/100000000%10+'0';
                        DisNum1[2]=OriginNum/1000000000%10+'0';
                        DisNum1[1]=OriginNum/10000000000%10+'0';
                        DisNum1[0]=OriginNum/100000000000%10+'0';
       
       
       
       
       
       
       
        for(j=0;j<12;j++)
        {
                if(DisNum1[j]!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab[8*x+y]);
        for(i=j;i<12;i++)
        {
                Lcd_WriteData(DisNum1[i]);
        }
}




void shuzi_Disp(uint8_t x,uint8_t y,uint8_t s)
{
     Lcd_WriteCmd(addr_tab[8*x+y]);

     Lcd_WriteData(s);

}

#endif

#if 0 //并口
//PC0~2 PE7~14


#define  LCD_RS_1    GPIO_SetBits(GPIOC, GPIO_Pin_2)//PORTB|=1<<PB5
#define  LCD_RS_0    GPIO_ResetBits(GPIOC, GPIO_Pin_2) //PORTB&=~(1<<PB5)
#define  LCD_RW_1    GPIO_SetBits(GPIOC, GPIO_Pin_1)//PORTB|=1<<PB6
#define  LCD_RW_0    GPIO_ResetBits(GPIOC, GPIO_Pin_1) //PORTB&=~(1<<PB6)
#define  LCD_EN_1    GPIO_SetBits(GPIOC, GPIO_Pin_0)//PORTB|=1<<PB7
#define  LCD_EN_0    GPIO_ResetBits(GPIOC, GPIO_Pin_0)//PORTB&=~(1<<PB7)



#else //串口

#define  LCD_RS_1    GPIO_SetBits(GPIOC, GPIO_Pin_2)//PORTB|=1<<PB5
#define  LCD_RS_0    GPIO_ResetBits(GPIOC, GPIO_Pin_2) //PORTB&=~(1<<PB5)
#define  LCD_RW_1    GPIO_SetBits(GPIOC, GPIO_Pin_1)//PORTB|=1<<PB6
#define  LCD_RW_0    GPIO_ResetBits(GPIOC, GPIO_Pin_1) //PORTB&=~(1<<PB6)
#define  LCD_EN_1    GPIO_SetBits(GPIOC, GPIO_Pin_0)//PORTB|=1<<PB7
#define  LCD_EN_0    GPIO_ResetBits(GPIOC, GPIO_Pin_0)//PORTB&=~(1<<PB7)

//函数声明

#define Set_CS()   LCD_RS_1
#define Set_SID()  LCD_RW_1
#define Set_SCLK() LCD_EN_1
#define Set_RST()  PCout(3)=1

#define Clr_CS()   LCD_RS_0
#define Clr_SID()  LCD_RW_0
#define Clr_SCLK() LCD_EN_0
#define Clr_RST()  PCout(3)=0

void LCD12864(void);
void LCD12864_Init(void);
void LCD12864_Display(unsigned char x,unsigned char y,unsigned char *p);
void LCD12864_Cls(void);
void Lcd_WriteCmd(unsigned char Command);
void LCD12864();

#endif
zxopenyz 发表于 2020-1-18 08:29:35 | 显示全部楼层
LCD12864 并口和串口通用程序
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-5-2 19:45 , Processed in 0.060988 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表