我们经常会因为让PCB  layout更好布线、IO口数量、遗漏或者其它原因,使用8个不连续的端口,而我们的程序通常是固化的,比如你在LCD1602中8个数据端分布在IGROA,IGROB,IGROC中,这个问题是经常出现 的不论你是用51还是STM32,这个时候你套用以前的1602程序是不行的,那么怎么解决呢,叫让单片机终结者来给你写个程序参考一下吧。

思路:

1、配置IO口

2、引入8个连续的新的端口D0,D1,D2,D3,D4,D5,D6,D7

3、把一个16进制数或者10进制数移位给D0,D1,D2,D3,D4,D5,D6,D7

main.c中

#include "gpio.h"
#include "delay.h"
#include "sys.h"
#include "1602.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_it.h" 
#include "stm32f10x_flash.h" 

 int main(void)
 {	
	 
	 
		delay_init();							//延时初始化
	 
	 
		gpio_init();							//IO初始化

	 
	 	lcd_Init();   						//液晶初始化


		Display_Init();						//液晶初始化赋值

	 
	 	 
		while(1)
			
			{

				Display_test();
			}

	}
 }

 

1602.h

#ifndef __1602_H
#define __1602_H	 
 #include "sys.h"
typedef struct{
	u32 weight_value;


}smart_balance_para;



#define RS  GPIO_Pin_11            
#define RW  GPIO_Pin_2
#define EN  GPIO_Pin_10


#define D0  PBout(0)
#define D1  PBout(1)
#define D2  PCout(4)
#define D3  PCout(5)
#define D4  PAout(6)
#define D5  PAout(7)
#define D6  PAout(4)
#define D7  PAout(5)




#define    LCD_RS(x)  x ? GPIO_SetBits(GPIOB, RS): GPIO_ResetBits(GPIOB, RS)
#define    LCD_RW(x)  x ? GPIO_SetBits(GPIOB, RW): GPIO_ResetBits(GPIOB, RW)
#define    LCD_EN(x)  x ? GPIO_SetBits(GPIOB, EN): GPIO_ResetBits(GPIOB, EN)


void lcd_Init(void);
void lcd_wcmd(u8 cmd);
void lcd_pos(unsigned char pos);
void lcd_wdat(u8 dat);
void LCD_Setpos(unsigned char row,unsigned char col);
void Display(u32 val);
void LCD_DispChar(unsigned char ch);
void LCD_DispString(char str[]);
void LCD_Setpos_DispString(unsigned char row,unsigned char col,char str[]);
void LCD_Dispnum(unsigned int num);	
void LCD_Dispnum_fu(int32 num);	
void Display_test(void);				    
void Display_Init(void);				    
void Display_adjust(int32 val);
#endif

1602..c

#include "stm32f10x.h"
#include "1602.h"
#include "Time.h"
#include "delay.h"
#include <stdlib.h>
 
extern int32 sx;



char dis6[] = {"Loading:"};
char dis7[] = {"12345678"};
char dis8[] = {"87654321"};


 static  int reverse_bit(int num)  
{  
    int i;  
    int bit;  
    int new_num = 0;  
    for (i = 0; i < 8; i++)  
    {  
        bit = num & 1;            //
        new_num <<= 1;            //
        new_num =new_num | bit;   //
        num >>= 1;                
    }  
    return new_num;  
}  


/******************************写命令*************************************************/	
void lcd_wcmd(u8 cmd)
	{                          // 写入指令数据到LCD

	u16  cmd_tmp ;                        // 写入指令数据到LCD

	LCD_RS(0); // 0;
	LCD_RW(0); // 0;

 

	D0=(cmd>>0)&0x01;
	D1=(cmd>>1)&0x01;
	D2=(cmd>>2)&0x01;
	D3=(cmd>>3)&0x01;
	D4=(cmd>>4)&0x01;
	D5=(cmd>>5)&0x01;
	D6=(cmd>>6)&0x01;
	D7=(cmd>>7)&0x01;
		
		
		
	LCD_EN(1); // 0;
	LCD_EN(0); // 0; 
	delay_us(50);
	}
/******************************设置位置*************************************************/		
	void lcd_pos(unsigned char pos)
	{                          //设定显示位置
	lcd_wcmd(pos | 0x80);
	}

/******************************设置位置*************************************************/	
	void lcd_wdat(u8 dat) 
	{                          //写入字符显示数据到LCD
	u16 dat_tmp;	
	LCD_RS(1); //= 1;
	LCD_RW(0); //= 0;
		
	D0=(dat>>0)&0x01;//移位 87654321中的1移位到D0
	D1=(dat>>1)&0x01;
	D2=(dat>>2)&0x01;
	D3=(dat>>3)&0x01;
	D4=(dat>>4)&0x01;
	D5=(dat>>5)&0x01;
	D6=(dat>>6)&0x01;
	D7=(dat>>7)&0x01;//移位 87654321中的8移位到D7

	LCD_EN(1); //= 0;	
	LCD_EN(0);// = 1;
	delay_us(50);
}


void lcd_Init(void) 
{ 	    
  GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO, ENABLE);
 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE);
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_2 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //输出的最大频率为50MHZ         	
	GPIO_Init(GPIOB, &GPIO_InitStructure);   //初始化GPIOB端口

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //输出的最大频率为50MHZ         	
	GPIO_Init(GPIOB, &GPIO_InitStructure);   //初始化GPIOB端口
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ; //所有GPIO为同一类型端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;	 //开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //输出的最大频率为5M0HZ
	GPIO_Init(GPIOB, &GPIO_InitStructure);   //初始化GPIOB端口
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; //所有GPIO为同一类型端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;	 //开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //输出的最大频率为50MHZ
	GPIO_Init(GPIOC, &GPIO_InitStructure);   //初始化GPIOC端口
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //所有GPIO为同一类型端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;	 //开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //输出的最大频率为50MHZ
	GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIOA端口

 	GPIO_Write(GPIOA,0XFFFF);  //将GPIOB 16个端口全部置为高电
 	GPIO_Write(GPIOB,0XFFFF);  //将GPIOB 16个端口全部置为高电
 	GPIO_Write(GPIOC,0XFFFF);  //将GPIOB 16个端口全部置为高电
	GPIO_SetBits(GPIOB,GPIO_Pin_2);
  GPIO_SetBits(GPIOB,GPIO_Pin_11);
	
  lcd_wcmd(0x38);          //显示模式设置
	delay_ms(5);
  lcd_wcmd(0x38);          //显示模式设置
	delay_ms(5);
  lcd_wcmd(0x38);          //显示模式设置
	delay_ms(5);
  lcd_wcmd(0x38);          //显示模式设置
	lcd_wcmd(0x08);          //显示关闭
	lcd_wcmd(0x01);          //显示清屏
	lcd_wcmd(0x06);          //显示光标移动设置
	delay_ms(5);
	lcd_wcmd(0x0C);          //显示开及光标设置


}


void Display_test(void)
{
						LCD_Setpos(1,0);
						LCD_DispString(dis7);
						LCD_Setpos(2,0);
						LCD_DispString(dis8);
}
	
void Display_Init(void)
{
	 Display_overKG();
	 LCD_Setpos(1,0);
	 LCD_DispString(dis6);
}
	   
 



void LCD1602_DisplayOneChar(unsigned char X,unsigned char Y,unsigned char ddata)
{
	Y &= 0x01;
	X &= 0xf;
	if (Y) X |= 0x40;                                                  //当要显示第二行时地址码+0x40;        
    X |= 0x80;                                                         // 算出指令码         
	lcd_wcmd(X);                                           //发送地址码	         
   // LCD1602_BusyCheck(); 	            
    lcd_wdat(ddata);
}


void LCD_Setpos(unsigned char row,unsigned char col)
{
 if(row==1) lcd_wcmd(col | 0x80);
 else lcd_wcmd(col | 0xC0);
}

void LCD_DispChar(unsigned char ch)
{
 lcd_wdat(ch);
}

void LCD_DispString(char str[])
{
    unsigned char i=0;
 while(str[i] != '\0')
 {
    lcd_wdat(str[i]);
    i++;
	 delay_ms(1);
 }
}
void LCD_Setpos_DispString(unsigned char row,unsigned char col,char str[])
{
 LCD_Setpos(row,col);
 LCD_DispString(str);
}