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

📄 main.c

📁 自己做的单片机Proteus仿真实例
💻 C
字号:
/*****http://hi.baidu.com/echoas**********
程序:MCS-51驱动AMPIRE128*64液晶
内容:LCD12864综合显示--汉字,图片、几何图形 
编译器:keil uVision3
开发板:Proteus仿真图
作者:大海橡树
整理日期:2011-01-28
修改:无 

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

					O(∩_∩)O~

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

#define LCD_databus P0 //LCD12864的8位数据口

sbit RS=P2^2; 	//RS为0---命令;1----数据 
sbit RW=P2^1; 	//RW为1---写;0---读 
sbit EN=P2^0; 	//使能端 
sbit CS1=P2^4; 	//片选1低电平有效,控制左半屏 
sbit CS2=P2^3; 	//片选1低电平有效,控制右半屏 

sbit KEY1=P3^0;
sbit KEY2=P3^1;
sbit KEY3=P3^2;	//三个按键控制口 


void delay(uint i)
{
	while(--i);
}
void Read_busy()//读“忙”函数-----数据线的最高位DB71则busy		
{
	P0=0x00;
   	RS=0;  
   	RW=1; 
	EN=1;
	while(P0 & 0x80);
	EN=0;
}

void write_LCD_command(uchar value)	//写命令函数 
{
   Read_busy();						//对LCD的每次读写都要读忙 
   RS=0;	 						//选择命令 
   RW=0; 							//读操作 
   LCD_databus=value;
   EN=1;							//EN由1----0锁存有效数据 
   _nop_();
   _nop_(); 
   EN=0;
}

void write_LCD_data(uchar value)//写数据函数	
{
   Read_busy();
   RS=1; 						//选择数据 
   RW=0;	
   LCD_databus=value;
   EN=1;						//EN由1----0锁存有效数据 
   _nop_();		
   _nop_();
   EN=0;
}

uchar Read_LCD(void)			//读数据函数 
{
	uchar value;
	Read_busy();
	LCD_databus=0xFF;			//先进行一次空读操作 
	RS=1;
	RW=1;
	EN=1;
	_nop_();
	_nop_();
	EN=0;
	
	LCD_databus=0xFF;			//读取真正的数据 
	RS=1;
	RW=1;
	EN=1;
	value=LCD_databus;
	_nop_();
	_nop_();
	EN=0;
	
	return value; 
}

void Set_page(uchar page)		//设置“页”LCD12864共8页,一页是8行点阵点	
{
  page=0xb8|page; 				//页的首地址为0xB8
  write_LCD_command(page);
}

void Set_line(uchar startline)  //设置显示的起始行	   
{
  startline=0xC0|startline;     //起始行地址为0xC0 
  write_LCD_command(startline); //设置从哪行开始:共0--63;一般从0 行开始显示
}

void Set_column(uchar column)	//设置显示的列	
{
  column=column &0x3f; 			//列的最大值为64
  column= 0x40|column; 			//列的首地址为0x40 
  write_LCD_command(column);	//规定显示的列的位置 
}

void SetOnOff(uchar onoff)		//显示开关函数:0x3E是关显示,0x3F是开显示   
{
	onoff=0x3e|onoff; 			//onoff:1---开显示;0---关显示
	write_LCD_command(onoff);
}

void SelectScreen(uchar screen)	//选择屏幕 
{ 						 
   switch(screen)
   { 
   	 case 0: CS1=0;CS2=0;break; //全屏     
     case 1: CS1=0;CS2=1;break;//左半屏        
     case 2: CS1=1;CS2=0;break;//右半屏       
     default:break; 
   }
}

void ClearScreen(uchar screen)	//清屏函数  
{ 	
     uchar i,j;
     SelectScreen(screen);		//0--全屏;1---左半屏;2---右半屏 
	 for(i=0;i<8;i++)	 		//控制页数0-7,共8页
	 {
        Set_page(i);
		Set_column(0);
      	for(j=0;j<64;j++)	   //控制列数0-63,共64列
	  	{
          write_LCD_data(0x00); //写入0,地址指针自加1 
      	}
     }					 
}

void init_LCD() 					//LCD的初始化  
{ 
	SetOnOff(1); 				//开显示
	SelectScreen(0);
	ClearScreen(0);				//清屏
	Set_line(0); 				//开始行:0
}
void Draw_dots(uchar x,uchar y,uchar color)
{
	uchar x_byte;
	uchar x_bit; 
	uchar Temp_data;		//暂时存放从LCD读出的数据 
	x_byte=(y>>3);  		//计算出该点属于哪个字节 
	x_bit=y-(x_byte<<3);	//属于字节的哪一位 

	
	if(x>63)				//x>63则显示在右半屏 
	{
		SelectScreen(2);
		x=x-64;
	}
	else					//显示在左半屏 
	{
		SelectScreen(1); 
	}
	Set_page(x_byte);		//设置行地址 
	Set_column(x);			//设置列地址
 	Temp_data=Read_LCD();	//先读出没打点前LCD中的数据 
	switch(color)
	{
		case 0x01 : Temp_data &= ~(1<<x_bit);break;	//擦除
		case 0x02 : Temp_data ^= (1<<x_bit); break;	//反白 
		case 0x03 : Temp_data |= (1<<x_bit); break;	//画点 
		default : break;
	} 
	
	Set_page(x_byte);
	Set_column(x);
	write_LCD_data(Temp_data);	//将处理后的数据送到LCD中显示 
	
}
/**********************************
两点间画直线:
x1<x2<127,y1<y2<64
***********************************/                    
void Draw_line(unsigned char x1,y1,x2,y2)
{
	unsigned char i;	
	for(i=x1;i<x2+1;i++)	
		Draw_dots(i,(y2-y1)*(i-x1)/(x2-x1)+y1,2);
}
/**********************************
画圆:
(x,y)为圆心,r为半径
***********************************/ 
void Draw_circle(unsigned char x,y,r)
{
	unsigned char i;	
	for(i=x-r;i<x+r+1;i++)
	{
		Draw_dots(i,y-sqrt(r*r-(x-i)*(x-i)),2);		
		Draw_dots(i,y+sqrt(r*r-(x-i)*(x-i)),2);		
	}
}
/**********************************
两矩形:
(x1,y1)为矩形左上角坐标点
(x2,y2)为矩形右上角坐标点
***********************************/ 
void Draw_retic(uchar x1,uchar y1,uchar x2,uchar y2)//画正方形,x1,y1为左上角坐标,x2,y2为右下角坐标
{
	uchar i;
	for(i=0;i<=x2-x1;i++)
	{  
		Draw_dots(x1+i,y1,2);  
		Draw_dots(x1+i,y2,2);  
	}
	for(i=0;i<=y2-y1;i++)
	{  
		Draw_dots(x1,y1+i,2);  
		Draw_dots(x2,y1+i,2);  
	}
}


void Display_ASCII(uchar screen,uchar page,uchar column,uchar *p)
{
	uchar i;
	SelectScreen(screen);
	Set_page(page);
	Set_column(column);
	for(i=0;i<8;i++)			//显示字符上半部分:8*8 
	{
		write_LCD_data(p[i]);
	}
	Set_page(page+1);			//显示字符下半部分:8*8 
	Set_column(column);
	for(i=0;i<8;i++)
	{
		write_LCD_data(p[i+8]);
	} 
}  
void Display_HZ(uchar screen,uchar page,uchar column,uchar *p)
{
	uchar i;
	SelectScreen(screen);
	Set_page(page);					//写上半页:16*8 
	Set_column(column*16); 			//控制列
	for(i=0;i<16;i++)  				//控制16列的数据输出
	{
		write_LCD_data(p[i]); 		//汉字的上半部分 
	}
	Set_page(page+1);				//写下半页:16*8 
	Set_column(column*16);			//控制列
    for(i=0;i<16;i++)				//控制16列的数据输出
	{
		write_LCD_data(p[i+16]);	//汉字的下半部分 
	}
} 

void Display_picture(uchar a[][64])//显示图形—128*64大小 
{
	uchar i,j;
	
	for(j=0;j<8;j++)
	{	
		SelectScreen(1);
		Set_page(j);
		Set_column(0);
		for(i=0;i<64;i++)
		{
			write_LCD_data(a[2*j][i]);//每隔一行取一次数组中的数据
		}
		SelectScreen(2);
		Set_page(j);
		Set_column(0);
		for(i=0;i<64;i++)
		{
			write_LCD_data(a[2*j+1][i]);//每隔一行取一次数组中的数据
		}	
	}	
}

void key_scan(void)
{
	uchar i;
	if(KEY1==0)						//按键1按下,显示汉字 
	{
		delay(5000);
		if(KEY1==0)
		{
			while(!KEY1);
			ClearScreen(0);
			for(i=8;i>0;i--)	  	//滚屏
			{
				Display_HZ(1,0+i,2,huan);
				Display_HZ(1,0+i,3,ying);
				Display_HZ(2,0+i,0,fang);
				Display_HZ(2,0+i,1,wen);
				Display_HZ(1,2+i,0,da);
				Display_HZ(1,2+i,1,hai);
				Display_HZ(1,2+i,2,xiang);
				Display_HZ(1,2+i,3,shu);
				Display_HZ(2,2+i,0,bai);
				Display_HZ(2,2+i,1,du);
				Display_HZ(2,2+i,2,kong);
				Display_HZ(2,2+i,3,jian);
				delay(30000);
				ClearScreen(0);
			}
			Display_HZ(1,0+i,2,huan);
			Display_HZ(1,0+i,3,ying);
			Display_HZ(2,0+i,0,fang);
			Display_HZ(2,0+i,1,wen);
			Display_HZ(1,2+i,0,da);
			Display_HZ(1,2+i,1,hai);
			Display_HZ(1,2+i,2,xiang);
			Display_HZ(1,2+i,3,shu);
			Display_HZ(2,2+i,0,bai);
			Display_HZ(2,2+i,1,du);
			Display_HZ(2,2+i,2,kong);
			Display_HZ(2,2+i,3,jian);			
		}
	}

	if(KEY2==0)				//按键2按下,显示图片---大海橡树 
	{
		delay(5000);
		if(KEY2==0)
		{
			while(!KEY2);
			ClearScreen(0);
			Display_picture(BMP);
		}
	}

	if(KEY3==0)				//按键3按下,显示几何图形 
	{
		delay(5000);
		if(KEY3==0)
		{
			while(!KEY3);
			ClearScreen(0);
			Display_HZ(1,0,2,zhi);
			Display_HZ(1,0,3,xian);
		
			Display_HZ(2,2,1,ju);
			Display_HZ(2,2,2,xing);
		
			Display_HZ(1,4,1,yuan);
		
			Draw_line(0,0,127,63);
			Draw_retic(70,0,120,33);
			Draw_circle(30,40,20);
		}
	}
}
void main()
{  
   	init_LCD();					//初始12864  
   	ClearScreen(0);				//清屏
   	Set_line(0);				//显示开始行  
	Display_HZ(1,2,1,qing);
	Display_HZ(1,2,2,an);
	Display_HZ(1,2,3,button);
	Display_HZ(2,2,0,xuan);
	Display_HZ(2,2,1,ze);
	Display_HZ(2,2,2,andsoon);	//上电显示:“请按键选择…” 
	while(1)
	{
		
		key_scan();
	}
}

⌨️ 快捷键说明

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