天天看點

51單片機控制12864繪制序列槽發送的距離變化曲線

51單片機控制12864繪制序列槽發送的距離變化曲線

資料采集端使用STM32為主要,超音波子產品測距,測距資訊經過壓縮,序列槽發送給51單片機,51單片機控制12864顯示距離變化曲線。

51單片機控制12864繪制序列槽發送的距離變化曲線
51單片機控制12864繪制序列槽發送的距離變化曲線
51單片機控制12864繪制序列槽發送的距離變化曲線

程式

#include<reg52.h>
#include<math.h>
#include"ZB.h"
#define uchar unsigned char
#define uint  unsigned int

#define LCD_databus P0 //LCD資料總線連接配接P0口 

sbit RS=P2^6;
sbit RW=P2^5;
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 DisTance;	//距離作為橫軸13-127  X 13-127
uchar RSSI;	//信号強度作為縱軸20-63  Y 0-39
unsigned Interrupt_Flag=1;
unsigned int receiveData;
uchar HZ1[]="周期";
uchar HZ2[]="幅度";
//uchar DELE_DATA[115];
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 Usart() interrupt 4
{
	Interrupt_Flag=0;
	RSSI=SBUF;
	RI = 0;
	SBUF=RSSI;
	while(!TI);			
	TI=0;						
	
}

void uart(void)					 
{
	SCON=0x40;				 
	REN=1;						 
	TMOD=0x20;				 
	TH1=0xfd,TL1=0xfd;		                     
	TR1=1;
    ES=1;						//打開接收中斷
	EA=1;						//打開總中斷				 
}	


void main()
{
	uchar i;
	uchar w=10,A=10;	//A是正弦波的振幅
	uart();
	init_LCD();
	Clear_GDRAM();
	write_LCD_command(0x36);
	//display_BMP(ZB);	//坐标
	while(1)
	{		
		for(i=13;i<128;i++)		//畫圖 Y軸方向0-39  X = 13-127
		{
			while(Interrupt_Flag==1);	//等待序列槽中斷,接收資料後标志位清零,進行畫點
			Draw_dots(i,RSSI,1);	//将得到的資料進行顯示
			Interrupt_Flag=1;	//從置标志位,繼續等待
		}			
		  Clear_GDRAM();	//清屏函數
	      write_LCD_command(0x36);
	    //  display_BMP(ZB);	//坐标
	}	
}




           

繼續閱讀