STM32 19264 驱动 (proteus仿真和实际开发板)(不带字库)


  
在proteus 8.10和开发板上试验了19264液晶屏的显示。 Proteus的原理图:

Proteus下的源代码。
main.c:
#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
/*
GPIO :  
*/
#define RCC_APB2ENR    *(uint32_t*)(0x40021000+0x18)
#define RCC_APB1ENR    *(uint32_t*)(0x40021000+0x1C)
#define GPIOC_CRH    *(uint32_t*)(0x40011000+0x04)
#define GPIOC_ODR    *(uint32_t*)(0x40011000+0x0C)
#define GPIOB_CRL    *(uint32_t*)(0x40010C00+0x00)
#define GPIOB_ODR    *(uint16_t*)(0x40010C00+0x0C)
#define GPIOB_BSRR   *(uint16_t*)(0x40010C00+0x10)
#define SETENA_ISER0    *(uint32_t*)(0xe000E100+0x00)
#define EXTI_IMR        *(uint32_t*)(0x40010400+0x00)
#define EXTI_RTSR       *(uint32_t*)(0x40010400+0x08)
#define EXTI_FTSR       *(uint32_t*)(0x40010400+0x0C)
#define EXTI_PR         *(uint32_t*)(0x40010400+0x14)
#define AFIO_EXTICR2    *(uint32_t*)(0x40010000+0x0C)

#define GPIOA_IDR    *(uint32_t*)(0x40010800+0x08)
#define GPIOA_ODR    *(uint32_t*)(0x40010800+0x0C)
#define GPIOA_CRH    *(uint32_t*)(0x40010800+0x04)
#define SETENA_ISER1    *(uint32_t*)(0xe000E100+0x04)


//#define USART1_BASE    *(uint32_t*)(0x40013800+0x00)  //bug : redefinition
#define USART1_SR    *(uint32_t*)(0x40013800+0x00)
#define USART1_DR    *(uint32_t*)(0x40013800+0x04)
#define USART1_BRR    *(uint32_t*)(0x40013800+0x08)
#define USART1_CR1    *(uint32_t*)(0x40013800+0x0C)
#define USART1_CR2    *(uint32_t*)(0x40013800+0x10)
#define USART1_CR3    *(uint32_t*)(0x40013800+0x14)

#define TIM1_CR1      *(uint32_t*)(0x40012c00+0x00)
#define TIM1_DIER     *(uint32_t*)(0x40012c00+0x0C)
#define TIM1_SR       *(uint32_t*)(0x40012c00+0x10)
#define TIM1_PSC      *(uint32_t*)(0x40012c00+0x28)
#define TIM1_ARR      *(uint32_t*)(0x40012c00+0x2C)

#define TIM3_CR1      *(uint32_t*)(0x40000400+0x00)
#define TIM3_DIER      *(uint32_t*)(0x40000400+0x0C)
#define TIM3_SR      *(uint32_t*)(0x40000400+0x10)
#define TIM3_PSC      *(uint32_t*)(0x40000400+0x28)
#define TIM3_ARR      *(uint32_t*)(0x40000400+0x2C)
unsigned char table_zf[] = 
{
   0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x00, 0x20, 0x3f, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00
}	;

unsigned char table_hz[] = {
   0x40, 0x20, 0xf8, 0x07, 0x00, 0xf8, 0x02, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0xfe, 0x04, 0x00, 
	 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x7f, 0x00, 0x00
};


typedef unsigned int uint32_t;


void delay_us(uint32_t n)
{
   SysTick->LOAD = 72*n;
	 SysTick->CTRL = 0x00000005;
	 while(!(SysTick->CTRL & 0x00010000))
		 ;
	 SysTick->CTRL = 0x00000004;
}

#if 0
void busy()
{
	int i;
	 uint8_t busy = 1;
		
	 GPIO_InitTypeDef GPIO_InitStruct;
	 
   //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	 GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 |
	                              GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7;
	 GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	 GPIO_Init(GPIOC,&GPIO_InitStruct);
	
	
	
	
	while(busy)
	{
	//rs = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_RESET); 

	//rw = 1;
		GPIO_WriteBit(GPIOC,GPIO_Pin_10,Bit_SET); 
		
		//e = 1
		GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); 
  
	 // for(i = 0; i < 10000; i++)
	 //   ;

    busy = GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_7); 

		//e = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET);
	}
	
	
	 GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 |
	                              GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7;
	 GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	 GPIO_Init(GPIOC,&GPIO_InitStruct);
	

}
#else
void busy()
{
   delay_us(10000);
}
#endif



void send_cmd(unsigned char data)
{
	 int i;
	
	unsigned char data2 = 0;
	{
	    data2  = (((data & 0x01)  >> 0)<< 7 ) ;
		  data2 |= (((data & 0x02)  >> 1)<< 6 ) ;
		  data2 |= (((data & 0x04)  >> 2)<< 5 ) ;
      data2 |= (((data & 0x08) >> 3)<< 4 ) ;
		  data2 |= (((data & 0x10)  >> 4)<< 3 ) ;
		  data2 |= (((data & 0x20)  >> 5)<< 2 ) ;
		  data2 |= (((data & 0x40)  >> 6)<< 1 ) ;
		  data2 |= (((data & 0x80) >> 7) << 0 ) ;
	}
	
	
	
	busy();

	
  //rs = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_RESET); 

	//rw = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_10,Bit_RESET); 


	
	//bus0 = cmd;
	// for(i = 0;  i < 8; i++)
	{
		  
			GPIO_WriteBit(GPIOA,GPIO_Pin_8,(data & 0x1) >> 0); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_9,(data & 0x2) >> 1); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_10,(data & 0x4) >> 2); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_11,(data & 0x8) >> 3); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_12,(data & 0x10) >> 4); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_13,(data & 0x20) >> 5); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_14,(data & 0x40) >> 6); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_15,(data & 0x80) >> 7); 
		
//			while(1)
//				;
		//GPIOC->ODR &= 0xffffff00;
		//GPIOC->ODR |= data2;
		//GPIOC->ODR = 0x55; //RST????

	}	
	
	//delay
	delay_us(10);
	
		
	//e = 1
		GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); 
    delay_us(10);




	//e = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET); 

}
	
void send_data(unsigned char data)
{
	 int i;
	unsigned char data2 = 0;
	
	
	
	{
      data2  = (((data & 0x01)  >> 0)<< 7 ) ;
		  data2 |= (((data & 0x02)  >> 1)<< 6 ) ;
		  data2 |= (((data & 0x04)  >> 2)<< 5 ) ;
      data2 |= (((data & 0x08) >> 3)<< 4 ) ;
		  data2 |= (((data & 0x10)  >> 4)<< 3 ) ;
		  data2 |= (((data & 0x20)  >> 5)<< 2 ) ;
		  data2 |= (((data & 0x40)  >> 6)<< 1 ) ;
		  data2 |= (((data & 0x80) >> 7) << 0 ) ;
		  //data  =  data2;
	}

   busy();
	
   //rs = 1
		GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_SET); 
	
	//rw = 0;
		GPIO_WriteBit(GPIOC,GPIO_Pin_10,Bit_RESET); 
	
	//bus0 = data;
	// for(i = 0;  i < 8; i++)
	{
	  
			GPIO_WriteBit(GPIOA,GPIO_Pin_8,(data & 0x1) >> 0); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_9,(data & 0x2) >> 1); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_10,(data & 0x4) >> 2); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_11,(data & 0x8) >> 3); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_12,(data & 0x10) >> 4); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_13,(data & 0x20) >> 5); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_14,(data & 0x40) >> 6); 
			GPIO_WriteBit(GPIOA,GPIO_Pin_15,(data & 0x80) >> 7); 
		//GPIOC->ODR &= 0xffffff00;
		//GPIOC->ODR |= data2;

	}
	
	
	//delay
	delay_us(10);
	//e = 1
			GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); 
  delay_us(10);
	//e = 0;
			GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET); 

}


void select(int cs)
{
	
    if(cs == 0)
		{
			
		   GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_RESET); //cs1 = 1;
			 GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_RESET); //cs2 = 1;
		}
		else if(cs == 1)
		{
		   GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_RESET); //cs1 = 1;
			 GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_SET); //cs2 = 0;
		}
		else if(cs == 2)
		{
		   GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_SET); //cs1 = 0;
			 GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_RESET); //cs2 = 1;
		}
		else
		{
		   GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_SET); //cs1 = 0;
			 GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_SET); //cs2 = 1;
		}
	
	
}



#define lcdrow   0xc0
#define lcdpage   0xb8
#define lcdcol   0x40

void lcd_init()
{
	 int i, j;
	 GPIO_InitTypeDef GPIO_InitStruct;
   //GPIO_WriteBit(GPIOC,GPIO_Pin_14,Bit_SET);
	 // GPIOC_CHR 配置外设时钟使能寄存器
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	 GPIO_InitStruct.GPIO_Pin   = 
	                              GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10  |GPIO_Pin_11;
	 GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	 GPIO_Init(GPIOC,&GPIO_InitStruct);
	

	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	 GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_1 | GPIO_Pin_2 | 
	                              GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_11 |
	                              GPIO_Pin_12 |GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;
	 GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	 GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	
	
	////////////////////////////////////////////////////////////////
	

	
	////////////////////////////////////////////////////////////////
	
  //select(0);
	select(0);
	
	
	//rst = 0;
  GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET); 

	//delay 10ms
  delay_us(10000);

	//rst =1;
	GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET); 
	



	
	//clear
#if 1	
  //select(0);
	select(0);
  send_cmd(0xb8);
	send_cmd(0x40);

       /*
       for(i = 0; i < 2; i++)
	     {
     	 	 for( j =0; j < 16; j++)
	       {
				    send_cmd(lcdpage+i);
				    send_cmd(lcdcol +j);
	          send_data(table_hz[j+i*16]);
	       }
			 }	
			 */

 

  /*
  for(i = 0; i < 8; i++)
	{
	    send_cmd(i + lcdpage);
		  send_cmd(lcdcol);
		  for( j = 0; j < 64; j++)
		        send_data(0x00);
		
	}
	 */
#endif

	
	
	send_cmd(lcdrow);
	send_cmd(lcdcol);
 send_cmd(lcdpage);
	send_cmd(0x3f);
//  while(1)
//		  	;
 	


	
}



 
 int main()
 {
	 int i,j;
	 
	 lcd_init();
	 
	 
	     for(i = 0; i < 2; i++)
       	 for( j =0; j < 8; j++)
	       {
				    send_cmd(lcdpage+i);
				    send_cmd(lcdcol +j);
	          send_data(table_zf[j+i*8]);
	       }
			 
	 
	     
	     for(i = 0; i < 2; i++)
	     {
     	 	 for( j =0; j < 16; j++)
	       {
				    send_cmd(lcdpage+i);
				    send_cmd(lcdcol +j + 16);//send_cmd(lcdcol +j);
	          send_data(table_hz[j+i*16]);
	       }
			 }
			 
	 while(1)
       ;	 

	 return 0;
	 
	

}

 


至此试验就告完成。用过仿真软件Proteus和编译器Keil MDK5,表示谢意。
源文件打包在此:stm32_19264_proteus.zip

开发板上的源文件打包在此:stm32_19264_board_3.zip

开发中小结一些经验:
(1)Proteus仿真改变GPIO引脚;
(2)除了ks0108和st7920,内核AIP31108电源 2.7V~5.5V,不能靠USB供电,要用实际开发板外部电源;
(3)去掉串口printf打印;
(4)屏插座接触松动也会造成显示不良;
(5)调试经验:一步一步调试。
  

More powered by