打印
[应用相关]

隆重推出STM32F的LCD320*240驱动程序

[复制链接]
6413|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sunke9|  楼主 | 2008-7-17 21:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本驱动程序针对与SED1335兼容控制芯片的LCD320240液晶显示模块,实现了输出8*16、16*24、16*32三种字号的数字及英文符号,输出16*16、24*24、32*32三种字号的汉字,还能按照起点终点坐标画直线和斜线。

#include "lcd.h" 
#include "ZK.h"
//============================ 1335 常用指令列表 =============================== 
//初始化设置。A0=1..写指令/0...读写参数。后续8字节参数串ParaSysTable8[] 

const unsigned char ParaSysTable8[]= {0x30,0x87,0x07,0x27,0x42,0xf0,0x28,0x00 };// P1-P8参数 
#define BasePart1 0x00 
#define BasePart2 0x40 
#define BasePart3 0x00 
#define BasePart4 0x00 
const unsigned char ParaScrTableA[]= {0x00,BasePart1,0xF0,0x00,BasePart2,0xF0,0x00,BasePart3,0x00,BasePart4 }; 
#define Scroll 0x44 // 时序要求:/WR=0;/RD=1 
#define SystemSet 0x40 // 时序要求:/WR=0;/RD=1 
#define SleepIn 0x53 
//显示状态设置。A0=1..ON/0..OFF;/WR=0;/RD=1. 
#define DispOn 0x59 
#define DispOff 0x58 
#define Ovlay 0x5b 
#define HdotScr 0x5a 
#define CsrW 0x46 
//读取光标指针。A0=1..写指令/0...读写参数;/WR=0;/RD=1. 
#define CsrR 0x47
//光标移动方向设置。A0=1;/WR=0;/RD=1. 
/* 该指令代码写入后,计算机将从SED1335等数据通道读出当前的光标指针值。光标指针读 
出的顺序是先CSRL再CSRH. 
*/ 

//数据写入设置。A0=1..写指令/0...读写参数;/WR=0;/RD=1. 
#define mWrite 0x42 

//数据读取设置。A0=1..写指令/0...读写参数;/WR=0;/RD=1. 
#define mRead 0x43 

// 程序参数定义,根据用户选择的LCM型号修改 
#define Busy 0x40 
#define paraP9 0x28 

#define CsrDirR 0x4c 
#define CsrDirL 0x4d 
#define CsrDirU 0x4e 
#define CsrDirD 0x4f 

extern void delay(void); 
void delay_1ms(void);
void _delay_ms(u32 j);
void sed1335_write_command(unsigned char chCMD);
void sed1335_write_data(unsigned char chData);
void LcmInition(void);
void LcmClear(void); 
void Locatexy(unsigned char x,unsigned char y, unsigned char attribs);
void Putstr(unsigned char x,unsigned char y,unsigned char *pstr,unsigned char flag,unsigned char dotwidth);
void Point(unsigned int Px, unsigned char Py, unsigned char attr );
void Linexy(unsigned int x0,unsigned char y0,unsigned int xt,unsigned char yt,unsigned char att);

/*********************************************************** 
*   函数说明:向LCD发送指令函数                            * 
*   输入:    要发送的指令                                 * 
*   输出:    无                                           * 
*   调用函数:无                                           * 
***********************************************************/ 
void sed1335_write_command(unsigned char chCMD) 
{
    u16 LCD_DATA_OUT ;    
    LCD_DATA_OUT = (GPIO_ReadOutputData(GPIOE)&0xff00)|chCMD; 
    GPIO_Write(GPIOE, LCD_DATA_OUT);        
    AO_H;
    RD_H;         
    WR_L;         
    WR_H;   


/*********************************************************** 
*   函数说明:向LCD发送数据函数                            * 
*   输入:    要发送的数据                                 * 
*   输出:    无                                           * 
*   调用函数:无                                           * 
***********************************************************/ 
void sed1335_write_data(unsigned char chData) 

    u16 LCD_DATA_OUT ;    
    LCD_DATA_OUT = (GPIO_ReadOutputData(GPIOE)&0xff00)|chData; 
    GPIO_Write(GPIOE, LCD_DATA_OUT);          
    AO_L;
    RD_H;           
    WR_L;           
    WR_H;          

/*********************************************************** 
*   函数说明:从LCD读取数据函数                            * 
*   输入:    无                                           * 
*   输出:   cbuf                                          * 
*   调用函数:无                                           * 
***********************************************************/ 
Uchar ReadDataLcm( void ) 

        unsigned char cbuf;
        unsigned int temp; 
          GPIO_InitTypeDef GPIO_InitStructure;
        /* Configure PE.00~ PE.07 as output push-pull[把PE0-PE7配置成输出模式] */
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO最高速度50MHz
        GPIO_Init(GPIOE, &GPIO_InitStructure);
        AO_H;
        RD_L;       
        WR_H;
        temp = GPIO_ReadInputData(GPIOE);
        cbuf = temp & 0x00ff;        
        RD_H; 
        /* Configure PE.00~ PE.07 as output push-pull[把PE0-PE7配置成输出模式] */
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO最高速度50MHz
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        return (unsigned char)cbuf; 

/*********************************************************** 
*   函数说明:LCD320240初始化函数                          * 
*   输入:    无                                           * 
*   输出:    无                                           * 
*   调用函数:无                                           * 
***********************************************************/ 
void LcmInition(void) 

    unsigned char i;
    CS_L;
    RST_L;            
    delay();            
    RST_H;        
    delay();           
    sed1335_write_command(0x40); /* ---------LCD SYSTEM SET系统设置令,8个参数-------- */
    for (i=0;i<8;i++) 
    { 
            sed1335_write_data( ParaSysTable8 ); // 
    }           
    sed1335_write_command(0x44);/* ---------LCD SCROLL显示区设置命令,最多10个参数--------- */           
    for (i=0;i<10;i++) 
    { 
            sed1335_write_data( ParaScrTableA );
    }            
    sed1335_write_command(HdotScr);//显示画面水平移动量:00--07 点            
    sed1335_write_data(0x00);// 写入P1参数
    sed1335_write_command(Ovlay);//显示属性:DM1(DM2)=0,文本方式;DM1(DM2)=1,图形方式;OV=1,三重合成;OV=0,两重合成    
    sed1335_write_data(0x0d);    
    delay();     
    sed1335_write_command(DispOn);    
    sed1335_write_data(0x15);    
}    
/*********************************************************** 
*   函数说明:LCD320240清屏函数                            * 
*   输入:    无                                           * 
*   输出:    无                                           * 
*   调用函数:无                                           * 
***********************************************************/ 
void LcmClear(void) 

    u16 j="32768";    
    sed1335_write_command(CsrDirR);
    sed1335_write_command(CsrW);
    sed1335_write_data(0x00);    
    sed1335_write_data(0x00);
    sed1335_write_command(mWrite);   
    while(j--)
    {
      sed1335_write_data(0x00);    
    }
    
}

/********************************************/ 
/*画线。任意方向的斜线,直线数学方程 aX+bY=1 */ 
/********************************************/ 
// 参数类型有待修改 
void Linexy(unsigned int x0,unsigned char y0,unsigned int xt,unsigned char yt,unsigned char att) 

        register unsigned int t; 
        int xerr="0",yerr=0,delta_x,delta_y,distance; 
        int incx,incy; 
        unsigned int row,col; 
        delta_x = xt-x0; //计算坐标增量 
        delta_y = yt-y0; 
        col = x0; 
        row = y0; 
        if(delta_x>0) 
        {
                incx="1"; //设置单步方向 
        }
        else 
        { 
                if( delta_x==0 ) 
                {        
                        incx="0"; //垂直线 
                }
                else 
                {
                        incx="-1";
                        delta_x=-delta_x;
                } 
        } 
        if(delta_y>0) 
        {
                incy="1";
        }
        else 
        { 
                if( delta_y==0 ) 
                {
                        incy="0";
                } //水平线 
                else 
                {
                        incy="-1";
                        delta_y=-delta_y;
                } 
        } 
        if( delta_x > delta_y ) 
        {
                distance="delta"_x;
        } //选取基本增量坐标轴 
        else 
        {
                distance="delta"_y;
        } 
        for( t="0";t <= distance+1; t++ ) 
        { //画线输出 
                Point((unsigned int)col,row,att); //画点 
                xerr += delta_x ; 
                yerr += delta_y ; 
                if( xerr > distance ) 
                { 
                        xerr-=distance; 
                        col+=incx; 
                } 
                if( yerr > distance ) 
                { 
                        yerr-=distance; 
                        row+=incy; 
                } 
        } 


/*==================================================== 
; 绘点子程序,携入参数X坐标的最高位决定写或擦点 
====================================================*/ 
void Point(unsigned int Px, unsigned char Py, unsigned char attr ) 

        unsigned int tempPtr; 
        unsigned char tempD,tempP; 
        tempPtr = (unsigned int)Py * paraP9 + (Px & 0x7fff)/8; // 去除最高位(显示属性) 
        sed1335_write_command( CsrDirD ); // CSRDIR 代码(光标自动下移) 
        sed1335_write_command( CsrW ); // 设置光标地址 
        sed1335_write_data( (unsigned char)(tempPtr & 0xff) ); 
        sed1335_write_data( (unsigned char)(tempPtr /256) ); 
        sed1335_write_command( mRead ); // 读显示ram指令 
        tempD = ReadDataLcm(); // 读取当前显示数据 
       tempP = 1<<(unsigned char)(7-Px & 0x0007); 
        // 根据预定属性决定写点或擦除 
        if( attr )
        {
                tempD |= tempP;
        } // 画点 
        else 
        {
                tempD &= ~tempP;
        } // 消点 
        sed1335_write_command( CsrW ); // 重新设置光标地址 
        sed1335_write_data( (unsigned char)(tempPtr & 0xff) ); 
        sed1335_write_data( (unsigned char)(tempPtr /256) ); 
        sed1335_write_command( mWrite ); // 代码0x42,数据写入指令 
        sed1335_write_data( tempD ); // 写入合成数据 


/********************************************** 
ASCII(8*16) 及 汉字(16*16) 混合字符串显示函数
x,y显示字符串的左上角xy坐标.x..8点一字节位置; y..一条扫描线定位
*ptr...字符串指针,本函数所指的是flash字串 
att....显示区标志,0...第一区;1...第二区 
返回参数:输出字串长度,留意汉字一个算两个 
其它假定:调用时汉字必须在字库数组中已经存在,否则将输出不正确的结果 
***********************************************/ 
void Putstr(unsigned char x,unsigned char y,unsigned char *pstr,unsigned char flag,unsigned char dotwidth) 

        unsigned char j,m,temp; 
        unsigned char uRow,uCol; 
        unsigned int count; 
        uRow="x"; 
        uCol="y"; 
        sed1335_write_command( CsrDirD ); 
        Locatexy(uRow,uCol,flag); 
        while(*pstr)
        {
                if(*pstr>0xa0)
                {
                        switch(dotwidth)
                        {
                                case 16://写16*16的汉字
                                {
                                    count="0";
                                    while((HZ16_16[count]!=*pstr)||(HZ16_16[count+1]!=*(pstr+1))) 
                                    { 
                                          count="count"+0x22;
                                          if(HZ16_16[count]==0)
                                          {
                                                count="0xffff";
                                                break;
                                          }
                                    }
                                    pstr+=2;
                                    count+=2;
                                    for(m=0;m<2;m++)
                                    { 
                                        Locatexy(uRow+m,uCol,flag);
                                        sed1335_write_command( mWrite ); // 写数据(命令)
                                        for(temp=0;temp<16;temp++)
                                        {sed1335_write_data(HZ16_16[2*temp+count+m]);} 
                                    }
                                    uRow+=2;
                                }break;
                                case 24://写24*24的汉字
                                {
                                    count="0";
                                    while((HZ24_24[count]!=*pstr)||(HZ24_24[count+1]!=*(pstr+1))) 
                                    { 
                                          count="count"+0x4A;
                                          if(HZ24_24[count]==0)
                                          {
                                                count="0xffff";
                                                break;
                                          }
                                    }
                                    pstr+=2;
                                    count+=2;
                                    for(m=0;m<3;m++)
                                    { 
                                        Locatexy(uRow+m,uCol,flag );
                                        sed1335_write_command( mWrite ); // 写数据(命令)
                                        for(temp=0;temp<24;temp++)
                                        {sed1335_write_data(HZ24_24[3*temp+count+m]);} 
                                    }
                                    uRow+=3;
                                }break;
                                case 32://写32*32的汉字
                                {
                                    count="0";
                                    while((HZ32_32[count]!=*pstr)||(HZ32_32[count+1]!=*(pstr+1))) 
                                    { 
                                          count="count"+0x82;
                                          if(HZ32_32[count]==0)
                                          {
                                                count="0xffff";
                                                break;
                                          }
                                    }
                                    pstr+=2;
                                    count+=2;
                                    for(m=0;m<4;m++)
                                    { 
                                        Locatexy(uRow+m,uCol,flag);
                                        sed1335_write_command( mWrite ); // 写数据(命令)
                                        for(temp=0;temp<32;temp++)
                                        {sed1335_write_data(HZ32_32[4*temp+count+m]);} 
                                    }
                                    uRow+=4;
                                } break;
                        }
                                
                }//if
                else
                { 
                        switch(dotwidth)
                        {
                                case 16://写16*16的数字
                                {
                                      Locatexy(uRow,uCol,flag);
                                      sed1335_write_command( mWrite ); // 写数据(命令)
                                      for(j=0;j<16;j++)
                                      {sed1335_write_data(ASC_MSK[(*pstr-0x20)*16 +j ]);}
                                      pstr++; 
                                      uRow++;
                                } break;
                                case 24://写24*24的数字
                                {
                                    count="0";
                                    while(ASC_MSK24[count]!=*pstr) 
                                    { 
                                          count="count"+0x31;
                                          if(ASC_MSK24[count]==0)
                                          {
                                                count="0xffff";
                                                break;
                                          }
                                    }
                                    pstr+=1;
                                    count+=1;
                                    for(m=0;m<2;m++)
                                    { 
                                        Locatexy(uRow+m,uCol,flag);
                                        sed1335_write_command( mWrite ); // 写数据(命令)
                                        for(temp=0;temp<24;temp++)
                                        {sed1335_write_data(ASC_MSK24[2*temp+count+m]);} 
                                    }
                                    uRow+=2;
                                }break;
                                case 32://写32*32的数字
                                {
                                    count="0";
                                    while(ASC_MSK32[count]!=*pstr) 
                                    { 
                                          count="count"+0x41;
                                          if(ASC_MSK32[count]==0)
                                          {
                                                count="0xffff";
                                                break;
                                          }
                                    }
                                    pstr+=1;
                                    count+=1;
                                    for(m=0;m<2;m++)
                                    { 
                                        Locatexy(uRow+m,uCol,flag);
                                        sed1335_write_command( mWrite ); // 写数据(命令)
                                        for(temp=0;temp<32;temp++)
                                        {sed1335_write_data(ASC_MSK32[temp+count+m*32]);} 
                                    }
                                    uRow+=2;
                                }break;                                
                                
                        }
                }
                if(uRow >= 40) // 光标后移 
                {
                        switch(dotwidth)
                        {
                                case 16:
                                {
                                      uCol += 16; // Y坐标
                                }break; 
                                case 24:
                                {
                                      uCol += 24; // Y坐标
                                }break; 
         &n
相关链接:https://bbs.21ic.com/upfiles/img/20079/20079282825769.rar
沙发
grant_jx| | 2008-7-17 22:50 | 只看该作者

潜力帖,有穿裤子的机会

使用特权

评论回复
板凳
kfawj| | 2008-7-18 08:54 | 只看该作者

有格子不太好看哟!

正在调这部分程序。
可惜还没有成功,正好参考一下啦!

使用特权

评论回复
地板
sunke9|  楼主 | 2008-7-18 10:02 | 只看该作者

请大家注意一个地方!

我的电路后来为了能实现读lcd内的数据,把数据线驱动的244去掉了,直接接到cpu上了,运行常。

使用特权

评论回复
5
kfawj| | 2008-7-18 16:24 | 只看该作者

继续!晕……

所有操作,不正常……
pa8----------->db6
不知道为什么,这个i/o口一直为高!
请问楼主输出高电平是,是5V,还是3V呀?
我这为3.3V输出。
74ls244接法与楼主无太多的差异!

使用特权

评论回复
6
sunke9|  楼主 | 2008-7-19 13:28 | 只看该作者

楼上用的是我这个程序吗?

你改IO口了?如果改了,需要改程序的几个地方呢.

使用特权

评论回复
7
kfawj| | 2008-7-19 15:04 | 只看该作者

to:sunke9

谢谢楼主的关心!!!
知道!!!
我仔细看了我的程序与你的程序,并无太多的差异。
又看了一遍液晶的芯片,RA8835(通过看资料没有发现问题)、LY62256(可能就是它,它不支持3.3V工作电压,不过最低2V就是高电平啦)。

至现在更郁闷。有5V的PIC18F6622推,没有想到液晶上的一个器件突然发热(可能是对比度的负压升压部分)(彻底没有得调啦)

第一次遇到这么棘手的东东(快两周啦,与做一个小东东的周期差不多了)

5555555555555555555555555……

使用特权

评论回复
8
sunke9|  楼主 | 2008-7-19 18:29 | 只看该作者

调这个LCD,对比度很重要!

我刚开始的时候找了一份资料关于对比度调节电压部分写的不是很明确,我就给接了个+5V结果怎么也调不出来字,有的时候还能出竖条或横条,我就以为对比度调好了呢,一个劲的改程序也不见效后来找了一份别的产品的图纸才发现需要-24V电压.负压弄好了,调节电位器也有难度,调大了全蓝,调小了全白,只有很小的范围内能看到字.

使用特权

评论回复
9
again_gyf| | 2008-7-19 20:05 | 只看该作者

VO大概在-20V左右就可以!

偶用的是44B0自带的控制器,点这个饼很容易!呵呵!

使用特权

评论回复
10
kl818bc| | 2008-7-19 21:31 | 只看该作者

STM3210xCDE 的FSMC好像有支持并口LCD

LCD parallel interface, 8080/6800 modes

使用特权

评论回复
11
香水城| | 2008-7-19 21:32 | 只看该作者

楼主做这个项目时,支持并口LCD的STM32还没有出来呢

使用特权

评论回复
12
gpfrank| | 2008-7-20 12:08 | 只看该作者

我的YM320240E-3 只显示1/6,而且坐标全乱套

我的YM320240E-3 只显示1/6,而且坐标全乱套

使用特权

评论回复
13
sunke9|  楼主 | 2008-7-21 08:08 | 只看该作者

楼上的初始化程序没弄好吧?

既然能显示1/6说明驱动没有问题,仔细看看初始化程序吧

使用特权

评论回复
14
billy_yin| | 2008-7-21 10:20 | 只看该作者

mark

使用特权

评论回复
15
kfawj| | 2008-7-23 08:35 | 只看该作者

谢谢楼主

一个偶然的机会,发现液晶的负压芯片发热。
唉!如果它再没有问题,我也该疯了。
程序没有问题。可以很好的执行。
只是液晶坏了。(又买了一块别的厂家的液晶,一切运行良好)

再次感谢大家的帮助!!

使用特权

评论回复
16
foxcome| | 2008-7-28 14:22 | 只看该作者

fsmc 最高频率

STM32 的FSMC总线最高能跑多高的频率呢?

使用特权

评论回复
17
lianshumou| | 2008-7-28 15:46 | 只看该作者

18M的读写速度

使用特权

评论回复
18
gpfrank| | 2008-7-30 13:07 | 只看该作者

我按照原厂的驱动进行修改参数,仍旧结果还是那样

我按照原厂的驱动进行修改参数,仍旧结果还是那样
还是只显示1/5,不知道是不是屏幕坏了。
只能再搞一块去了。

使用特权

评论回复
19
zsh198702| | 2011-3-19 20:04 | 只看该作者
去研究研究

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

349

帖子

1

粉丝