天天看点

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);	//坐标
	}	
}




           

继续阅读