ST7920控制器反显程序例程

发布时间:2018/7/27 10:37:21

/*ST7920驱动的12864液晶,3线模式,带任意位置汉字反白程序AVR单片机

//ST7920驱动的带字库的液晶虽然有反白指令,但是不能单行反白,单字反白,它只能1、3两行或2、4两行同时

//反白。本程序克服了这个缺点,可以设置任意位置的文字反白与取消反白。希望对有需要的朋友有用*/

/***********************************************************************

工    程:ST7920驱动的12864液晶的3线串行驱动模式    

引脚定义:RS(CS)=====>PB5

   RW(SID)====>PB6

         EN(SCLK)===>PB7

   PSB为硬件控制,接高电平为8位或4位的并行模式,接低电平为串行模式

   本例程使用3线串行模式

************************************************************************/

#include <iom128v.h>

#include <macros.h>

#define uchar unsigned char

#define uint unsigned int

#define nop()  NOP()

#define xtal 8

#define CS  PB5

#define SID  PB6

#define SCLK PB7

#define Set_CS() DDRB |= (1<<CS);PORTB |= (1<<CS)

#define Set_SID() DDRB |= (1<<SID);PORTB |= (1<<SID)

#define Set_SCLK() DDRB |= (1<<SCLK);PORTB |= (1<<SCLK)

#define Clr_CS() DDRB |= (1<<CS);PORTB &=~(1<<CS)

#define Clr_SID() DDRB |= (1<<SID);PORTB &=~(1<<SID)

#define Clr_SCLK() DDRB |= (1<<SCLK);PORTB &=~(1<<SCLK)

//====================================================================

//函数声明

void Delay(uint ms);      //延时子程序

void W_1byte(uchar RW, uchar RS, uchar W_data);

void Write_8bits(uint W_bits);

void LCD_Init(void);

void Char_Set_XY(uchar x, uchar y, uchar *p);

void Set_Draw(void);

//设定哪一行,从那一个位置开始到那一个位置结束使用反白

//x=液晶屏上汉字的位置(1~8);end_x=汉字结束的地址(1~8);y=1~4行

//clear=1:清除反白;clear=0:设置反白;

void Set_White(uchar x,uchar y,uchar end_x,uchar clear);  

void Draw_Pic(uchar x, uchar y, const uchar *Draw);

/********************************************************************/

void main()

{

uchar i = 0;

PORTB = 0XFF;   //

DDRB = 0XFF;   //PB口全部设为输出模式

Clr_CS();

Clr_SID();

Clr_SCLK();

LCD_Init();

Delay(50);

LCD_Init();     //初始化两边是关键,否则液晶上电重起将不能显示

while(1)

{

 nop();

 nop();

 Delay(500);

 Char_Set_XY(0,0,"ST7920_3_wires");

 Char_Set_XY(2,1,"反白练习");

 Char_Set_XY(0,2,"可以单字反白或不");

 Char_Set_XY(3,3,"反白");

 Delay(2000);

 Delay(2000);

 Set_Draw();

 Delay(100);

 Set_White(1,1,7,0);   //第1行,第1个汉字位置到第8汉字位置反白

 Set_White(3,2,6,0);   //第2行,第3个汉字位置到第6汉字位置反白

 Set_White(1,3,8,0);   //第3行,第1个汉字位置到第8汉字位置反白

 Set_White(4,4,5,0);   //第4行,第4个汉字位置到第5汉字位置反白

 Delay(2000);

 Delay(2000);

 Set_White(4,1,4,1);   //第1行,第4个汉字位置等取消反白

 Set_White(5,2,5,1);   //第2行,第5个汉字位置等取消反白

 Set_White(6,3,6,1);   //第3行,第6个汉字位置等取消反白

 Set_White(4,4,4,1);   //第4行,第4个汉字位置等取消反白

 Delay(2000);

 Delay(2000);

 Set_White(1,1,1,1);   //

 Set_White(3,2,3,1);   //

 Set_White(2,3,2,1);   //

 Set_White(5,4,5,1);   //

 Delay(2000);

 Delay(2000);

 Set_White(1,1,8,1);   //第1行,第1个汉字位置到第8汉字位置取消反白

 Set_White(1,2,8,1);   //第2行,第1个汉字位置到第8汉字位置取消反白

 Set_White(1,3,8,1);   //第3行,第1个汉字位置到第8汉字位置取消反白

 Set_White(1,4,8,1);   //第4行,第1个汉字位置到第8汉字位置取消反白

 Delay(2000);

 Delay(2000);

}

}

/******************************************************************/

void LCD_Init(void)

{

 uchar cmd;

 cmd=0x30;   //功能设置 8位数据,基本指令

W_1byte(0,0,cmd);

Delay(2);

cmd=0x0C;   //显示状态 ON,游标OFF,反白OFF

W_1byte(0,0,cmd); //写指令

Delay(2);

cmd=0x01;   //清除显示

W_1byte(0,0,cmd); //写指令

Delay(2);

cmd=0x02;   //地址归位

W_1byte(0,0,cmd); //写指令

Delay(2);

cmd=0x80;   //设置DDRAM地址

W_1byte(0,0,cmd); //写指令

Delay(2);   //延时

}

/*******************************************************************

函 数 名:W_1byte

入口参数:RW、RS、W_data

出口参数:无

建立日期:2007年3月3日

修改日期:

函数作用:写一个字节的数据到12864液晶,包括指令和数据

说    明:RW=1,从液晶读数据到MCU;RW=0,写一个数据到液晶;

  (一般RW都设为0,即只向液晶写数据,不读数据)

         RS=1,写入的是数据;RS=0,写入的是指令;

   一般模式:RW=0,RS=1;写数据

      RW=0,RS=0;写指令

********************************************************************/

void W_1byte(uchar RW, uchar RS, uchar W_data)

{

uint H_data,L_data,S_ID = 0xf8;  //11111RWRS0

if(RW == 0)

{

  S_ID &=~ 0x04;

}

else     //if(RW==1)

{

  S_ID |= 0X04;

}

if(RS == 0)

{

  S_ID &=~ 0x02;

}

else     //if(RS==1)

{

  S_ID |= 0X02;

}

H_data = W_data;

H_data &= 0xf0;   //屏蔽低4位的数据

L_data = W_data;     //xxxx0000格式

L_data &= 0x0f;   //屏蔽高4位的数据

L_data <<= 4;   //xxxx0000格式

Set_CS();

Write_8bits(S_ID);   //发送S_ID

Write_8bits(H_data); //发送H_data

Write_8bits(L_data); //发送L_data

Clr_CS();

}

/********************************************************************

函 数 名:Write_8bits

入口参数:W_bits

出口参数:无

建立日期:2007年3月3日

修改日期:

函数作用:负责串行输出8个bit位

说    明:

********************************************************************/

void Write_8bits(uint W_bits)

{

uint i,Temp_data;

for(i=0; i<8; i++)

{

 Temp_data = W_bits;

 Temp_data <<= i;

 if((Temp_data&0x80)==0)

 {

   Clr_SID();

 }

 else

 {

   Set_SID();

 }

 nop();

 Set_SCLK();

 nop();

 nop();

 Clr_SCLK();

 nop();

 Clr_SID();

}

}

/********************************************************************

函 数 名:Delay

入口参数:ms

出口参数:无

建立日期:2007年3月3日

修改日期:

函数作用:毫秒级的延时程序,当晶振为12Mhz时,xtal=12;

说    明:

********************************************************************/

void Delay(uint ms)

{

   uint i;

   while(ms--)    

  {

    for(i=1;i<(uint)(xtal*143-2);i++)

        ;

  }  

}

//===================================================================*/

/********************************************************************

函 数 名:Char_Set_XY

入口参数:x,y,*p

出口参数:无

建立日期:2007年8月26日

修改日期:

函数作用:

说    明:

********************************************************************/

void Char_Set_XY(uchar x, uchar y, uchar *p)

{

    if(y == 0)

{

  W_1byte(0,0,(0x80+x));

}

if(y == 1)

{

 W_1byte(0,0,(0x90+x));

}

if(y == 2)

{

 W_1byte(0,0,(0x88+x));

}

if(y == 3)

{

 W_1byte(0,0,(0x98+x));

}

while(*p != 0)

{

 W_1byte(0,1,*p++);

}

}

//===================================================================*/

/********************************************************************

函 数 名:Set_Draw(

入口参数:无

出口参数:无

建立日期:2007年8月26日

修改日期:

函数作用:

说    明:

********************************************************************/

void Set_Draw(void)

{

//W_1byte(0,0,0x01);   //清屏

Delay(20);     //延时

//W_1byte(0,0,0x34);   //8BIT控制界面,扩充指令集,,绘图显示OFF

W_1byte(0,0,0x36);

Delay(20);     //延时

}

//===================================================================*/

/********************************************************************

函 数 名:Draw_Pic  128*64

入口参数:x,y,*Draw

出口参数:无

建立日期:2007年8月26日

修改日期:

函数作用:

说    明:

********************************************************************/

/*************************************************/

void Draw_Pic(uchar x, uchar y, const uchar *Draw)

{

uchar i, j, temp_x, temp_y;  //

temp_x = x;      //

temp_y = y;      //

temp_x |= 0x80;     //

temp_y |= 0x80;     //

for(i=0;i<32;i++ )    //上半屏32行

{

 W_1byte(0,0,temp_y++);  //设置绘图区的Y地址坐标0

 W_1byte(0,0,temp_x);  //设置绘图区的X地址坐标0

 for(j=0;j<16;j++)   //

 {

   W_1byte(0,1,*Draw++); //

 }

}

temp_x = 0x88;     //

temp_y = 0x80;     //

j = 0;         //

for(;i<64;i++ )

{

 W_1byte(0,0,temp_y++);  //设置绘图区的Y地址坐标

 W_1byte(0,0,temp_x);   //设置绘图区的X地址坐标

 for(j=0;j<16;j++)

 {

   W_1byte(0,1,*Draw++); //

 }

}

}

/**************************************************/

/**************************************************/

void Set_White(uchar x,uchar y,uchar end_x,uchar clear)

{

 uchar i, j, white_x, white_y,white_end_x,clr_x,clr_y;  //

white_end_x = (end_x-x+1);

white_end_x <<= 1;

if(y==1)

{

  white_x = (0x80+x-1);

 white_y = 0x80;

 clr_x = 0x80;

 clr_y = 0x80;

}

else if(y==2)

{

  white_x = (0x80+x-1);

 white_y = 0x90;

 clr_x = 0x80;

 clr_y = 0x90;

}

else if(y==3)

{

  white_x = (0x88+x-1);

 white_y = 0x80;

 clr_x = 0x88;

 clr_y = 0x80;

}

else if(y==4)

{

  white_x = (0x88+x-1);

 white_y = 0x90;

 clr_x = 0x88;

 clr_y = 0x90;

}

if(clear==0)//要反白时,先将整行的液晶全部清成不反白(此处行指y)

{

  for(i=0;i<16;i++ )   //16行

 {

   W_1byte(0,0,clr_y++); //设置绘图区的Y地址坐标0

  W_1byte(0,0,clr_x);  //设置绘图区的X地址坐标0

  for(j=0;j<16;j++)  //

  {

    W_1byte(0,1,0x00); //清成不反白

    nop();

  }

 }

}

nop();

for(i=0;i<16;i++ )    //16行,因为是16*16汉字

{

 W_1byte(0,0,white_y++);  //设置绘图区的Y地址坐标0

 W_1byte(0,0,white_x);  //设置绘图区的X地址坐标0

 for(j=0;j<white_end_x;j++) //

 {

   if(clear==1)

   {

     W_1byte(0,1,0x00); //取消这一行的8个点的反白,液晶地址自动加1

          //(此处行指一个一个液晶点所组成的行)

   }

   else

   {

   W_1byte(0,1,0xff); //反白这一行的8个点,液晶地址自动加1

          //(此处行指一个一个液晶点所组成的行)

   }

   nop();

 }

}

}

/*************************************************/

上一篇:HGSC256643OLED显示屏SPI接口测试程序
下一篇:1U机箱OLED显示屏测试程序