PIC驅(qū)動JM240128液晶
頭文件
本文引用地址:http://www.ex-cimer.com/article/201611/317659.htm#ifndef JM240_H
#define JM240_H
#include "main.h"
//define port
#define DB PORTD
#define DB_DIR TRISD
#define WR RA0
#define RD RA1
#define CE RA2
#define CD RA3
#define RST RA4
typedef struct JM240
{
uint graphic_add ;//only use graphic mode
uchar graphic_width ;//define graphic width
uint offset ;// offset address of currect page
uint cur_page ;//current page
uchar char_width ;//width of charactor
uchar chn_width ;//width of chn
} JM240 ;
//define the first address of seperative page
extern JM240 jm ;
enum state{} ;
//define basic function
void init_jm240() ;//init JM240 include initiating control port ,JM240 struct and iniatiating LCD
void send_byte(uchar data) ;//send data
void send_cmd(uchar cmd) ;//send a cmd
uchar ch_status() ;//get status word
void ch_busy(uchar flag) ;//check whether the current lcd is busy or not
void rst_lcd() ;//reset lcd
uchar rd_data() ;
//define high zone function
void wr_data(uchar dat) ;
void wr_cmd0(uchar cmd) ;//no para command
void wr_cmd1(uchar data,uchar cmd) ;//one para command
void wr_cmd2(uchar dat1,uchar dat2,uchar cmd) ;//two para command
void wr_cmd3(uint data,uchar cmd) ;//one para of int type command
void set_mode(uchar mode) ;
void enable_autowr(uchar flag) ;
void enable_autord(uchar flag) ;
void auto_wr(uchar dat) ;
uchar auto_rd() ;
//define higher zone function
void str_disp(const uchar *str,uchar x,uchar y) ;//display string through internal character library
void show_char(uchar data,uchar x,uchar y) ;
void show_chn(const uchar *chn,uchar x,uchar y) ;
void chns_disp(const uchar *chn,uchar x,uchar y,uchar count) ;
void show_img(uchar x,uchar y,uchar x1,uchar y1,const uchar *img) ;
void lcd_refresh(const uchar *img) ;
void clr_lcd(uchar x,uchar y,uchar x1,uchar y1) ;
void clr_ram() ;
void wr_img(uchar x,uchar y,uchar width,uchar height,const uchar *img) ;
void set_add(uint ad) ;
void add_xy(uchar x,uchar y) ;//move ram pointer
void add_add(uint x) ;
void set_graphic(uint add,uchar width) ;//set graphic par
//define draw
void draw_vline(uchar x,uchar y,uchar height) ;
void draw_hline(uchar x,uchar y,uchar width) ;
void draw_frame(uchar x,uchar y,uchar width,uchar height) ;
void draw_point(uchar x,uchar y) ;
void draw_page(uchar num) ;
#endif
子程序
#include "jm240.h"
#include "ascii0816.h"
const uint add[]={0x0000,0x0F00,0x1E00,0x2D00,0x3C00,0x4B00,0x5A00,0x6900,0x7800,0x9700,0xA600,0xB500,0xC400} ;
JM240 jm ;
void init_jm240()
{
//set the directio of port
DB_DIR=0 ;
ADCON1=0x06 ;
TRISA=TRISA&0xC0 ;
//init global variable
jm.graphic_add=0x0000 ;
jm.graphic_width=30 ;
jm.cur_page=0 ;
jm.offset=0x0000 ;
jm.char_width=8 ;
jm.chn_width=16 ;
//init
rst_lcd() ;
set_graphic(jm.graphic_add,jm.graphic_width) ;
wr_cmd0(0x80) ;// 或模式
wr_cmd0(0x98) ;//note here must start graphic display
clr_ram() ;
}
//restart lcd
void rst_lcd()
{
RST=0 ;
DelayUs(50) ;
RST=1 ;
DelayMs(50) ;
}
//get the currrent state of lcd
uchar ch_status()
{
uchar temp ;
CD=1 ;
WR=1 ;
CE=0 ;
DB_DIR=0x00 ;
DB=0xff ;
RD=0 ;
DB_DIR=0xFF ;
temp=DB ;
RD=1 ;
CE=1 ;
DB_DIR=0x00 ;
return temp ;
}
//check whether lcd is busy or not at present
void ch_busy(uchar flag)
{
uchar temp1,temp2 ;
if(!flag)//one write or read status flag
temp2=0x03 ;
else
{
if(flag==1)// auto write status flag check
temp2=0x08 ;
else//auto read state flag check
temp2=0x04 ;
}
do
{
temp1=ch_status() ;
temp1=temp1&temp2 ;
}while(temp1!=temp2) ;
}
//set graphic mode
void set_graphic(uint ad,uchar width)
{
jm.graphic_add=ad ;
jm.graphic_width=width ;
wr_cmd3(ad,0x42) ;
wr_cmd2(width,0x00,0x43) ;
}
//read a byte from lcd
uchar rd_data()
{
uchar temp ;
ch_busy(0) ;
CD=0 ;
DB=0 ;
CE=0 ;
DB_DIR=0x00 ;
DB=0xff ;
RD=0 ;
DB=0 ;
CE=0 ;
DB_DIR=0xFF ;
temp=DB ;
RD=1 ;
CD=1 ;
return temp ;
}
//send a byte to lcd ram
void send_byte(uchar dat)
{
RD=1 ;
DB_DIR=0x00 ;
CE=0 ;
CD=0 ;
WR=0 ;
DB=dat ;
//DelayUs(2) ;
CE=1 ;
CD=1 ;
WR=1 ;
}
//send a command word to lcd registor
void send_cmd(uchar cmd)
{
RD=1 ;
DB_DIR=0x00 ;
CE=0 ;
CD=1 ;
WR=0 ;
DB=cmd ;
//DelayUs(2) ;
CE=1 ;
CD=1 ;
WR=1 ;
}
//write a byte
void wr_data(uchar data)
{
ch_busy(0) ;
send_byte(data) ;
}
//write a command with no parameter
void wr_cmd0(uchar cmd)
{
ch_busy(0) ;
send_cmd(cmd) ;
}
//write a command with one parametre
void wr_cmd1(uchar para,uchar cmd)
{
ch_busy(0) ;
send_byte(para) ;
ch_busy(0) ;
send_cmd(cmd) ;
}
//write a cammand with two parameters
void wr_cmd2(uchar para1,uchar para2,uchar cmd)
{
ch_busy(0) ;
send_byte(para1) ;
ch_busy(0) ;
send_byte(para2) ;
ch_busy(0) ;
send_cmd(cmd) ;
}
//write a command with a uint parameter
void wr_cmd3(uint para,uchar cmd)
{
uchar temp,temp1 ;
temp=(uchar )para ;
temp1=(uchar)(para>>8) ;
wr_cmd2(temp,temp1,cmd) ;
}
//autowrite
void auto_wr(uchar dat)
{
ch_busy(1) ;
send_byte(dat) ;
}
//autoread
uchar auto_rd()
{
uchar temp ;
ch_busy(2) ;
CD=0 ;
DB=0 ;
CE=0 ;
DB_DIR=0x00 ;
DB=0xff ;
RD=0 ;
DB=0 ;
CE=0 ;
DB_DIR=0xFF ;
temp=DB ;
RD=1 ;
CD=1 ;
return temp ;
}
//enable auto write or not
void enable_autowr(uchar flag)
{
if(flag)
wr_cmd0(0xB0) ;
else
wr_cmd0(0xB2) ;
}
//enable autoread or not
void enable_autord(uchar flag)
{
if(flag)
wr_cmd0(0xB1) ;
else
wr_cmd0(0xB3) ;
}
//define higher function
//current display ram address add add
void add_add(uint ad)
{
uint temp ;
jm.offset+=ad ;
temp=jm.cur_page+jm.offset ;
wr_cmd3(temp,0x24) ;
}
//set addres s pointer
// had better not use this function
void set_add(uint ad)
{
jm.cur_page=ad ;
wr_cmd3(ad,0x24) ;
}
//move address pointer to y row and x column
void add_xy(uchar x,uchar y)
{
uint temp ;
temp=(uint)x+((uint)y)*jm.graphic_width ;
jm.offset=temp ;
temp=temp+jm.cur_page ;
wr_cmd3(temp,0x24) ;
}
void str_disp(const uchar *str,uchar x,uchar y)
{
uint temp1 ;
uchar temp,temp2,j,i ;
//wr_cmd0(0x9F) ;
//wr_cmd0(0x81) ;
//add_xy(1,x,y) ;
//while(*str!=/0)
//{
//temp=*(str++)-0x20 ;
//wr_cmd1(temp,0xC0) ;//address auto add 1
//}
//wr_cmd0(jm.disp_mode)
i=x ;
y=y*16 ;
while(*str!=/0)
{
add_xy(i++,y) ;
temp1=(*(str++)-0x20)*16 ;
for(j=0;j<16;j++)
{
temp2=ascii0816[temp1+j];
wr_cmd1(temp2,0xC4) ;
add_add(30) ;
}
}
}
//here as long as we understand how lcd scan screen,we can
//implement what function we want
//this lcd scan in horizon mode
void show_char( uchar dat ,uchar x,uchar y)
{
uint temp1 ;
uchar i ,j ,temp2;
y=y*16 ;
add_xy(x,y) ;
temp1=(dat-0x20)*16 ;
//for one char is composed of 16*8 dots ,so we need scan 16 times in horizontal way
for(j=0;j<16;j++)
{
temp2=ascii0816[temp1+j];
//one times we write in 8 dots
wr_cmd1(temp2,0xC4) ;
add_add(30) ;
}
}
void show_chn(const uchar *chn,uchar x,uchar y)
{
uchar i ;
//x=x*8;
y=y*16 ;
add_xy(x,y) ;
for(i=0;i<16;i++)
{
wr_cmd1(*chn++,0xC4) ;
add_add(1) ;
wr_cmd1(*chn++,0xC4) ;
add_add(29) ;
}
}
void chns_disp(const uchar *chn,uchar x,uchar y,uchar count)
{
uchar i,j ;
for(i=0;i
add_xy(x+i*2,y) ;
for(j=0;j<16;j++)
{
wr_cmd1(*chn++,0xC4) ;
add_add(1) ;
wr_cmd1(*chn++,0xC4) ;
add_add(29) ;
}
//y=y+16 ;
}
}
void show_img(uchar x,uchar y,uchar width,uchar height,const uchar *img)
{
uchar i ,j,temp1,temp2 ;
//set_add(jm.cur_page) ;
//temp1=(x1-x)/8 ;
//temp2=(y1-y) ;
add_xy(0,y) ;
add_add(x) ;
for(i=0;i
for(j=0;j
wr_cmd1(*img++,0xC4) ;
add_add(1) ;
}
add_add(30-width) ;
}
}
void clr_lcd(uchar x,uchar y,uchar width,uchar height)
{
uchar i,j;
width=width/8 ;
//add_xy(0,x,y) ;
for(i=0;i
add_xy(0,y+i) ;//move to the position where you want to clear
add_add(x) ;
enable_autowr(1) ;
for(j=0;j
auto_wr(0x00) ;
}
enable_autowr(0) ;
}
}
void clr_ram()
{
uint i ;
set_add(jm.cur_page) ;
enable_autowr(1) ;
for(i=0;i<0xFFFE;i++)
{
auto_wr(0x00) ;
}
enable_autowr(0) ;
set_add(jm.cur_page) ;
}
//this function has some problems
void wr_img(uchar x,uchar y,uchar width,uchar height,const uchar *img)
{
uchar i,j,flag ;
if(jm.offset<0xF00)
flag=0 ;
else
flag=1 ;
width=width/8 ;
for(i=0;i
add_xy(x,y+i) ;//move to the position where you want to clear
enable_autowr(1) ;
for(j=0;j
auto_wr(*img++) ;
}
enable_autowr(0) ;
}
}
//draw picture
void draw_vline(uchar x,uchar y,uchar height)
{
uchar i ;
add_xy(x,y) ;
for(i=0;i
wr_cmd0(0xF8) ;
add_add(30) ;
}
}
void draw_hline(uchar x,uchar y,uchar width)
{
uchar i;
add_xy(x,y) ;
width=width/8 ;
enable_autowr(1) ;
for(i=0;i
enable_autowr(0) ;
}
void draw_frame(uchar x,uchar y,uchar width,uchar height)
{
uchar i,j ;
width=width/8 ;
//draw two horizon line
add_xy(x,y) ;
enable_autowr(1) ;
for(i=0;i
enable_autowr(0) ;
add_xy(x,y+height) ;
enable_autowr(1) ;
for(i=0;i
enable_autowr(0) ;
//draw two vertical line
add_xy(x,y) ;
for(i=0;i
wr_cmd0(0xFF) ;
add_add(29) ;
wr_cmd0(0xF8) ;
add_add(1) ;
}
}
void draw_point(uchar x,uchar y)
{
uchar temp ;
temp=x%8 ;
x=x/8 ;
add_xy(0,y) ;
add_add(x) ;
temp=7-temp+0xF8 ;
wr_cmd0(temp) ;
}
void draw_page(uchar num)
{
uint temp=jm.cur_page ;
set_add(add[num]) ;
clr_lcd(0,0,239,127) ;
draw_frame(0,0,240,126) ;
draw_hline(1,105,220) ;
draw_vline(1,20,90) ;
//chns_disp(str,8,3,6) ;
//chns_disp(str1,205,102,2) ;
//show_chn(str2,0,2) ;
//show_chn(str2+32,0,3) ;
draw_point(12,3) ;
set_add(temp) ;
}
測試程序
#include
#include
#include "main.h"
#include "jm240.h"
void interrupt main_int()
{
;
}
void init_all()
{
init_jm240() ;
}
const uchar str[]={
/*---------------實----------------*/
0x01,0x00,0x00,0x80,0x3F,0xFE,0x28,0x04,0x46,0x88,0x04,0x80,0x08,0x80,0x06,0x80,
0x04,0x80,0x7F,0xFE,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x18,0x18,0x60,0x10,
/*---------------時----------------*/
0x00,0x10,0x00,0x10,0x7C,0x10,0x44,0x10,0x47,0xFE,0x44,0x10,0x7C,0x10,0x45,0x10,
0x44,0x90,0x44,0x90,0x7C,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x20,
/*---------------溫----------------*/
0x40,0x00,0x27,0xF0,0x24,0x10,0x07,0xF0,0x94,0x10,0x54,0x10,0x17,0xF0,0x20,0x00,
0x2F,0xFC,0xC9,0x24,0x49,0x24,0x49,0x24,0x49,0x24,0x49,0x24,0x5F,0xFE,0x40,0x00,
/*---------------度----------------*/
0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x2F,0xFC,0x22,0x20,0x23,0xE0,
0x20,0x00,0x27,0xF8,0x22,0x10,0x21,0x20,0x20,0xC0,0x41,0x30,0x46,0x0E,0x98,0x04,
/*---------------曲----------------*/
0x04,0x40,0x04,0x40,0x04,0x40,0x3F,0xFC,0x24,0x44,0x24,0x44,0x24,0x44,0x24,0x44,
0x3F,0xFC,0x24,0x44,0x24,0x44,0x24,0x44,0x24,0x44,0x3F,0xFC,0x20,0x04,0x00,0x00,
/*---------------線----------------*/
0x10,0x40,0x18,0x50,0x10,0x4C,0x20,0x48,0x23,0xFC,0x48,0x40,0xF8,0x40,0x13,0xFE,
0x20,0x40,0x7C,0x48,0x00,0x30,0x00,0x22,0x1C,0xD2,0xE3,0x0A,0x00,0x06,0x00,0x02,
} ;
const uchar str1[]=
{
/*---------------時----------------*/
0x00,0x10,0x00,0x10,0x7C,0x10,0x44,0x10,0x47,0xFE,0x44,0x10,0x7C,0x10,0x45,0x10,
0x44,0x90,0x44,0x90,0x7C,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x50,0x00,0x20,
/*---------------間----------------*/
0x20,0x00,0x13,0xFC,0x10,0x04,0x40,0x04,0x47,0xE4,0x44,0x24,0x44,0x24,0x47,0xE4,
0x44,0x24,0x44,0x24,0x47,0xE4,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x14,0x40,0x08,
} ;
const uchar str2[]=
{
/*---------------溫----------------*/
0x40,0x00,0x27,0xF0,0x24,0x10,0x07,0xF0,0x94,0x10,0x54,0x10,0x17,0xF0,0x20,0x00,
0x2F,0xFC,0xC9,0x24,0x49,0x24,0x49,0x24,0x49,0x24,0x49,0x24,0x5F,0xFE,0x40,0x00,
/*---------------度----------------*/
0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x2F,0xFC,0x22,0x20,0x23,0xE0,
0x20,0x00,0x27,0xF8,0x22,0x10,0x21,0x20,0x20,0xC0,0x41,0x30,0x46,0x0E,0x98,0x04,
};
const char dat[]=
{
0,1,2,3,4,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,22,23,24,25,26,26,27,28,
28,29,30,30,31,31,32,32,33,33,
33,34,34,34,34,35,35,35,35,35,
35,35,35,35,35,35,34,34,34,34,
33,33,32,32,32,31,30,30,29,29,
28,27,27,26,25,24,24,23,22,21,
20,19,18,17,16,15,14,13,12,11,
10,9,8,7,6,5,4,3,2,1,
-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,
-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,
-21,-22,-23,-24,-24,-25,-26,-27,-27,-28,
-29,-29,-30,-30,-31,-32,-32,-32,-33,-33,
-34,-34,-34,-34,-35,-35,-35,-35,-35,-35,
-35,-35,-35,-35,-35,-34,-34,-34,-34,-33,
-33,-33,-32,-32,-31,-31,-30,-30,-29,-28,
-28,-27,-26,-26,-25,-24,-23,-22,-22,-21,
-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,
-10,-9,-8,-7,-6,-4,-3,-2,-1,0,
};
const char dat1[]=
{-3,-2,-1,0,
0,1,2,3,4,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,22,23,24,25,26,26,27,28,
28,29,30,30,31,31,32,32,33,33,
33,34,34,34,34,35,35,35,35,35,
35,35,35,35,35,35,34,34,34,34,
33,33,32,32,32,31,30,30,29,29,
28,27,27,26,25,24,24,23,22,21,
20,19,18,17,16,15,14,13,12,11,
10,9,8,7,6,5,4,3,2,1,
-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,
-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,
-21,-22,-23,-24,-24,-25,-26,-27,-27,-28,
-29,-29,-30,-30,-31,-32,-32,-32,-33,-33,
-34,-34,-34,-34,-35,-35,-35,-35,-35,-35,
-35,-35,-35,-35,-35,-34,-34,-34,-34,-33,
-33,-33,-32,-32,-31,-31,-30,-30,-29,-28,
-28,-27,-26,-26,-25,-24,-23,-22,-22,-21,
-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,
-10,-9,-8,-7,-6,-4,
};
bank1uchar i,j,tmp1;
bank1uint temp ;
void test()
{
set_graphic(0x0000,30) ;
set_add(0x0F00) ;
set_graphic(0x0000,30) ;
clr_lcd(2,18,220,80) ;
set_add(0x0F00) ;
for(i=0;i<200;i++)
{
//if(i+j<200)
//tmp1=dat[i+j]+55 ;
//else
//tmp1=dat[200-i-j]+55 ;
draw_point(16+i,20) ;
}
if(j>=200)
j=0 ;
else
j++ ;
DelayMs(255) ;
DelayMs(255) ;
set_graphic(0x0F00,30) ;
set_add(0x0000) ;
clr_lcd(2,18,220,80) ;
set_graphic(0x0F00,30) ;
set_add(0x0000) ;
for(i=0;i<200;i++)
{
//if(i+j<200)
//tmp1=dat[i+j]+55 ;
//else
//tmp1=dat[200-i-j]+55 ;
draw_point(16+i,j) ;
}
if(j>=200)
j=0 ;
else
j++ ;
}
void main()
{
//const uchar str1[]="hello world!" ;
init_all() ;
wr_cmd0(0x98) ;
clr_lcd(1,1,240,128) ;
draw_frame(0,0,240,126) ;
draw_hline(1,105,220) ;
draw_vline(1,20,90) ;
chns_disp(str,8,3,6) ;
chns_disp(str1,205,102,2) ;
show_chn(str2,0,2) ;
show_chn(str2+32,0,3) ;
draw_point(12,3) ;
//clr_lcd(0,0,240,128) ;
//show_img(0,0,240,128,img) ;
for(i=0;i<200;i++)
{
draw_point(16+i,dat[i]+55) ;
}
//clr_lcd(2,18,220,80) ;
temp=jm.cur_page ;
set_add(0x0F00) ;
clr_lcd(1,1,240,128) ;
draw_frame(0,0,240,126) ;
draw_hline(1,105,220) ;
draw_vline(1,20,90) ;
chns_disp(str,8,3,6) ;
chns_disp(str1,205,102,2) ;
show_chn(str2,0,2) ;
show_chn(str2+32,0,3) ;
draw_point(12,3) ;
//clr_lcd(0,0,240,128) ;
//show_img(0,0,240,128,img) ;
for(i=0;i<200;i++)
{
draw_point(16+i,dat1[i]+55) ;
}
set_add(temp) ;
j=0 ;
while(1)
{
//set_graphic(0x0000,30) ;
//set_add(0x0F00) ;
////set_graphic(0x0000,30) ;
//clr_lcd(2,18,220,80) ;
//set_add(0x0F00) ;
//for(i=0;i<200;i++)
//{
//
//if(i+j<200)
//tmp1=dat[i+j]+55 ;
//else
//tmp1=dat[200-i-j]+55 ;
//
//draw_point(16+i,2) ;
//}
////if(j>=200)
//// j=0 ;
////else
//j++ ;
////DelayMs(255) ;
////DelayMs(255) ;
//
//set_graphic(0x0F00,30) ;
//set_add(0x0000) ;
//clr_lcd(2,18,220,80) ;
//set_graphic(0x0F00,30) ;
//set_add(0x0000) ;
//for(i=0;i<200;i++)
//{
//if(i+j<200)
//tmp1=dat[i+j]+55 ;
//else
//tmp1=dat[200-i-j]+55 ;
//
//draw_point(16+i,5) ;
//}
////if(j>=200)
//// j=0 ;
////else
//j++ ;
////DelayMs(255) ;
////DelayMs(255) ;
test() ;
}
}
本來想用來畫動態(tài)曲線的,可是PIC16F877A的RAM空間太小,不能容下200字節(jié)的數(shù)組,所以也就沒有做完,不過思路就有了,
就是建立兩個緩沖區(qū),一個緩沖區(qū)顯示,一個緩沖區(qū)用于寫數(shù)據(jù),當(dāng)一個緩沖區(qū)在顯示時,向另一個緩沖區(qū)中寫數(shù)據(jù),然后移動顯示指針,顯示另一個緩沖區(qū)的數(shù)據(jù),再重復(fù)上面的操作!這樣顯示比使用一個緩沖區(qū)效果要好!不會因刷屏而造成屏幕的閃爍!
評論