#include "char.h"
#include "main.h"
#include <string.h>
#define u8 unsigned char; 
#define u16 unsigned short int;  
#define u32 unsigned int;  
#define OLED_CS   cs_Pin		
#define OLED_RST  RES_Pin
#define OLED_DC   dc_Pin
#define OLED_SCL  D0_Pin
#define OLED_SDA  D1_Pin
unsigned char OLED_GRAM[128][8];	 

void OLED_WR_Byte(unsigned char dat,unsigned char cmd)               ///////////////////////////////////////////1
{	
	unsigned char i;		
  if(cmd==0)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_RESET);
	}
	  if(cmd==1)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
	}

	HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_RESET);

	for(i=0;i<8;i++)
	{			  
		HAL_GPIO_WritePin(D0_GPIO_Port,D0_Pin,GPIO_PIN_RESET);
		
		if(dat&0x80)
			HAL_GPIO_WritePin(D1_GPIO_Port,D1_Pin,GPIO_PIN_SET);
		else 
		   	HAL_GPIO_WritePin(D1_GPIO_Port,D1_Pin,GPIO_PIN_RESET);
		
		HAL_GPIO_WritePin(D0_GPIO_Port,D0_Pin,GPIO_PIN_SET);
		dat<<=1;   
	}				 

HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
 	  
} 



void OLED_Refresh_Gram(void)                                                ///////////////////////////////////2
{
	unsigned char i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,0);    //设置页地址（0~7）
		OLED_WR_Byte (0x00,0);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,0);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],1); 
	}   
}

void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	OLED_WR_Byte(0xb0+y,0);
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,0);
	OLED_WR_Byte((x&0x0f)|0x01,0); 
}   	  
//开启OLED显示    





void OLED_Display_On(void)                                                ///////////////////////////////////3
{
	OLED_WR_Byte(0X8D,0);  //SET DCDC命令
	OLED_WR_Byte(0X14,0);  //DCDC ON
	OLED_WR_Byte(0XAF,0);  //DISPLAY ON
}

void OLED_DrawPoint(unsigned char x,unsigned char y,unsigned char t)
{
	unsigned char pos,bx,temp=0;
	if(x>127||y>63)return;//超出范围了.
	pos=7-y/8;
	bx=y%8;
	temp=1<<(7-bx);
	if(t)OLED_GRAM[x][pos]|=temp;
	else OLED_GRAM[x][pos]&=~temp;
	
  
}




void OLED_Fill(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char dot)  ///////////////////////////4
{  
	unsigned char x,y;  
	for(x=x1;x<=x2;x++)
	{
		for(y=y1;y<=y2;y++)
		{ 	
			OLED_DrawPoint(x,y,dot);	
		}
	}													    
	OLED_Refresh_Gram();//更新显示
}




void OLED_Clear(void)   ////////////////////////////////////////////////////////////////////////////////5
{  
	unsigned char i,n;		    
	for(i=0;i<8;i++)  
	{    
		for(n=0;n<128;n++)
		{
			OLED_GRAM[n][i]=0;
		}
	}
	OLED_Refresh_Gram();//更新显示 
}





//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 12/16/24
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char ucWid,unsigned char mode) ///////////////////////////6
{      			    
	unsigned char temp,t,t1;
	unsigned char y0=y;
	unsigned char cucWid=(ucWid/8+((ucWid%8)?1:0))*(ucWid/2);		//得到字体一个字符对应点阵集所占的字节数
	chr=chr-' ';//得到偏移后的值		 
    for(t=0;t<cucWid;t++)
    {   
		if(ucWid==12)temp=ascii_1206[chr][t]; 	 	//调用1206字体
		else if(ucWid==16)temp=ascii_1608[chr][t];	//调用1608字体
		else if(ucWid==24)temp=ascii_2412[chr][t];	//调用2412字体
		else return;								//没有的字库
        for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)OLED_DrawPoint(x,y,mode);
			else OLED_DrawPoint(x,y,!mode);
			temp<<=1;
			y++;
			if((y-y0)==ucWid)
			{
				y=y0;
				x++;
				break;
			}
		}  	 
    }       
   
}

////////////////////////////////////////////////////////////////////////////////



void OLED_ShowFontHZ(unsigned char x,unsigned char y,unsigned char pos,unsigned char size,unsigned char mode)
{
	unsigned char temp,t,t1;
	unsigned char y0=y;  
	unsigned char csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数	 
	if(size!=12&&size!=16&&size!=24)return;	//不支持的size
	 
	for(t=0;t<csize;t++)
	{   												   
		if(size==12)temp=FontHzk[pos][t]; 	 	//调用1206字体
		else if(size==16)temp=FontHzk[pos][t];	//调用1608字体
		else if(size==24)temp=FontHzk[pos][t];	//调用2412字体
		else return;								//没有的字库
        for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)OLED_DrawPoint(x,y,mode);
			else OLED_DrawPoint(x,y,!mode);
			temp<<=1;
			y++;
			if((y-y0)==size)
			{
				y=y0;
				x++;
				break;
			}
		}  	 
	}  	
} 	
////////////////////////////////////////////

void showstring(char A[], unsigned char x ,unsigned char y)  ///////////////////////////////////////////7
{
	OLED_Clear();
	int len,i=0;
	unsigned a=1,b=1;
	len=strlen(A);
	a=x+a;
	b=y+b;
	while(i<len)
	{
		OLED_ShowChar(a,b,A[i],16,1);
		a=a+9;
		if((i>12)&&(((i-12)%13)==1))
		{
			a=1+x;
			b=b+16;
		}
		i=i+1;
	}
	
	OLED_Refresh_Gram()	;	
	
}

void plusstring(char A[], unsigned char x ,unsigned char y) ///////////////////////////////////////////8
{
	int len,i=0;
	unsigned a=1,b=1;
	len=strlen(A);
	a=x+a;
	b=y+b;
	while(i<len)
	{
		OLED_ShowChar(a,b,A[i],16,1);
		a=a+9;
		if((i>12)&&(((i-12)%13)==1))
		{
			a=1+x;
			b=b+16;
		}
		i=i+1;
	}
	
	OLED_Refresh_Gram()	;	
	
}


void roll_x_string(char A[], unsigned char x1 ,unsigned char y1, unsigned char x2)   /////////////////////////////////9
{
	if(x1>x2)
	{
		while((x1-x2)>10)
		{
			showstring(A,x1,y1);
			x1=x1-10;
			
		}
		showstring(A,x2,y1);
		
	}
	else
	{
		while((x2-x1)>5)
		{
			showstring(A,x1,y1);
			x1=x1+5;
			
		}
		showstring(A,x2,y1);
	}
	
}


void roll_y_string(char A[], unsigned char x1 ,unsigned char y1, unsigned char y2)   /////////////////////////////////10
{
	if(y1>y2)
	{
		while(y1>y2)
		{
			showstring(A,x1,y1);
			y1=y1-1;
			
		}
	}
	else
	{
		while(y1<y2)
		{
			showstring(A,x1,y1);
			y1=y1+1;
			
		}
	}
	
}


	


void OLED_Init()                                                    /////////////////////////////////12
{

	
	
	
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
	HAL_Delay(100);
	
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_RESET);
 HAL_Delay(100);
	
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
					  
	OLED_WR_Byte(0xAE,0); //关闭显示
	OLED_WR_Byte(0xD5,0); //设置时钟分频因子,震荡频率
	OLED_WR_Byte(80,0);   //[3:0],分频因子;[7:4],震荡频率
	OLED_WR_Byte(0xA8,0); //设置驱动路数
	OLED_WR_Byte(0X3F,0); //默认0X3F(1/64) 
	OLED_WR_Byte(0xD3,0); //设置显示偏移
	OLED_WR_Byte(0X00,0); //默认为0

	OLED_WR_Byte(0x40,0); //设置显示开始行 [5:0],行数.
													    
	OLED_WR_Byte(0x8D,0); //电荷泵设置
	OLED_WR_Byte(0x14,0); //bit2，开启/关闭
	OLED_WR_Byte(0x20,0); //设置内存地址模式
	OLED_WR_Byte(0x02,0); //[1:0],00，列地址模式;01，行地址模式;10,页地址模式;默认10;
	OLED_WR_Byte(0xA1,0); //段重定义设置,bit0:0,0->0;1,0->127;
	OLED_WR_Byte(0xC0,0); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
	OLED_WR_Byte(0xDA,0); //设置COM硬件引脚配置
	OLED_WR_Byte(0x12,0); //[5:4]配置
		 
	OLED_WR_Byte(0x81,0); //对比度设置
	OLED_WR_Byte(0x7F,0); //1~255;默认0X7F (亮度设置,越大越亮)
	OLED_WR_Byte(0xD9,0); //设置预充电周期
	OLED_WR_Byte(0xf1,0); //[3:0],PHASE 1;[7:4],PHASE 2;
	OLED_WR_Byte(0xDB,0); //设置VCOMH 电压倍率
	OLED_WR_Byte(0x30,0); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;

	OLED_WR_Byte(0xA4,0); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
	OLED_WR_Byte(0xA6,0); //设置显示方式;bit0:1,反相显示;0,正常显示	    						   
	OLED_WR_Byte(0xAF,0); //开启显示	 
	OLED_Clear();
}

	void sciishow(char *box, unsigned char A)
	{
		unsigned char high, low;
		high=(A&0xf0)>>4;
		low=A&0x0f;
	if(high>=0x0A)
	{
		box[0]=high+0x37;
	}
	else
	{
		box[0]=high+0x30;
	}
		if(low>=0x0A)
	{
		box[1]=low+0x37;
	}
	else
	{
		box[1]=low+0x30;
	}
		
	}
