fpga_feixiang 发表于 2020-1-17 22:36:13

LCD12864 并口和串口通用程序

#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_InitTypeDefGPIO_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);
   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 =OriginNum/10000000+0x30;
        DisNum1 = (OriginNum%10000000)/1000000+0x30;
        DisNum1 = (OriginNum%1000000)/100000+0x30;
        DisNum1 = (OriginNum%100000)/10000+0x30;
        DisNum1 = (OriginNum%10000)/1000+0x30;
        DisNum1 = (OriginNum%1000)/100+0x30;
        DisNum1 = (OriginNum%100)/10+0x30;
        DisNum1 = (OriginNum%10)+0x30;

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

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


       
                        DisNum1=OriginNum%10+'0';
          DisNum1=OriginNum/10%10+'0';
          DisNum1=OriginNum/100%10+'0';
                        DisNum1=OriginNum/1000%10+'0';
                        DisNum1=OriginNum/10000%10+'0';
                        DisNum1=OriginNum/100000%10+'0';
                        DisNum1=OriginNum/1000000%10+'0';                       
                        DisNum1=OriginNum/10000000%10+'0';
                        DisNum1=OriginNum/100000000%10+'0';
                        DisNum1=OriginNum/1000000000%10+'0';
                        DisNum1=OriginNum/10000000000%10+'0';
                        DisNum1=OriginNum/100000000000%10+'0';
       
       
       
       
       
       
       
        for(j=0;j<12;j++)
        {
                if(DisNum1!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab);
        for(i=j;i<12;i++)
        {
                Lcd_WriteData(DisNum1);
        }
}

void shuzi_Disp(uint8_t x,uint8_t y,uint8_t s)
{
   Lcd_WriteCmd(addr_tab);

   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);
   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 =OriginNum/10000000+0x30;
        DisNum1 = (OriginNum%10000000)/1000000+0x30;
        DisNum1 = (OriginNum%1000000)/100000+0x30;
        DisNum1 = (OriginNum%100000)/10000+0x30;
        DisNum1 = (OriginNum%10000)/1000+0x30;
        DisNum1 = (OriginNum%1000)/100+0x30;
        DisNum1 = (OriginNum%100)/10+0x30;
        DisNum1 = (OriginNum%10)+0x30;

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

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


       
                        DisNum1=OriginNum%10+'0';
          DisNum1=OriginNum/10%10+'0';
          DisNum1=OriginNum/100%10+'0';
                        DisNum1=OriginNum/1000%10+'0';
                        DisNum1=OriginNum/10000%10+'0';
                        DisNum1=OriginNum/100000%10+'0';
                        DisNum1=OriginNum/1000000%10+'0';                       
                        DisNum1=OriginNum/10000000%10+'0';
                        DisNum1=OriginNum/100000000%10+'0';
                        DisNum1=OriginNum/1000000000%10+'0';
                        DisNum1=OriginNum/10000000000%10+'0';
                        DisNum1=OriginNum/100000000000%10+'0';
       
       
       
       
       
       
       
        for(j=0;j<12;j++)
        {
                if(DisNum1!=0x30)
                {
                        break;
                }
        }
        Lcd_WriteCmd(addr_tab);
        for(i=j;i<12;i++)
        {
                Lcd_WriteData(DisNum1);
        }
}




void shuzi_Disp(uint8_t x,uint8_t y,uint8_t s)
{
   Lcd_WriteCmd(addr_tab);

   Lcd_WriteData(s);

}

#endif

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


#defineLCD_RS_1    GPIO_SetBits(GPIOC, GPIO_Pin_2)//PORTB|=1<<PB5
#defineLCD_RS_0    GPIO_ResetBits(GPIOC, GPIO_Pin_2) //PORTB&=~(1<<PB5)
#defineLCD_RW_1    GPIO_SetBits(GPIOC, GPIO_Pin_1)//PORTB|=1<<PB6
#defineLCD_RW_0    GPIO_ResetBits(GPIOC, GPIO_Pin_1) //PORTB&=~(1<<PB6)
#defineLCD_EN_1    GPIO_SetBits(GPIOC, GPIO_Pin_0)//PORTB|=1<<PB7
#defineLCD_EN_0    GPIO_ResetBits(GPIOC, GPIO_Pin_0)//PORTB&=~(1<<PB7)



#else //串口

#defineLCD_RS_1    GPIO_SetBits(GPIOC, GPIO_Pin_2)//PORTB|=1<<PB5
#defineLCD_RS_0    GPIO_ResetBits(GPIOC, GPIO_Pin_2) //PORTB&=~(1<<PB5)
#defineLCD_RW_1    GPIO_SetBits(GPIOC, GPIO_Pin_1)//PORTB|=1<<PB6
#defineLCD_RW_0    GPIO_ResetBits(GPIOC, GPIO_Pin_1) //PORTB&=~(1<<PB6)
#defineLCD_EN_1    GPIO_SetBits(GPIOC, GPIO_Pin_0)//PORTB|=1<<PB7
#defineLCD_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]
查看完整版本: LCD12864 并口和串口通用程序