1、STM32：LCD1602.h
 #ifndef __LCD1602_H
 #define __LCD1602_H     
      
 //1602液晶指令/数据或选择引脚
 #define LCD_RS_PORT     GPIOB
 #define LCD_RS_PIN      GPIO_Pin_10
 ​
 #define  LCD_RS_0       GPIO_ResetBits(LCD_RS_PORT, LCD_RS_PIN)
 #define  LCD_RS_1       GPIO_SetBits(LCD_RS_PORT, LCD_RS_PIN)
 ​
 ​
 //1602液晶使能引脚
 #define LCD_EN_PORT     GPIOB
 #define LCD_EN_PIN      GPIO_Pin_11                 //PB11
 ​
 #define  LCD_EN_0       GPIO_ResetBits(LCD_EN_PORT, LCD_EN_PIN)
 #define  LCD_EN_1       GPIO_SetBits(LCD_EN_PORT, LCD_EN_PIN)
 ​
 //1602液晶数据端口    
 #define MOSIO PBout(0)  
 #define R_CLK PCout(5)
 #define S_CLK PCout(4)
 ​
 /*********************函数声明*****************/
 void LCD1602_Init(void);
 void LCD1602_Clear(void);
 void LCD1602_ShowStr(unsigned char xpos,unsigned char ypos,char *p);
 void LCD1602_BKLSet(unsigned char on);
 unsigned char LCD1602_BKLGet(void);
 void LCD1602_ShowLineStr(unsigned char xpos,unsigned char ypos,char *p);
 void LCD1602_ShowState(unsigned char Signal, unsigned char GprsState);
 /**********************************************/
 #endif  
 ​


2、STM32：LCD1602.c
 #include "LCD1602.h"
 #include "delay.h"//程序中的延时函数根据自己32单片机来就行    
 ​
 void hc595SendData(unsigned char sendVal)
 {
     unsigned char i;
     //从CPU中向595一位一位发送，595一位一位接收
     for(i = 0; i < 8; i++)
     {
         if((sendVal << i) & 0x80)
             MOSIO = 1;
         else MOSIO = 0;
         S_CLK = 0;
         S_CLK = 1;
 ​
     }
     //CPU发送完后，R_CLK将数据并行输出，
     //实现了只占用CPU一个输出口就可以输出8bit数据
     R_CLK = 0;
     R_CLK = 1;
 ​
 }
 ​
 void LCD1602_write_com(unsigned char com)   
 {
     hc595SendData(com);
     LCD_RS_0;
     LCD_EN_0;
     delay_ms(10);   
     LCD_EN_1;
 }
 ​
 void LCD1602_write_data(unsigned char date) 
 {
     hc595SendData(date);
     LCD_RS_1;
     LCD_EN_0;
     delay_ms(10);
     LCD_EN_1;
 }
 ​
 void LCD1602_Init(void) 
 {
      GPIO_InitTypeDef  GPIO_InitStructure;
  
     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE );
     
     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Pin =  LCD_RS_PIN | LCD_EN_PIN | GPIO_Pin_0;
     GPIO_Init(GPIOB, &GPIO_InitStructure);  
 ​
     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_4 | GPIO_Pin_5;              
     GPIO_Init(GPIOC, &GPIO_InitStructure);  
     
     LCD1602_write_com(0x01); 
     LCD1602_write_com(0x38);
     LCD1602_write_com(0x0C);//开显示，不需要光标 
     LCD1602_write_com(0x06);
 }
 ​
 void LCD1602_Clear(void)
 {
     LCD1602_write_com(0x01);
 }
 ​
 void LCD1602_ShowChar(unsigned char xpos,unsigned char ypos,char xsz)   
 {
     ypos%=2;
     if(ypos==0)
     {
         LCD1602_write_com(0x80+xpos);
     }
     else
     {
         LCD1602_write_com(0x80+0x40+xpos);
     }
     LCD1602_write_data(xsz);
 }
 ​
 void LCD1602_ShowLineStr(unsigned char xpos,unsigned char ypos,char *p)
 {
     unsigned char i=0;
     if(ypos>1 || xpos>=16)return;
     while(*p!='\0' && i<16 && xpos<16)
     {
         i++;
         LCD1602_ShowChar(xpos++,ypos,*p++);
         delay_us(500);
     }
 }
 ​
 void LCD1602_ShowStr(unsigned char xpos,unsigned char ypos,char *p)
 {
     if(ypos>1)return;
     while(*p!='\0')
     {
         LCD1602_ShowChar(xpos++,ypos,*p++);
         if(*p=='\n')//当检测到换行符时，进行换行检测
         {
             xpos=0;
             ypos++;
             p++;
         }
     }
 }