天天看點

STM32(stm32f401xx)開發之LCD128*64(ampire128*64)Proteus和Keils程式下載下傳(百度網盤)ampire128*64 (preteus)仿真程式編寫(keil)總代碼

目錄 ampire128*64

  • Proteus和Keils程式下載下傳(百度網盤)
  • ampire128*64 (preteus)
    • 概述
    • ampire128*64的仿真實物圖
    • 關于ampire128*64的引腳接線
  • 仿真程式編寫(keil)
    • 查詢 忙 狀态 void check_busy()
    • 寫指令 void LCD_write_command(char cmdata)
    • 寫資料 void LCD_write_data(char wodata)
    • LCD初始化 void LCD_Init()
    • 設定 LCD 顯示的坐标 void set_xy(char x, char y)
    • 顯示 16*16 像素點的漢字 void disp_hz(char R,char L,char *p)
    • 顯示 16*8 像素點的字母或符号 void disp_hz(char R,char L,char *p)
    • 主函數 int main()
  • 總代碼

Proteus和Keils程式下載下傳(百度網盤)

連結:https://pan.baidu.com/s/16d4WXDRUduuw7KPAu1_-mQ

提取碼:nbxy

(有一說一,CSDN上傳資源就算本來下載下傳積分設成0,也會自己調高,真的難受,還是放連結了)

ampire128*64 (preteus)

概述

ampire128*64 就是一塊lcd顯示屏,可以看成是 128**64 個燈泡組成

“寫資料”——函數控制燈泡的亮滅

“寫指令”——函數執行 lcd 本身自帶的指令

要讓 LCD 顯示東西

  • 把 LCD 初始化
  • 将要顯示的 字模資料 寫入 DDRAM ,就可以控制燈泡的亮滅
    • PCtoLCD2002(取字模軟體),使用該軟體取出要使用的字模資料
      • 使用說明:修改字模選項
        STM32(stm32f401xx)開發之LCD128*64(ampire128*64)Proteus和Keils程式下載下傳(百度網盤)ampire128*64 (preteus)仿真程式編寫(keil)總代碼
        STM32(stm32f401xx)開發之LCD128*64(ampire128*64)Proteus和Keils程式下載下傳(百度網盤)ampire128*64 (preteus)仿真程式編寫(keil)總代碼

ampire128*64的仿真實物圖

STM32(stm32f401xx)開發之LCD128*64(ampire128*64)Proteus和Keils程式下載下傳(百度網盤)ampire128*64 (preteus)仿真程式編寫(keil)總代碼

晶片用的是stm32f401VE

晶片仿真沒接電源,實物一定要接

關于ampire128*64的引腳接線

STM32(stm32f401xx)開發之LCD128*64(ampire128*64)Proteus和Keils程式下載下傳(百度網盤)ampire128*64 (preteus)仿真程式編寫(keil)總代碼

CS1:左半屏選擇引腳,低電平有效。該引腳有效時左半螢幕操作有效

CS2:右半屏選擇引腳,低電平有效。該引腳有效時右半螢幕操作有效

GND:電源地

VCC:電源正

V0:LCD的驅動電壓,用來調節LCD背景深淺對比度(這個腳懸空不接就可以)

RS:指令/資料控制引腳。該腳為高電平是DB資料線上傳輸的是資料,該腳為低電平是DB資料線上傳輸的是指令

R/W:讀/寫控制引腳。該腳為高電平時從LCD子產品中毒資料,該腳為低電平時寫資料到LCD子產品中。

E:LCD讀寫使能引腳

DB7 - DB0 :資料總線

RST:複位腳,低電平複位(直接接高電平)

-Vout:LCD的驅動電源(接-10v的電源)

不懂沒關系,照圖接引腳就行

仿真程式編寫(keil)

查詢 忙 狀态 void check_busy()

void check_busy()
{
char a=0;
for(a=0;a<200;a++);    //此處為延時,一段時間後確定處于空閑狀态
 //此處為狀态查詢,查詢忙狀态,沒有使用成功,以後再調試
//RW=1;
GPIO_WriteBit(GPIOB,LCD_RW,1);
//RS=0;     
GPIO_WriteBit(GPIOB,LCD_RS,0);                            
//E=1;
GPIO_WriteBit(GPIOB,LCD_EA,1);

while(1)
{
     //E=0;
     GPIO_WriteBit(GPIOB,LCD_EA,0);
     //這裡就是要檢測 DB7 引腳的電平,低電平說明不忙,可以寫入資料或指令
     if ( DB7引腳 == 0)
        break;
  	  //設定循環次數,防止無限循環
  	  a++;
     if(a>10)
		  break;
 	   
}
//E=1;
GPIO_WriteBit(GPIOB,LCD_EA,1);
}       
           

這個函數用來檢查lcd是否處于 忙 狀态

如果 LCD 處于 忙 狀态,那就等着

直到LCD不忙的時候再寫指令或資料

正常來說每次寫指令或寫資料的時候要先調用此函數,查 忙 狀态,proteuw仿真的時候有點小bug,會一直處于 忙狀态 ,就不調用了

寫指令 void LCD_write_command(char cmdata)

void LCD_write_command(char cmdata)
{
		//這裡本來要調用查 忙 函數,仿真可以不調用
		//check_busy();
		
		//LCD_RS=0; 
		GPIO_WriteBit(GPIOB,LCD_RS,0);
		//LCD_RW=0;
		GPIO_WriteBit(GPIOB,LCD_RW,0);	 
 
		
		//LCD_EA=1;     //開使能
		GPIO_WriteBit(GPIOB,LCD_EA,1);	
	
		// D0-D7 =cmdata;
		GPIO_Write(GPIOA,cmdata);

		//LCD_EA=0;     //關使能
		GPIO_WriteBit(GPIOB,LCD_EA,0);

		delay_us(15);
}
           

寫資料 void LCD_write_data(char wodata)

void LCD_write_data(char wodata)
{
    //這裡本來要調用查 忙 函數,仿真可以不調用
	//check_busy();
	
	//LCD_RS=1;  
	GPIO_WriteBit(GPIOB,LCD_RS,1);

	//LCD_RW=0;  
	GPIO_WriteBit(GPIOB,LCD_RW,0);

	//LCD_EA=1;
	GPIO_WriteBit(GPIOB,LCD_EA,1);

	//D0-D7 = wodata;
	GPIO_Write(GPIOA,wodata);

	//LCD_EA=0;
	GPIO_WriteBit(GPIOB,LCD_EA,0);
	
	delay_us(15);

}
           

LCD初始化 void LCD_Init()

void LCD_Init()
{

	LCD_write_command(0x30); //
	delay_us(4);
	
	LCD_write_command(0x0c); //開顯示,關光标,不閃爍
	delay_us(10);

	LCD_write_command(0x01); //清除顯示
	delay_us(10);	
	
	LCD_write_command(0x06); //光标的移動方向向左,DDRM的位址計數器(AC)加1
	delay_us(10);	


}
           

這裡初始化的指令照搬就行,每次初始化基本都是這樣,想要其他初始化的可以去查 ampire128 的指令集

設定 LCD 顯示的坐标 void set_xy(char x, char y)

void set_xy(char x, char y)
{
	if( y>=64 )
	{
		GPIO_WriteBit(GPIOB,CS1,1);
		GPIO_WriteBit(GPIOB,CS2,0);
		y = y-64;
	}
	else
	{
		GPIO_WriteBit(GPIOB,CS1,0);
		GPIO_WriteBit(GPIOB,CS2,1);	
	}
	
	LCD_write_command( 0x40 | y );
	delay_us(15);
	LCD_write_command( 0xb8 | x );
	
	
}
           

顯示 16*16 像素點的漢字 void disp_hz(char R,char L,char *p)

void disp_hz(char R,char L,char *p)//漢字 16*16
{
	char i;
	for(i=0;i<16;i++)
	{
		set_xy(2*R,16*L+i);           //設定顯示位置,每個漢字16*16個點,顯示時每行8*16個點,是以需要兩行8*32個點,此處為第一行
		LCD_write_data(p[i]);           //寫入DDRAM
		set_xy(2*R+1,16*L+i);        //第二行
		LCD_write_data(p[i+16]);
	}
}
           

顯示 16*8 像素點的字母或符号 void disp_hz(char R,char L,char *p)

void disp_zf(char R,char L,char *p)//字母符号 16*8
{
	char i;
	for(i=0;i<8;i++)
	{
		set_xy(2*R,8*L+i);                 //設定顯示位置,每個字母16*8個點,顯示時每行8*8個點,是以需要兩行8*16個點,此處為第一行
		LCD_write_data(p[i]);
		
		set_xy(2*R+1,8*L+i);                //第二行
		LCD_write_data(p[i+8]);
	}
}
           

主函數 int main()

int main()
{
	char k=0;
	//初始化計時器
	systick_init();
	//初始化 GPIO
	GPIO_INIT();
	// LCD 初始化	
	LCD_Init();
	
	//lcd顯示“溫度”
	for(k=0;k<3;k++)
		disp_hz(1,0+k,Chra[k]); 
	//lcd顯示“濕度”
	for(k=0;k<3;k++)
		disp_hz(2,0+k,Chra[k+3]); 

	while(1)
	{	
	}
	
	return 0;//主函數的傳回
}
           

總代碼

#include <stdio.h>//單片機工程可以不用

#include <stm32f4xx.h>//這個頭檔案一定要包含 ---這個頭檔案官方幫我們定義好了所有寄存器的位址



//适合LM016L液晶顯示器


#define LCD_RS GPIO_Pin_0
#define LCD_RW GPIO_Pin_1
#define LCD_EA GPIO_Pin_2
#define CS1 GPIO_Pin_5
#define CS2 GPIO_Pin_4




/*----lcd字模定義----------------------------------------------------------------------------------*/

char Max[3][16] = 
{
// M(0) a(1) x(2)
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x01,0x3E,0x01,0x3F,0x20,0x00},/*"M",0*/
{0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x19,0x24,0x24,0x12,0x3F,0x20,0x00},/*"a",1*/
{0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x20,0x31,0x0E,0x2E,0x31,0x20,0x00}/*"x",2*/

};


char Number[10][16] = 
{



{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",9*/
{0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00},/*"1",0*/
{0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",1*/
{0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00},/*"3",2*/
{0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24},/*"4",3*/
{0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00},/*"5",4*/
{0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00},/*"6",5*/
{0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00},/*"7",6*/
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",7*/
{0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00}/*"9",8*/


};
char Chra[6][32] = 
{
	{0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,
0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,
0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00},/*"溫",0*/
	
{0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,
0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,
0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00},/*"度",1*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",0*/


{0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,
0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,
0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00},/*"濕",2*/

{0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,
0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,
0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00},/*"度",3*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",0*/


};





/*------------------滴答定時器子產品----------------------------------------------------------*/


void systick_init(void)
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

}

void delay_us(unsigned int us)
{
	unsigned int set_time = us*84;//得到設定值  us*84<16777215   us<199728
	unsigned int tmp;
	
	//初始化
	SysTick->LOAD = set_time;//把目前擷取需要的延時的時間設定值丢給LOAD寄存器 24bit
	SysTick->VAL  = 0;//先清空計數器的目前值  寫0  之後再開啟定時器後 會将LOAD的設定值自動裝載進VAL

	//開滴答定時器
	SysTick->CTRL |= 0x01;//給最低位1 開滴答定時器
	
	while(1)
	{
		tmp = SysTick->CTRL;//讀取
		//隻要該條件為非零 就表示已經遞減計數到0
		if(tmp & 0x10000)
		{
			break;//跳出
	
		}
	}
	SysTick->VAL = 0;//把計數值清零
	SysTick->CTRL &= (~0x01) ;//關閉定時器   0xFFFFFFFE 1110
	//0|任何位不會改變該位
	//1|任何位都會變為1
}

	


void delay_ms(unsigned int ms)
{
	unsigned int set_time = ms*84000;//得到設定值  us*84000<16777215   us<199.728  最高這一次延時
	unsigned int tmp;
	
	//初始化
	SysTick->LOAD = set_time;//把目前擷取需要的延時的時間設定值丢給LOAD寄存器 24bit
	SysTick->VAL  = 0;//先清空計數器的目前值  寫0  之後再開啟定時器後 會将LOAD的設定值自動裝載進VAL

	//開滴答定時器
	SysTick->CTRL |= 0x01;//給最低位1 開滴答定時器
	
	while(1)
	{
		tmp = SysTick->CTRL;//讀取
		//隻要該條件為非零 就表示已經遞減計數到0
		if(tmp & 0x10000)
		{
			break;//跳出
	
		}
	}
	SysTick->VAL = 0;//把計數值清零
	SysTick->CTRL &= (~0x01) ;//關閉定時器   0xFFFFFFFE 1110
	//0|任何位不會改變該位
	//1|任何位都會變為1
}

void delay_s(unsigned int s)
{
	
	while(--s)
	{
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
		delay_ms(100);
	}
	
}
	
















/*--------lcd子產品-------------------------------------------------------------------------------------------------
*/

void check_busy()
{
char a=0;
for(a=0;a<200;a++);                  //此處為延時,一段時間後確定處于空閑狀态
/*                                      //此處為狀态查詢,查詢忙狀态,沒有使用成功,以後再調試
RW=1;
RS=0;                                 
E=1;
while(1)
{
     E=1;
     if(!(P0&0x80))
        break;
  	  a++;
     if(a>10)
		  break;
 	   
}
E=1;
*/
}       






//寫指令
void LCD_write_command(char cmdata)
{

		//check_busy();
		//LCD_RS=0; 
		GPIO_WriteBit(GPIOB,LCD_RS,0);
		//LCD_RW=0;
		GPIO_WriteBit(GPIOB,LCD_RW,0);	 
 
		
		//LCD_EA=1;     //開使能
		GPIO_WriteBit(GPIOB,LCD_EA,1);	
	
		// D0-D7 =cmdata;
		GPIO_Write(GPIOA,cmdata);

		//LCD_EA=0;     //關使能
		GPIO_WriteBit(GPIOB,LCD_EA,0);

		delay_us(15);
}

//寫資料
void LCD_write_data(char wodata)
{
	//check_busy();
	//LCD_RS=1;  
	GPIO_WriteBit(GPIOB,LCD_RS,1);

	//LCD_RW=0;  
	GPIO_WriteBit(GPIOB,LCD_RW,0);

	//LCD_EA=1;
	GPIO_WriteBit(GPIOB,LCD_EA,1);

	//D0-D7 = wodata;
	GPIO_Write(GPIOA,wodata);

	//LCD_EA=0;
	GPIO_WriteBit(GPIOB,LCD_EA,0);
	delay_us(15);

}



//LCD初始化
void LCD_Init()
{

	LCD_write_command(0x30); //
	delay_us(4);
	
	LCD_write_command(0x0c); //開顯示,關光标,不閃爍
	delay_us(10);

	LCD_write_command(0x01); //清除顯示
	delay_us(10);	
	
	LCD_write_command(0x06); //光标的移動方向向左,DDRM的位址計數器(AC)加1
	delay_us(10);	


}



void set_xy(char x, char y)
{
	if( y>=64 )
	{
		GPIO_WriteBit(GPIOB,CS1,1);
		GPIO_WriteBit(GPIOB,CS2,0);
		y = y-64;
	}
	else
	{
		GPIO_WriteBit(GPIOB,CS1,0);
		GPIO_WriteBit(GPIOB,CS2,1);	
	}
	
	LCD_write_command( 0x40 | y );
	delay_us(15);
	LCD_write_command( 0xb8 | x );
	
	
}



void disp_hz(char R,char L,char *p)//漢字 16*16
{
	char i;
	for(i=0;i<16;i++)
	{
		set_xy(2*R,16*L+i);           //設定顯示位置,每個漢字16*16個點,顯示時每行8*16個點,是以需要兩行8*32個點,此處為第一行
		LCD_write_data(p[i]);           //寫入DDRAM
		set_xy(2*R+1,16*L+i);        //第二行
		LCD_write_data(p[i+16]);
	}
}




void disp_zf(char R,char L,char *p)//字母符号 16*8
{
	char i;
	for(i=0;i<8;i++)
	{
		set_xy(2*R,8*L+i);                 //設定顯示位置,每個字母16*8個點,顯示時每行8*8個點,是以需要兩行8*16個點,此處為第一行
		LCD_write_data(p[i]);
		
		set_xy(2*R+1,8*L+i);                //第二行
		LCD_write_data(p[i+8]);
	}
}

void GPIO_INIT(void)
{
	//使能指定的GPIO子產品時鐘--預設複位後開機時鐘不會全部提供給各個子產品 使用時需要自己開啟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

	
	GPIO_InitTypeDef aaa;
	
	aaa.GPIO_Pin = GPIO_Pin_All;//引腳号選擇  PA0  也要按照官方的填法  怎麼填 去頭檔案 stm32f4xx_gpio.h
	aaa.GPIO_Mode = GPIO_Mode_OUT;//輸出模式
	aaa.GPIO_OType =  GPIO_OType_PP;//推挽輸出
	aaa.GPIO_Speed = GPIO_High_Speed;//高速
	//寫入
	GPIO_Init(GPIOC,&aaa);//&	
	GPIO_Init(GPIOA,&aaa);//&
	GPIO_Init(GPIOB,&aaa);//&
		
	//控制引腳
	GPIO_WriteBit(GPIOC, GPIO_Pin_All , 1);	


	
	
	
}



int main()
{
	char k=0;
	//初始化計時器
	systick_init();
	//初始化 GPIO
	GPIO_INIT();
	// LCD 初始化	
	LCD_Init();
	
	//lcd顯示“溫度”
	for(k=0;k<3;k++)
		disp_hz(1,0+k,Chra[k]); 
	//lcd顯示“濕度”
	for(k=0;k<3;k++)
		disp_hz(2,0+k,Chra[k+3]); 

	while(1)
	{	
	}
	
	return 0;//主函數的傳回
}
           

繼續閱讀