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

📄 main.c

📁 自己做的单片机Proteus仿真实例
💻 C
字号:
/********http://hi.baidu.com/echoas*******
程序:LCD12864显示图形 
内容:在12864上显示正弦曲线——按键可调频率和幅度 
学习板:HOT-51
软件:keil uVision3
液晶:QY12864HZ1 
作者:大海橡树
整理日期:2010-12-08
修改:无 


备注:有什么错误的地方,欢迎网友们到空间留言

					O(∩_∩)O~


********http://hi.baidu.com/echoas********/
#include<AT89X52.h>
#include<math.h>
#include"ZB.h"
#define uchar unsigned char
#define uint  unsigned int

#define LCD_databus P0 //LCD数据总线连接P0口 

sbit RS=P2^5;
sbit RW=P2^6;
sbit EN=P2^7;//LCD12864三个控制位 

sbit DQ=P2^3;//DS18B20数据线 
sbit KEY1=P3^2;
sbit KEY2=P3^3;
sbit KEY3=P3^4;
uchar key_value;

uchar HZ1[]="周期";
uchar HZ2[]="幅度";
void delay(uint i)	//延时函数 
{
	while(--i);
}
void Read_busy()	//LCD12864忙检测 
{
	RS=0;
	RW=1;
	EN=1;
	LCD_databus=0xFF;
	while(LCD_databus & 0x80);	//判断最高位,1---busy,0---Nobusy 
	EN=0;
}

void write_LCD_command(uchar value)//写指令 
{
	RS=0;
	RW=0;
	EN=1;
	LCD_databus=value;
	delay(7);
	EN=0;
}

void write_LCD_data(uchar value)//写数据 
{
	RS=1;
	RW=0;
	EN=1;
	LCD_databus=value;
	delay(7);
	EN=0;
}

void init_LCD()		//初始化LCD 
{
	write_LCD_command(0x30);	//8位数,基本指令 
	delay(100);
	write_LCD_command(0x30);
	delay(37);
	write_LCD_command(0x0C);	//开显示,不显示光标,光标不闪烁 
	delay(100);
	write_LCD_command(0x01);	//清屏指令 
	delay(100);
	write_LCD_command(0x06);	//没写入数据,地址指针加1 
}

void Clear_GDRAM()		//清楚GDRAM 
{
	uchar x,y;
	for(y=0;y<64;y++)
	{
		for(x=0;x<16;x++)
		{
			write_LCD_command(0x34);
			write_LCD_command(y+0x80);	//先送垂直地址 
			write_LCD_command(x+0x80);	//后送水平地址 
			write_LCD_command(0x30);	//基本指令 
			write_LCD_data(0x00);		//写入数据0 
			write_LCD_data(0x00);
		}
	}
}

uchar ReadByte()	//读LCD 
{
	uchar Read_value;
	Read_busy();
	RS=1;
	RW=1;
	EN=0;
	EN=1;
	Read_value=LCD_databus;	
	EN=0;
	
	return Read_value;
}

void display_BMP(uchar *address)//显示图片 
{
	uchar i,j;
	for(i=16;i<32;i++)
	{
		write_LCD_command(0x80+i);	//先送垂直地址 
		write_LCD_command(0x80);	//再送水平地址 
		for(j=0;j<16;j++)
		{
			write_LCD_data(*address);//写入数据 
			address++;
		}
	}
	
	for(i=0;i<32;i++)
	{
		write_LCD_command(0x80+i);//先送垂直地址 
		write_LCD_command(0x88);	//再送水平地址
		for(j=0;j<16;j++)
		{
			write_LCD_data(*address);
			address++;
		}
	}
	
}

void Draw_dots(uchar x,uchar y,uchar color)
{
	uchar ROW,xlabel,xlabel_bit;
	uchar Read_H,Read_L; 		//读LCD中的数据
	write_LCD_command(0x34);	//扩充指令
	write_LCD_command(0x36);	//打开绘图指令
	xlabel=x>>4;				//取16*16首地址
	xlabel_bit=x & 0x0F;		//计算该点在16位数据的第几位	
	if(y<32)					//如果是上半屏,上下半屏y都是0--31
	{
		ROW=y;
	}
	else						//显示的是下半屏
	{
		ROW=y-32;
		xlabel+=8;			   //规定显示在下半屏
	}
	write_LCD_command(ROW+0x80); //送入垂直地址
	write_LCD_command(xlabel+0x80);//再送入水平地址
	ReadByte();	//读取当前GDRAM数据前腰进行一次空读,接下来就可以读出数据了 
	Read_H=ReadByte(); //读高8位
	Read_L=ReadByte(); //读低8位
	
	write_LCD_command(ROW+0x80); 	//送入垂直地址
	write_LCD_command(xlabel+0x80);	//再送入水平地址
	
	if(xlabel_bit<8)
	{
		switch(color)
		{
			case 0:Read_H &= (~(0x01<<(7-xlabel_bit)));//若变白 
			break;
			case 1:Read_H |= (0x01<<(7-xlabel_bit));//若涂黑 
			break;
			case 2:Read_H ^= (0x01<<(7-xlabel_bit));//若反转 
			break;	
			default:break;
		}
		write_LCD_data(Read_H);//将数据写入GDRAM 
		write_LCD_data(Read_L);//先写高位,再写低位(地址指针顺序) 
	}
	else
	{
		switch(color)//color设置 
		{
			case 0: Read_L &= (~(0x01<<(15-xlabel_bit)));//若变白 
			break;
			case 1: Read_L |= (0x01<<(15-xlabel_bit));//若涂黑 
			break;
			case 2: Read_L ^= (0x01<<(15-xlabel_bit));//若反转 
			break;
			default:break;
		}
		write_LCD_data(Read_H);
		write_LCD_data(Read_L);//写入数据 
	}
	
	write_LCD_command(0x30);//回到普通模式 
}

void main()
{
	uchar i,j;
	uchar num;
	uchar w=10,A=6;
	init_LCD();
	Clear_GDRAM();
	write_LCD_command(0x36);
	display_BMP(ZB);
	while(1)
	{
		write_LCD_command(0x30);
		write_LCD_command(0x80);
		write_LCD_data('T');
		write_LCD_data(':');
		write_LCD_data(2*w/100+0x30);
		write_LCD_data(2*w%100/10+0x30);
		write_LCD_data(2*w%10+0x30);

		write_LCD_command(0x83);
		write_LCD_data('A');
		write_LCD_data(':');
		write_LCD_data(A/10+0x30);
		write_LCD_data(A%10+0x30);
		write_LCD_command(0x36);
		for(i=13;i<128;i++)
		{
			j=35-A*sin((i-13)*3.14/w);
			Draw_dots(i,j,1);
			delay(400);
		}
/**********以下为按键扫描函数**************/
		if(KEY1==0)			//模式键按下 
		{
			delay(2000);
			if(KEY1==0)
			{
				while(!KEY1);
				key_value++;
				if(key_value>2)
					key_value=0;
			}
		}
		if(key_value==1)			 //若选择的是周期模式
		{
			write_LCD_command(0x30);
			write_LCD_command(0x86);
			for(num=0;num<4;num++)
			{
				write_LCD_data(HZ1[num]); 	//显示"周期"汉字 
			}
			if(KEY2==0)						//加键按下时 
			{
				delay(1500);
				if(KEY2==0)
				{
					while(!KEY2);
					w=w+5;					//w加 
					if(w==65)
						w=10;
					Clear_GDRAM();
					write_LCD_command(0x36);//重新显示图形 
					display_BMP(ZB);	
				}	   
			}
			if(KEY3==0)
			{
				delay(2000);
				if(KEY3==0)
				{
					while(!KEY3);
					if(w>=10)
						w=w-5;
					Clear_GDRAM();
					write_LCD_command(0x36);
					display_BMP(ZB);		//重新显示图形
				}
			}	
		}

		if(key_value==2)				//若选择的是幅度模式
		{
			write_LCD_command(0x30);
			write_LCD_command(0x86);
			for(num=0;num<4;num++)
			{
				write_LCD_data(HZ2[num]);  
			}
			if(KEY2==0)
			{
				delay(1500);
				if(KEY2==0)
				{
					while(!KEY2);
					A=A+2;
					if(A==22)
						A=8;
					Clear_GDRAM();
					write_LCD_command(0x36);
					display_BMP(ZB);	
				}	   
			}
			if(KEY3==0)
			{
				delay(2000);
				if(KEY3==0)
				{
					while(!KEY3);
					if(A>=6)
						A=A-2;
					Clear_GDRAM();
					write_LCD_command(0x36);
					display_BMP(ZB);
				}
			}	
		}
	}	
}

⌨️ 快捷键说明

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