⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splc501.c

📁 SPLC501的AVR 驱动.驱动芯片采用AVR mega16或者mega32.5根线.SPI驱动.原创作品.
💻 C
字号:
#include <avr/io.h> 
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

prog_uchar HZK[]={
/*--  文字:  哇  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0xFC,0x04,0x04,0xFC,0x40,0x48,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0x48,0x40,0x00,
0x0F,0x02,0x02,0x47,0x40,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x44,0x40,0x00,

/*--  文字:  哈  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0xFC,0x04,0x04,0xFC,0x20,0x20,0x50,0x48,0x44,0x43,0x44,0x48,0x58,0x30,0x10,0x00,
0x07,0x01,0x01,0x03,0x00,0x00,0x7F,0x21,0x21,0x21,0x21,0x21,0x7F,0x00,0x00,0x00,

/*--  文字:  …  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0xC0,0xC0,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  文字:  睡  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0xFE,0x22,0x22,0xFE,0x00,0x92,0xF2,0x92,0x92,0xFE,0x91,0x91,0xF1,0x91,0x90,0x00,
0x7F,0x11,0x11,0x3F,0x00,0x48,0x4F,0x48,0x48,0x7F,0x48,0x48,0x4F,0x48,0x08,0x00,

/*--  文字:  觉  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x18,0x09,0xCA,0x4C,0x48,0x49,0x4A,0x4E,0x48,0x48,0xCC,0x0B,0x1A,0x00,0x00,
0x00,0x00,0x80,0x8F,0x40,0x20,0x10,0x0F,0x70,0x80,0x80,0x8F,0x80,0xE0,0x40,0x00,

/*--  文字:  啦  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0xFC,0x04,0x04,0xFC,0x08,0x08,0xFF,0x88,0x08,0xC8,0x09,0x0E,0x08,0xE8,0x08,0x00,
0x07,0x02,0x02,0x03,0x22,0x41,0x3F,0x00,0x20,0x23,0x2C,0x20,0x2C,0x23,0x20,0x00,

/*--  文字:  。  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  文字:  嘿  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0xFC,0x04,0x04,0xFC,0x00,0x7E,0x26,0x3A,0x22,0xFE,0x32,0x2E,0x2A,0x7E,0x00,0x00,
0x07,0x02,0x02,0x07,0x44,0x35,0x05,0x15,0x65,0x07,0x15,0x65,0x05,0x15,0x64,0x00};
//#define HZK(i)	(pgm_read_byte(HZK+(i)))

#define SPLC501_CLK_PORT	PORTA 
#define SPLC501_CLK_DDR 	DDRA 
#define SPLC501_DIN_PORT	PORTA 
#define SPLC501_DIN_DDR   	DDRA
#define SPLC501_A0_PORT 	PORTA 
#define SPLC501_A0_DDR  	DDRA 
#define SPLC501_RES_PORT 	PORTA 
#define SPLC501_RES_DDR 	DDRA 
#define SPLC501_CS_PORT		PORTA 
#define SPLC501_CS_DDR 		DDRA 

#define SPLC501_CLK 		0x01
#define SPLC501_DIN  		0x02
#define SPLC501_A0   		0x04
#define SPLC501_RES			0x08
#define SPLC501_CS			0x10

void SPLC501SPIWrite(unsigned char data_command,unsigned char a0) //a0=0时表示发送命令,a0=1时表示发送数据
{
	unsigned char i;
	if(a0)SPLC501_A0_PORT|=SPLC501_A0;		//SPLC501_A0=a0;
	else SPLC501_A0_PORT&=~SPLC501_A0;
	SPLC501_CS_PORT&=~SPLC501_CS;			//SPLC501_CS=0;
	for(i=0;i<8;i++)
	{
		SPLC501_CLK_PORT&=~SPLC501_CLK;		//SPLC501_CLK=0;
		if((data_command&0x80)==0)SPLC501_DIN_PORT&=~SPLC501_DIN;
		else SPLC501_DIN_PORT|=SPLC501_DIN;	//SPLC501_DIN=(data_command&0x80)==0?0:1;
		data_command<<=1;
		SPLC501_CLK_PORT|=SPLC501_CLK;		//SPLC501_CLK=1;
	}
	SPLC501_CS_PORT|=SPLC501_CS;			//SPLC501_CS=1;  
}

void SPLC501LineRun(unsigned char line)	//起始行设置.滚屏功能用
{
	//if(line>=0x80)line=0;				//line=0~63
	SPLC501SPIWrite(0x40+line,0);		//设置显示起始行对应RAM
}

void LCD_Init(void) //LCD初始化函数
{
	SPLC501_RES_PORT&=~SPLC501_RES;	//SPLC501_RES=0;  	//LCD(低电平)复位
	_delay_us(100);
	SPLC501_RES_PORT|=SPLC501_RES;	//SPLC501_RES=1; 	// RES置高
	_delay_us(100);
	SPLC501SPIWrite(0xa2,0);//LCD偏压设置:5V:0xa2;3.3V:0xa1.
	SPLC501SPIWrite(0xa1,0);//列地址选择为从右到左对应0~127;0xa1:列地址从左到右;0xa0:列地址从右到左
	SPLC501SPIWrite(0xc0,0);//行地址从上到下为0~63;0xc0:行地址从上到下;0xc8:行地址从下到上
	SPLC501SPIWrite(0x25,0);//V5电压内部电阻调整设置 一般在24~27之间
	SPLC501SPIWrite(0x81,0);//亮度调整命令0~63(暗到亮)
	SPLC501SPIWrite(0x10,0);//亮度调节为双字节命令,前一个参数控制字的深浅
	SPLC501SPIWrite(0x2f,0);//上电控制,打开调压器、稳压器和电压跟随
	SPLC501SPIWrite(0xa6,0);//正相反相显示控制指令,RAM中数据不变.0xa6:白底黑字;0xa7:黑底白字.
	SPLC501SPIWrite(0xaf,0);//0xae:set display off.0xaf:set display on
}

void Test(unsigned char a,unsigned char b)//全屏测试
{
	unsigned int i,j,page=0xb0;//指向首页命令
	for(i=0;i<8;i++)
	{
		SPLC501SPIWrite(page++,0);	//指向对应页
		SPLC501SPIWrite(0x10,0);	//SET COLUMN(列) ADDRESS MSB(高4位)为0
		SPLC501SPIWrite(0x04,0);	//SET COLUMN ADDRESS LSB(低4位)为0
		//SPLC501SPIWrite(0xee);	//读改写模式结束指令
		for(j=0;j<64;j++)
		{
			SPLC501SPIWrite(a,1);
			SPLC501SPIWrite(b,1);
		} 
	} 
}

//显示一个字或多个字函数
void DisplayWords(unsigned int p,		//指向图片数组首地址
			unsigned char page_f,		//起始页
			unsigned char page_sum,		//占多少页
			unsigned char column_f,		//起始列
			unsigned char column_sum)	//占多少列
{
	unsigned char i,j;
	unsigned char page=0xb0;			//指向首页命令
	for(i=page_f;i<page_sum+page_f;i++)
	{
		SPLC501SPIWrite(page+i,0); 
		SPLC501SPIWrite(0x10|(column_f>>4),0);		//设定列地址高4位为0
		SPLC501SPIWrite(0x04|(0x0f&column_f),0);	//设定列地址低4位为0
		for(j=0;j<column_sum;j++)SPLC501SPIWrite(pgm_read_byte(p++),1);
	}
}

//系统时钟:11059200Hz  分频:1024
//CTC TOP值:0x35
//误差:0.000000个系统周期
//Timer2初始化
volatile unsigned int sign_5ms=0;
void Timer2Init(void)
{
	TCNT2=0x00;
	OCR2=0x35;
	TCCR2=(1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS22);
	//TCNT2=0xcb;
	TIMSK|=1<<OCIE2;
}
//Timer2 CTC中断,此中断发生周期是:5毫秒
ISR(TIMER2_COMP_vect)
{
	sign_5ms+=1;
}

//系统时钟:11059200Hz  分频:256
//CTC TOP值:0xA8C0
//误差:0.000000个系统周期
//Timer1初始化
volatile unsigned char sign_1s=0;
void Timer1Init(void)
{
	TCCR1A=0;
	TCCR1B=(1<<WGM12)|(1<<CS12);
	OCR1A=0xA8C0;
	TIMSK|=1<<OCIE1A;
}
//Timer1 CTC中断,此中断发生周期是:1000毫秒
ISR(TIMER1_COMPA_vect)
{
	sign_1s++;
}

void MCU_Init(void)
{
	SPLC501_CLK_DDR|=SPLC501_CLK;
	SPLC501_DIN_DDR|=SPLC501_DIN;
	SPLC501_A0_DDR|=SPLC501_A0;
	SPLC501_CS_DDR|=SPLC501_CS;
	SPLC501_RES_DDR|=SPLC501_RES;
}

int main(void)
{
	unsigned char i=32;
	unsigned char j=0;
	unsigned char lie=16;
	unsigned char n=0;
	unsigned char hang=0;
	unsigned char line=0;
	MCU_Init();
	LCD_Init();
	Timer1Init();
	Timer2Init();
	asm("sei");
	//Test(0xaa,0x55);	//全屏测试
	Test(0x00,0x00);	//数据清0
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+j*i	 	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+j*i	 	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	n=0;
	hang+=2;
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+j*i	 	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+(j++)*i	,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+2*i		,hang,2,(n++)*lie,16);
	DisplayWords((unsigned int)HZK+2*i	 	,hang,2,(n++)*lie,16);
	while(1)
	{
		//if(sign_5ms>=200)
		if(sign_1s)
		{
			//sign_5ms=0;
			sign_1s=0;
			line&=0x3f;				//line=0~63
			SPLC501LineRun(line--);	//滚屏
		}
	}
}

void Frame_dis(unsigned char *p)//显示128×64图像函数,指针p指向图片数组首地址
{	//frame 帧
	unsigned char i,j;
	unsigned char page=0xb0;	//指向首页命令
	for(i=0;i<8;i++)			//共8页
	{ 
		SPLC501SPIWrite(page++,0);
		SPLC501SPIWrite(0x10,0);   //设定列地址高4位为0
		SPLC501SPIWrite(0x04,0);   //设定列地址低4位为0
		for(j=0;j<128;j++)SPLC501SPIWrite(*p++,1);//共128列
	} 
}

void Plot(unsigned char *P)		//p指向曲线数组首地址
{ 
	unsigned char i,j;
	unsigned char x,x1;
	unsigned int d;
	SPLC501SPIWrite(0x10,0);	//SET COLUMN ADDRESS MSB
	SPLC501SPIWrite(0x04,0);	//SET COLUMN ADDRESS LSB,
	for(i=0;i<128;i++)
	{
		d=*P;
		if(d>63)d=63;
		x=7-d/8;
		x1=7-(d&7);
		for(j=0;j<8;j++)
		{
			SPLC501SPIWrite(0xb0+j,0);//
			SPLC501SPIWrite(0x10|((0xf0&i)>>4),0);	//SET COLUMN ADDRESS MSB
			SPLC501SPIWrite(0x00|(0x0f&i),0);		//SET COLUMN ADDRESS LSB,
			if(j!=x)SPLC501SPIWrite(0,1);
			else SPLC501SPIWrite(1<<x1,1);
		}
	}
	SPLC501SPIWrite(0x40,0);	//start h
}
/////-----       图形显示模式	    -----/////

void LCD501_PutPixel(unsigned char x,unsigned char y)	//画点子程序
{
	unsigned char x_low,x_hight;	//定义列地址的高低位指令
	unsigned char Dot_Mask_Buf=0x01;
	unsigned char y_Page;	//用于存放要画点的位置所在的byte数据位置
	x+=4;
	x_low=(x&0x0f);			//定位列地址设置的低位指令
	x_hight=(x>>4)+0x10;	//定位列地址设置的高位指令
	y_Page=y&0x07;			//取低三位
	while(y_Page!=0)
	{
		Dot_Mask_Buf<<=1;
		y_Page--;
	}
	y_Page=y>>3;						//Get the page of the byte
	SPLC501SPIWrite(0xb0+y_Page,0);
	SPLC501SPIWrite(x_low,0);
	SPLC501SPIWrite(x_hight,0);
	//SPLC501SPIWrite(0xe0,0);			//设置为读写改模式
	/*y_Page = F_SPLC501_Read_Data();	//
	switch(CurPaintMode)
	{
		case 2: y_Page=y_Page&(~Dot_Mask_Buf);
				break;
		case 3: x=y_Page^Dot_Mask_Buf; 
				x=x&Dot_Mask_Buf;
				y_Page=(y_Page&(~Dot_Mask_Buf))|x;
				break;
		default: y_Page=y_Page|Dot_Mask_Buf;
				break;
	}*/
	y_Page=y_Page|Dot_Mask_Buf;
	SPLC501SPIWrite(y_Page,1);	//
	//SPLC501SPIWrite(0xee,0);	//读写改模式结束
}

//参数:x 要画线的x起点坐标   	 y 要画的线的y起点坐标  
//		ex 要画线的x终点坐标  	 ey要画的线的y起点坐标
void LCD501_Line(char x,char y,char ex,char ey)	//画直线程序
{
	char Offset_x,Offset_y;
	char Offset_k=0;
	unsigned char signErr_d=1;
	if(y>ey)
	{
		Offset_x=x;
		x=ex;
		ex=Offset_x;
		Offset_x=y;
		y=ey;
		ey=Offset_x;
	}
	Offset_x=ex-x;
	Offset_y=ey-y;
	LCD501_PutPixel(x,y);
	if(Offset_x<=0)
	{
		Offset_x = x-ex;
		signErr_d=0;
	}
	if(Offset_x>Offset_y)
	{
		while(x!=ex)
		{
			if(Offset_k>0)
			{
				y+=1;
				Offset_k+=(Offset_y-Offset_x);
			}
			else Offset_k+=Offset_y; 
			if(signErr_d)x+=1;
			else x-=1;
			LCD501_PutPixel(x,y);
		}
	}
	else
	{
		while(y!=ey)
		{
			if(Offset_k>0)
			{
				if(signErr_d)x+=1;
				else x-=1;
				Offset_k+=(Offset_x-Offset_y);
			}
			else Offset_k+=Offset_x;
			y+=1;
			LCD501_PutPixel(x,y);
		}
	}
}

//参数:x要画的圆心的x坐标   y要画的圆心的y坐标  r半径  
//		Mode绘点模式:0 画圆框;1 画实心圆

//extern void W_Red_Err(int *a,int *b,int *r);
void LCD_PaintRed_Dot(char x,char y,char a,char b,char mode)//画圆程序
{
    if(mode)
    {
       LCD501_Line(x+a,y+b,x-a,y+b);
       LCD501_Line(x+a,y-b,x-a,y-b);
    }
    else
    {
       LCD501_PutPixel(x+a,y+b);
       LCD501_PutPixel(x-a,y+b);
       LCD501_PutPixel(x+a,y-b);
       LCD501_PutPixel(x-a,y-b);
    }
}
/*
void LCD501_Circle(unsigned char x,unsigned char y,unsigned char r,unsigned char Mode)
{
	char arx1=0,ary1,arx2,ary2=0;
	unsigned char uiTemp;
    ary1=r;
    arx2=r;
    uiTemp = LCD501_GetPaintMode();
    LCD501_SetPaintMode(0);
    while(1)
    {
       LCD_PaintRed_Dot(x,y,arx1,ary1,Mode);
       W_Red_Err(&arx1,&ary1,&r);
       if(arx1==arx2)
       {
          LCD_PaintRed_Dot(x,y,arx1,ary1,Mode);
          break; 
       }
       LCD_PaintRed_Dot(x,y,arx2,ary2,Mode);
       W_Red_Err(&ary2,&arx2,&r);
       if(arx1==arx2) 
       {
          LCD_PaintRed_Dot(x,y,arx2,ary2,Mode);
          break;
       }
    }
    LCD501_SetPaintMode(uiTemp);
}

//程序:void LCD501_Rectangle(unsigned int left, unsigned int top, 
//							unsigned int right, unsigned int bottom, unsigned int Mode)
//描述:画矩形程序
//参数:left - 矩形的左上角横坐标,范围0到118
//		top - 矩形的左上角纵坐标,范围0到50
//		right - 矩形的右下角横坐标,范围1到119
//		bottom - 矩形的右下角纵坐标,范围1到51
//		Mode - 绘制模式,可以是下列数值之一:
//				0:	矩形框(空心矩形)
//				1:	矩形面(实心矩形)
//声明:xinqiang	20050521	sunnorth  Mz Design
//注意:无

void LCD501_Rectangle(unsigned int left, unsigned int top, unsigned int right, unsigned int bottom, unsigned int Mode)
{
	unsigned int uiTemp;
	if(left>right)
	{
		uiTemp = left;
		left = right;
		right = left;
	}
	if(top>bottom)
	{
		uiTemp = top;
		top = bottom;
		bottom = uiTemp;
	}
	if(Mode==0)
	{
		LCD501_Line(left,top,left,bottom);
		LCD501_Line(left,top,right,top);
		LCD501_Line(right,bottom,left+1,bottom);
		LCD501_Line(right,bottom,right,top+1);
	}
	else
	{
		for(uiTemp=top;uiTemp<=bottom;uiTemp++)
		{
			LCD501_Line(left,uiTemp,right,uiTemp);
			Clear_Watchdog();
		}
	}
}

//程序:void LCD501_PutString(int x,int y,unsigned int a)      [8x16] [6X8]
//描述: 显时8X16、6X8的自带ASCII字符,任意行定位
//参数:x 显示字符的起始列(0~128)   y 显示字符的起始行(0~63)
//		a ASCII码					  
//声明: xinqiang		20050519	sunnorth  Mz Design
//注意: 

void LCD501_PutString(int x,int y,unsigned int * string)       
{
	unsigned int x_err=6,y_err=8;
	if(CurASCIIFont)
	{
		x_err = 8;
		y_err = 16;
	}
	while(*string!=0)
	{
		if((x+x_err)>127)
		{
			x = 0;
			y = y+y_err;
		}
		if(y>63) y =0;
		LCD501_PutChar(x,y,*string);
		string++;
		x+=x_err;
	}
}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -