zhaolujia 发表于 2011-12-19 16:17:08

AVR的12864程序 画任意图像和线段 显示字符和汉字 还有uint_8

/************************************************************************
************************************************************************/
//12864液晶一定要注意是工作在什么指令集模式还有AC工作在什么模式


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

#ifndef _lcd12864_test_h
#define _lcd12864_test_h

#define LOW      0
#define HIGH1
#define FIRST_ADDR0       //定义字符/汉字显示起始位置

//12864相关初始化指令
#define CLEAR_SCREEN   0x01//清屏指令:清屏且AC值为00H
#define AC_INIT      0x02//将AC设置为00H。且游标移到原点位置

#define CURSE_ADD   0x06//设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)

#define FUN_MODE   0x30//工作模式:8位基本指令集

#define DISPLAY_ON   0x0c//显示开,显示游标,且游标位置反白

#define DISPLAY_OFF   0x08//显示关

#define CURSE_DIR       0x14//游标向右移动:AC=AC+1

#define SET_CG_AC   0x40//设置AC,范围为:00H~3FH

#define SET_DD_AC   0x80

#define FUN_MODEK   0x36//工作模式:8位扩展指令集

#define X1address       0x80      //12864上半屏X轴起始地址

#define X2address       0x88      //12864下半屏X轴起始地址

#define Yaddress      0x80      //Y轴起始地址

//***********************************************************************
// 端口定义
//***********************************************************************
#define RS_PORT_DDRDDRA
#define RS_PORT_PORT   PORTA
#define RS_PORT    4

#define RW_PORT_DDR   DDRA
#define RW_PORT_PORTPORTA
#define RW_PORT    5

#define EN_PORT_DDR   DDRA
#define EN_PORT_PORT   PORTA
#define EN_PORT    6


#define PSB_PORT_DDR   DDRA
#define PSB_PORT_PORT   PORTA
#define PSB_PORT    0

#define RET_PORT_DDR   DDRA
#define RET_PORT_PORT   PORTA
#define RET_PORT    1

#define DATA_PORT_DDR    DDRB
#define DATA_PORT_PIN    PINB
#define DATA_PORT      PORTB

/*******************************************************************************/
#define RS_CLR   RS_PORT_PORT &= ~(1 << RS_PORT)               //RS置低
#define RS_SET   RS_PORT_PORT |= (1 << RS_PORT)                  //RS置高

#define RW_CLR   RW_PORT_PORT &= ~(1 << RW_PORT)               //RW置低
#define RW_SET   RW_PORT_PORT |= (1 << RW_PORT)                  //RW置高

#define EN_CLR   EN_PORT_PORT &= ~(1 << EN_PORT)               //E置低
#define EN_SET   EN_PORT_PORT |= (1 << EN_PORT)                  //E置高


//***********************************************************************
// 函数声明
//***********************************************************************
void LCD_init(void);//液晶初始化
void wait_BF(void);   //等待忙信号
void LCD_write_com(unsigned char com);      //写命令
void LCD_write_data(unsigned char data);//写数据
void LCD_clear(void);//清屏基本指令集

void SetPos(unsigned char x, unsigned chary);

void DisplayListChar( unsigned char x, unsigned char y ,unsigned char *hz);//显示字库中的字符
void DisplayOneChar(unsigned char x, unsigned char y, unsigned char data );
void Display_8int(unsigned char x, unsigned char y, unsigned char data );


void Display_photo1(unsigned char *img1) ;//写上半屏的数据
void Display_photo2(unsigned char *img2);//写下半屏的数据
unsigned charLCD_read_char(void );//在写数据时先将CGRAM中的数据读出来
void Clear_CGRAM(void );//清空CGRAM
void Draw_point(unsigned char x, unsigned char y);//画点
void Draw_Horizontal_line(unsigned char X0, unsigned char X1, unsigned char Y);//画横线
void Draw_Vertical_line(unsigned char X, unsigned char Y0, unsigned char Y1);//画竖线
void Draw_line( unsigned char StartX, unsigned char StartY, unsigned char EndX, unsigned char EndY );//画任意线


#endif






/************************************************************************
************************************************************************/
//12864液晶一定要注意是工作在什么指令集模式还有AC工作在什么模式


//***********************************************************************
//   包含文件
//***********************************************************************
#include "lcd12864_test.h"
#include"config.h"
//***********************************************************************
//函数名称:等待忙信号
//入口参数:无
//返回参数:无
//***********************************************************************
void wait_BF(void)
{
        DATA_PORT = 0Xff;
        DATA_PORT_DDR = 0X00;
       
        RS_CLR;
        RW_SET;
        while(1)
        {
                EN_SET;
                _delay_us(20);
                if((DATA_PORT_PIN&(1<<7)) == 0)
                        break;
                EN_CLR;
        }
        DATA_PORT = 0X00;
        DATA_PORT_DDR = 0Xff;

        return ;

}


//***********************************************************************
// 显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com)
{
        wait_BF();
        RS_CLR;
        RW_CLR;
        EN_SET;
        DATA_PORT = com;
        _delay_us(20);
        EN_CLR;
}



//***********************************************************************
// 显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char data)
{
        wait_BF();
        RS_SET;
        RW_CLR;
        EN_SET;
        DATA_PORT = data;
        _delay_us(20);
        EN_CLR;
}
//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD_clear(void)
{
        wait_BF();
        LCD_write_com(0x01);
}


void SetPos(unsigned char x, unsigned chary)
{
       
        LCD_write_com(0x34);//绘图关闭
        LCD_write_com(0X30);//回到基本指令集 并且关闭绘图显示
       
        switch( y )
        {
                case 0: LCD_write_com(0x80 + x);break;
                case 1: LCD_write_com(0x90 + x);break;
                case 2: LCD_write_com(0x88 + x);break;
                case 3: LCD_write_com(0x98 + x);break;


        }
}
//***********************************************************************
//函数名称:显示单个ASCII字符
//入口参数:无
//返回参数:无
//***********************************************************************
void DisplayOneChar( unsigned char x, unsigned char y ,unsigned char data)//显示字库中的字符
{
       
        SetPos(x , y);
        LCD_write_data(data);
       
}
//***********************************************************************
//函数名称:显示8位整型数值
//入口参数:无
//返回参数:无
//***********************************************************************
void Display_8int( unsigned char x, unsigned char y ,unsigned char data)//显示字库中的字符
{
        unsigned chara, b, c ;
        a = data/100;
        b = data%100/10;
        c = data%10;

        SetPos(x , y);
        LCD_write_data(a +48);
        LCD_write_data(b +48);
        SetPos(x+ 1 , y);
        LCD_write_data(c +48);
       
}
//***********************************************************************
//函数名称:Display显示CGROM里的汉字
//入口参数:无
//返回参数:无
//***********************************************************************
void DisplayListChar( unsigned char x, unsigned char y ,unsigned char *hz)//显示字库中的字符
{
        SetPos(x , y);
        while(*hz != '\0')
        {
                LCD_write_data(*hz);
                hz++;
        }
}

//***********************************************************************
// 显示屏初始化函数

//***********************************************************************
void LCD_init(void)
{
        RS_PORT_DDR |= (1<<RS_PORT);
        RW_PORT_DDR |= (1<<RW_PORT);
        EN_PORT_DDR |= (1<<EN_PORT);
        PSB_PORT_DDR |= (1<<PSB_PORT);
        RET_PORT_DDR |= (1<<RET_PORT);
       
        PSB_PORT_PORT |= (1<<PSB_PORT);//置位后 并行输出
        RET_PORT_PORT |= (1<<RET_PORT);//低电平复位所以置高

        DATA_PORT_DDR = 0XFF;
        DATA_PORT = 0X00;

        LCD_write_com(FUN_MODE);   //显示模式设置
       
    LCD_write_com(DISPLAY_ON);   //显示开
       
    LCD_write_com(CLEAR_SCREEN);      //清屏
       
}
//****************************************************************
//函数名称:Display_photo(uchar *hz)显示自定义图形,分上下半屏来写
//上屏
//****************************************************************
void Display_photo1(uchar *img1)                      //写上半屏图形数据函数
{
           int i,j;   
        LCD_write_com(FUN_MODEK);                     //扩展指令,开绘图显示
          
        for(i=0;i<32;i++)                                 //上半屏32行
    {
                LCD_write_com(Yaddress+i);                   //先写垂直地址,即Y地址,不能自动加一
      LCD_write_com(X1address);                  //再写水平地址,即X地址
      
              for(j=0;j<8;j++)                     //连续写入2个字节的数据,一共8次,为一行,即16*8位数据
            {                                          
                        LCD_write_data(img1);
                                            //这个延时是必须的,因为没有对液晶进行判忙操作,所以进行延时
                        LCD_write_data(img1);
                                
      }
    }
}
//****************************************************************
//函数名称:Display_photo(uchar *hz)显示自定义图形,分上下半屏来写
//下屏
//****************************************************************
void Display_photo2(uchar *img2)                   //写下半屏图形数据
{
        int i,j;
        LCD_write_com(FUN_MODEK);                     //扩展指令,开绘图显示
        for(i=0;i<32;i++)                         //下半屏32行
        {
                   LCD_write_com(Yaddress+i);                //先写垂直地址,即Y地址,不能自动加一
           LCD_write_com(X2address);               //再写水平地址,即X地址
            for(j=0;j<8;j++)                        //连续写入2个字节的数据,一共8次,为一行,即16*8位数据
           {
   
                           LCD_write_data(img2);
                           LCD_write_data(img2);
                             
      
                }
        }
}
//****************************************************************
//从CGRAM中读取该字节的数据
//wr_com设定地址设定到哪里时就显示哪里的数据
//读取RAM中值的时候不属于基本指令集和扩展指令集中
//****************************************************************
unsigned charLCD_read_char()
{
        unsigned char temp;
        DATA_PORT = 0Xff;
        DATA_PORT_DDR = 0X00;

        RS_SET;
        RW_SET;
        EN_CLR;
        _delay_us(20);
        EN_SET;
        _delay_us(20);
        temp = DATA_PORT_PIN ;
        EN_CLR;
        DATA_PORT = 0X00;
        DATA_PORT_DDR = 0Xff;

        return temp;

}


void Clear_CGRAM()
{
        //将CGRAM中清零
        int m;
        unsigned char RamVar_1;
        for(m=0;m<512;m++)                //从flash中读取上半屏数据
    {
                RamVar_1 = 0;
    }

    Display_photo1(RamVar_1);   //显示上半屏数据
   
        for(m=0;m<512;m++)                //从flash中读取下半屏数据
    {
                RamVar_1 = 0;   
           }
        Display_photo2(RamVar_1);   //显示下半屏数据
}
//****************************************************************
//函数名称:画点函数 在指定的位置画一个像素点
//下屏
//****************************************************************
void Draw_point(unsigned char x, unsigned char y)
{
        uchar x_byte,x_bit;
        uchar y_byte,y_bit;
        uchar tmph,tmpl;
       
        x &= 0x7f;
        y &= 0x3f;

        x_byte = x/16;
        //x_bit =x & 0x0f;
        x_bit =x%16;

        y_byte = y/32;
        y_bit = y%32;
       
        //LCD_write_com(0x34);//扩展指令集
        //LCD_write_com(0x34);//绘图关闭
       
        //LCD_write_com(0x34);//如果老关显示时屏幕会颤动
        //LCD_write_com(0x36);//干脆就开着显示

        LCD_write_com( 0x80 +y_bit);

        LCD_write_com(0x80 +x_byte + 8*y_byte);
       
       
        LCD_read_char();
        tmph = LCD_read_char();
        tmpl = LCD_read_char();
       
        LCD_write_com( 0x80 +y_bit);
       //延时必须加上 否则报出错啊亲
        LCD_write_com(0x80 +x_byte + 8*y_byte);
       
       
        if(x_bit<8)
        {
               
                LCD_write_data( tmph|(0x01<<(7 - x_bit)));
               
                LCD_write_data(tmpl);
               

        }
        else
        {
                LCD_write_data(tmph);
               
                LCD_write_data(tmpl | (0x01<<(15 - x_bit)));
               
        }
       
        //LCD_write_com(0X36);//开绘图显示
       
        //LCD_write_com(0X30);//回到基本指令集
       
        return;
}
//****************************************************************
//函数名称:画水平线函数
//下屏
//****************************************************************
void Draw_Horizontal_line(unsigned char X0, unsigned char X1, unsigned char Y)//画横线
{
        LCD_write_com(0x36);//干脆就开着显示
        unsigned char Temp ;
    if( X0 > X1 )
    {
      Temp = X1 ;
      X1= X0 ;
      X0= Temp ;
    }
    for( ; X0 <= X1 ; X0++ )
            Draw_point( X0, Y ) ;   

}
//****************************************************************
//函数名称:画竖直线函数 用于垂线画
//下屏
//****************************************************************
void Draw_Vertical_line(unsigned char X, unsigned char Y0, unsigned char Y1)//画竖线
{
        LCD_write_com(0x36);//干脆就开着显示
        unsigned char Temp ;
    if( Y0 > Y1 )
    {
      Temp = Y1 ;
      Y1= Y0 ;
      Y0= Temp ;
    }
    for(; Y0 <= Y1 ; Y0++)
            Draw_point( X, Y0 ) ;

}
//****************************************************************
//函数名称:画任意线函数输入线段的起始位置和终止位置即可。。
//下屏
//****************************************************************
void Draw_line( unsigned char StartX, unsigned char StartY, unsigned char EndX, unsigned char EndY )
{
    LCD_write_com(0x36);//干脆就开着显示

        int t, distance;      /*根据屏幕大小改变变量类型(如改为int型)*/
    int x = 0 , y = 0 , delta_x, delta_y ;
    char incx, incy ;

    delta_x = EndX - StartX ;
    delta_y = EndY - StartY ;

    if( delta_x > 0 )
    {
      incx = 1;
    }
    else if( delta_x == 0 )
    {
      Draw_Vertical_line( StartX, StartY, EndY ) ;
      return ;
    }
    else
    {
      incx = -1 ;
    }
    if( delta_y > 0 )
    {
      incy = 1 ;
    }
    else if(delta_y == 0 )
    {
      Draw_Horizontal_line( StartX, EndX, StartY ) ;   
      return ;
    }
    else
    {
      incy = -1 ;
    }

    if(delta_x < 0)   //delta_x = ABS( delta_x );
                delta_x = -delta_x;
        if(delta_y < 0)    //delta_y = ABS( delta_y );
                delta_y = -delta_x;

        if( delta_x > delta_y )
    {
      distance = delta_x ;
    }
    else
    {
      distance = delta_y ;
    }
    Draw_point( StartX, StartY ) ;   
    /* Draw Line*/
    for( t = 0 ; t <= distance+1; t++ )
    {
      Draw_point( StartX, StartY ) ;
      x += delta_x ;
      y += delta_y ;
      if( x > distance )
      {
            x -= distance ;
            StartX += incx ;
      }
      if( y > distance )
      {
            y -= distance ;
            StartY += incy ;
      }
    }
}

xiazhijpeng 发表于 2012-2-11 10:16:00

这么多啊,头大。

bsyg2323 发表于 2012-6-10 10:02:09

{:lol:}谢谢。。。。mark

cos 发表于 2012-6-11 11:43:33

馬克帕克

_HOLDON 发表于 2012-10-11 15:00:17

学习了,{:smile:}

hzxin 发表于 2012-10-11 15:36:35

谢谢!学习了。{:smile:}

leida_3669 发表于 2013-4-3 16:49:38

{:lol:}很好用啊,谢谢楼主!!~

donny_y 发表于 2013-4-7 13:03:49

mark 下{:biggrin:}

zya311 发表于 2014-5-15 21:43:13

学习了!亲测可用!

光蛋骑士 发表于 2014-5-29 09:37:37

收了收了,谢谢楼主!
页: [1]
查看完整版本: AVR的12864程序 画任意图像和线段 显示字符和汉字 还有uint_8