?? cs23-2.c
字號:
#include <REG51.H>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS1=P2^4;
sbit CS2=P2^3;
sbit RS=P2^7;
sbit RW=P2^6;
sbit EN=P2^5;
sbit RST=P2^2;
#define DataPort P0
/**********常用操作命令和參數定義***********/
#define DISPON 0x3f //顯示屏開
#define DISPOFF 0x3e //顯示屏關
#define DISPFIRST 0xc0 //起始行顯示定義
#define SETX 0x40 //X定位(頁)
#define SETY 0xb8 //Y定位(列)
#define Lcdbusy 0x80 //LCM忙判斷定義
/***********************************************/
#define MODL 0x00 //左區
#define MODM 0x40 //左區與中區分界
//#define MODR 0x80 //中區與右區分界
#define LCMLIMIT 0x80 //中區的邊界
//#define LCMLIMIT 0xc0 //右區的邊界(這里不用)
/*************************************************/
uchar col,row,cbyte; //列、行、數據的變量定義
bit xy; //畫線標志,"1"水平線,"0"垂直線。
/**************************************************/
void Lcminit(void); //液晶模塊初始化子函數
void Delay(unsigned long MS); //延時子函數
void lcdbusyL(void); //左區判忙子函數
void lcdbusyM(void); //中區判忙子函數
//void lcdbusyR(void); //右區判忙子函數(這里不用)
void Wrdata(uchar X); //寫數據至LCM
void Lcmcls(void); //LCM清屏
void Lcmclsxx(void); //LCM全屏置黑
void wtcom(void); //公用判忙等待子函數
void Locatexy(void); //光標定義
void WrcmdL(uchar X); //寫命令至左區
void WrcmdM(uchar X); //寫命令至中區
//void WrcmdR(uchar X); //寫命令至右區(這里不用)
void Rddata(void); //讀LCM狀態子函數
void Linehv(uchar length); //水平、垂直畫線子函數
void point(void); //畫點子函數
void Linexy(uchar endx, uchar endy); //畫斜線子函數
/************************復位子函數*************************/
void reset() //復位子函數
{ //復位子函數開始
RST=0; //復位端置0
Delay(20); //延時20ms
RST=1; //復位端置1
Delay(20); //延時20ms
} //復位子函數結束
/*********************主函數**********************/
void main(void)
{ //主函數開始
col=0; //定位0列、0頁
row=0;
Delay(10); //延時一會
Lcminit(); //液晶模塊初始化
Delay(1000); //延時一會
/***********以下使用畫直線與斜線的方法,畫出一條小舢舨*********/
/****************先畫出船上建筑**************/
col=0; //定位x方位0、y方位32
row=32;
xy=1; //水平線
Linehv(127); //畫線,長度127
/*----------------------------------------------*/
col=33; //定位x方位33、y方位48
row=48;
xy=1; //水平線
Linehv(30); //畫線,長度30
col=36; //定位x方位36、y方位32
row=32;
xy=0; //垂直線
Linehv(16); //畫線,長度16
col=64; //定位x方位64、y方位48
row=48;
xy=1; //水平線
Linehv(30); //畫線,長度30
col=91; //定位x方位91、y方位32
row=32;
xy=0; //垂直線
Linehv(16); //畫線,長度16
/*------------------------------------------------*/
col=10; //定位x方位10、y方位32
row=32;
xy=0; //垂直線
Linehv(27); //畫線,長度27
/************以下畫出船底的弧形***********/
col=0; //定位x方位0、y方位32
row=32;
Linexy(10,16); //畫斜線,終點為x方位10、y方位16
col=10; //定位x方位10、y方位16
row=16;
Linexy(30,8); //畫斜線,終點為x方位30、y方位8
col=30; //定位x方位30、y方位8
row=8;
Linexy(64,5); //畫斜線,終點為x方位64、y方位5
/*-----------------------------------------------------------------*/
col=65; //定位x方位65、y方位5
row=5;
Linexy(97,8); //畫斜線,終點為x方位97、y方位8
col=97; //定位x方位97、y方位8
row=8;
Linexy(117,16); //畫斜線,終點為x方位117、y方位16
col=117; //定位x方位117、y方位16
row=16;
Linexy(127,32); //畫斜線,終點為x方位127、y方位32
/*----------------------------------畫舢舨結束------------------------------------*/
while(1); //死循環
} //主函數結束
/*************************畫斜線子函數************************/
void Linexy(uchar endx, uchar endy)
{
register uchar t;
char xerr=0,yerr=0,delta_x,delta_y,distance;
uchar incx,incy;
delta_x=endx-col;
delta_y=endy-row;
if(delta_x>0)incx=1;
else if(delta_x==0)incx=0;
else incx=-1;
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;
else incy=-1;
delta_x=cabs(delta_x);
delta_y=cabs(delta_y);
if(delta_x>delta_y) distance=delta_x;
else distance=delta_y;
/*-----------開始畫線-------------*/
for(t=0;t<=distance+1;t++){
point();
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance){
xerr-=distance;
col+=incx;
}
if(yerr>distance){
yerr-=distance;
row+=incy;
}
}
}
/*********************畫水平、垂直線子函數***********************/
void Linehv(uchar length) /*函數名為Linehv的畫水平、垂直線子函數,定義
length 為線段長度的無符號字符型變量。*/
{ //畫水平、垂直線子函數開始
uchar xs,ys; //定義xs、ys 為無符號字符型變量。
if(xy){ys=col; //若xy為1,則為水平劃線
for(xs=0;xs<length;xs++){
col=ys+xs;
point();}
}
else {xs=row; //否則為垂直劃線
for(ys=0;ys<length;ys++)
{
row=xs+ys;
point();}
}
} //畫水平、垂直線子函數結束
/**********************畫點子函數***************************/
void point(void) //畫點子函數
{ //畫點子函數開始
uchar x1,y1,x,y; //定義x1、y1、x、y 為無符號字符型變量
x1=col; //x方向座標col賦予x1(暫存)
y1=row; //y方向座標row賦予y1(暫存)
row=y1>>3; //y1右移3位后賦予row,獲得y方向的頁地址
Rddata(); //讀取列(x)地址、頁(y)地址處的數據
y=y1&0x07; //計算出該頁(1字節)內的y軸點位置地址
x=0x01;
x=x<<y; //移入所畫點
Wrdata(cbyte|x); //畫上屏幕
col=x1; //恢復x、y座標
row=y1;
} //畫點子函數結束
/***************全屏幕清屏子函數**********************/
void Lcmcls(void) //函數名為Lcmcls的全屏幕清屏子函數
{ //函數開始
for(row=0;row<8;row++)
{for(col=0;col<LCMLIMIT;col++)
Wrdata(0);} //將數據0寫到屏幕
} //函數結束
/**********************全屏幕置黑子函數**********************/
void Lcmclsxx(void) //函數名為Lcmclsxx的全屏幕置黑子函數
{ //函數開始
for(row=0;row<8;row++)
for(col=0;col<LCMLIMIT;col++)
Wrdata(255); //將8位數據全1(255)寫到屏幕
} //函數結束
/*************讀取液晶x列、y頁座標處的數據至全局變量cbyte中************/
void Rddata(void) //函數名為Rddata的子函數
{ //函數開始
Locatexy(); //座標定位
DataPort=0xff; //LCM口置全1
RS=1; //選擇數據寄存器
RW=1; //選擇讀
EN=1; //使能
cbyte=DataPort; //虛讀一次
EN=0; //禁能
Locatexy(); //座標定位
DataPort=0xff; //LCM口置全1
RS=1; //選擇數據寄存器
RW=1; //選擇讀
EN=1; //使能
cbyte=DataPort; //讀取數據(真讀)
EN=0; //禁能
} //函數結束
/**************將數據X寫入液晶x列、y頁座標處***********/
void Wrdata(uchar X) //函數名為Wrdata 的子函數,定義X為無符號字符型變量
{ //函數開始
Locatexy(); //座標定位
RS=1; //選擇數據寄存器
RW=0; //選擇寫
DataPort=X; //將數據X寫入LCM口
EN=1; //使能
EN=0; //禁能
} //函數結束
/******************寫命令至左區********************/
void WrcmdL(uchar X) //函數名為WrcmdL 的子函數,定義X為無符號字符型變量
{ //函數開始
lcdbusyL(); //調用左區判忙子函數
RS=0; //選擇指令寄存器
RW=0; //選擇寫
DataPort=X; //數據輸出至數據口
EN=1;EN=0; //使能,禁能
} //函數結束
/********************寫命令至中區************************/
void WrcmdM(uchar X) //函數名為WrcmdM的子函數,定義X為無符號字符型變量
{ //函數開始
lcdbusyM(); //調用中區判忙子函數
RS=0; //選擇指令寄存器
RW=0; //選擇寫
DataPort=X; //數據輸出至數據口
EN=1;EN=0; //使能,禁能
} //函數結束
/**************寫命令至右區****************
void WrcmdR(uchar X) //函數名為WrcmdR的子函數,定義X為無符號字符型變量
{ //函數開始
lcdbusyR(); //調用右區判忙子函數
RS=0; //選擇指令寄存器
RW=0; //選擇寫
DataPort=X; //數據輸出至數據口
EN=1;EN=0; //使能,禁能
} //函數結束
***********************左區判忙子函數***********************/
void lcdbusyL(void) //函數名為lcdbusyL 的左區判忙子函數
{ //函數開始
CS1=1;CS2=0; //選中左區
wtcom(); //調用判忙等待子函數
} //函數結束
void lcdbusyM(void) //函數名為lcdbusyM的中區判忙子函數
{ //函數開始
CS1=0;CS2=1; //選中中區
wtcom(); //調用判忙等待子函數
} //函數結束
/*void lcdbusyR(void) //函數名為lcdbusyR的右區判忙子函數(這里不用)
{ //函數開始
CS1=?;CS2=?; //根據所用LCM器件決定取值
wtcom(); //調用判忙等待子函數
}*/ //函數結束
/***********公用判忙等待子函數********************/
void wtcom(void) //函數名為wtcom 的公用判忙等待子函數
{ //函數開始
RS=0; //選擇指令寄存器
RW=1; //選擇讀
DataPort=0xff; //數據0xff輸出至數據口
EN=1; //使能
while(DataPort&Lcdbusy);// 若LCM忙則等待
EN=0; //禁能
} //函數結束
/************根據設定的col、row座標數據,定位LCM下一個操作單元************/
void Locatexy(void) //函數名為Locatexy 的子函數
{ //函數開始
uchar x,y; //定義x,y為無符號字符型變量
switch(col&0xc0) //限定x列最大值為192
{
case 0:{lcdbusyL();break;} //判左區忙
case 0x40:{lcdbusyM();break;} //判中區忙
//case 0x80:{lcdbusyR();break;} //判右區忙(這里不用)
}
x=col&0x3f|SETX; //獲得x列(0~63)地址
y=row&0x07|SETY; //獲得y頁(0~7)地址
wtcom(); //調用判忙等待子函數
RS=0; //選擇指令寄存器
RW=0; //選擇寫
DataPort=y; //y頁地址傳送至LCM口
EN=1;EN=0; //使能,禁能
wtcom(); //調用判忙等待子函數
RS=0; //選擇指令寄存器
RW=0; //選擇寫
DataPort=x; //x列地址傳送至LCM口
EN=1;EN=0; //使能,禁能
} //函數結束
/*******************液晶屏初始化******************************/
void Lcminit(void) //函數名為Lcminit的液晶屏初始化子函數
{ //函數開始
reset(); //調用復位子函數
cbyte=DISPFIRST; //定義起始行為0行
WrcmdL(cbyte); //寫命令至左區
WrcmdM(cbyte); //寫命令至中區
//WrcmdR(cbyte); //寫命令至右區(這里不用)
cbyte=DISPOFF; //關閉顯示屏
WrcmdL(cbyte); //寫命令至左區
WrcmdM(cbyte); //寫命令至中區
//WrcmdR(cbyte); //寫命令至右區(這里不用)
cbyte=DISPON; //打開顯示屏
WrcmdL(cbyte); //寫命令至左區
WrcmdM(cbyte); //寫命令至中區
//WrcmdR(cbyte); //寫命令至右區(這里不用)
Lcmcls(); //清屏
Delay(10000); //延時一會
Lcmclsxx(); //全屏置黑
Delay(10000); //延時一會
Lcmcls(); //清屏
Delay(30000); //延時一會
col=0; //定位x方向為0列
row=0; //定位y方向為0頁
Locatexy(); //定位0列、0頁為LCM下一個操作單元
} //函數結束
/*********************延時子函數**********************/
void Delay(unsigned long MS)
{
while(MS!=0)MS--;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -