打印
[STM32F1]

stm32f101驱动12864

[复制链接]
990|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件连接2,19脚连接5V,可调电阻正常连接。其他IO口直接连接stm32f101的IO口。软件
/*写命令到LCD*/
void SendCommandToLCD(INT8U com)
{
  INT16U Tcom;
  Tcom=com;
  CheckState();//状态检测LCD是否忙
  GPIO_WriteBit(GPIO_LCD_RS,
                PORT_LCD_RS,
                (BitAction)PIN_LCD_RS_ENABLE);         //向LCD发送命令。RS=0写指令,RS=1写数据
  GPIO_WriteBit(GPIO_LCD_RW,
                PORT_LCD_RW,
                (BitAction)PIN_LCD_RW_ENABLE);//R/W="L",E="H->L"数据被写到IR或DR
//DATA=com;         //com :命令
GPIOB->ODR=(GPIOB->ODR & 0xfc0f)|((Tcom<<2)&0xfff3);
if(com&0x01)
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_ENABLE);
}
if(com&0x02)
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_ENABLE);
}
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_DISABLE);//EN下降沿
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_ENABLE);//EN下降沿
}
/*选择屏幕 0全屏,1左屏 2右屏*/
void SelectScreen(INT8U screen)         
{switch(screen)
{
case 0:   GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_DISABLE);//全屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_DISABLE);
  break;
  case 1:  GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_DISABLE);//左屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_ENABLE);
  break;
  case 2: GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_ENABLE);//右屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_DISABLE);
  break;
}
}
/*初始化LCD*/
void init_lcd()           
{

        CheckState();
SelectScreen(0);
SetOnOff(0); //关显示
SelectScreen(0);
SetOnOff(1); //开显示
SelectScreen(0);
ClearScreen(0);//清屏
SetStartLine(0); //开始行:0
        
        
        
        

}
初始化之后一直无**常显示
沙发
feiyang0725|  楼主 | 2016-6-16 11:30 | 只看该作者
显示区域很小

QQ图片20160614154350.jpg (347.21 KB )

QQ图片20160614154350.jpg

QQ图片20160614154359.jpg (367.04 KB )

QQ图片20160614154359.jpg

使用特权

评论回复
板凳
jiangjian0206| | 2016-6-17 09:29 | 只看该作者
这是  没有成功吗,DB0-DB7 上啦电阻,实现读取指令。

使用特权

评论回复
地板
ROOTHer| | 2016-6-17 11:15 | 只看该作者
应该是显示地址没有写对,错位了

使用特权

评论回复
5
feiyang0725|  楼主 | 2016-6-17 17:10 | 只看该作者
jiangjian0206 发表于 2016-6-17 09:29
这是  没有成功吗,DB0-DB7 上啦电阻,实现读取指令。

我询问液晶屏的供应商,那边提示硬件可以直接这样设计的。。

使用特权

评论回复
6
feiyang0725|  楼主 | 2016-6-17 17:11 | 只看该作者
ROOTHer 发表于 2016-6-17 11:15
应该是显示地址没有写对,错位了

#define _LCD_DRV_C_

#include "Drv.h"
#include "Fmm.h"



//----------------------------------------------------------
void Delay(INT16U times)
  {
   while(times)
   {
    times--;
   }
  }
//----------------------------------------------------------
void M_Delay(INT16U NOs)
  {
   while(NOs)
   {
    Delay(200);
    NOs--;
   }
  }



//----------------------------------------------------------

//IO输入
void IOInitIn()
{
    GPIO_InitTypeDef InitType;
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAH;
    InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_Init(GPIOB,&InitType);
   
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAL0;
    InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    GPIO_Init(GPIO_LCD_CMD_DATAL0_SELECT,&InitType);
        
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAL1;
    InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;//数据引脚为浮空输入
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
    GPIO_Init(GPIO_LCD_CMD_DATAL1_SELECT,&InitType);
  
}
//IO输出
void IOInitOut()
{
  GPIO_InitTypeDef InitType;
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAH;
    InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_Init(GPIOB,&InitType);
   
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAL0;
    InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    GPIO_Init(GPIO_LCD_CMD_DATAL0_SELECT,&InitType);
        
    InitType.GPIO_Speed=GPIO_Speed_50MHz;
    InitType.GPIO_Pin = DATAL1;
    InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
    GPIO_Init(GPIO_LCD_CMD_DATAL1_SELECT,&InitType);
   
   
     InitType.GPIO_Speed=GPIO_Speed_50MHz;//RS
     InitType.GPIO_Pin = PORT_LCD_RS;
     InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
     GPIO_Init(GPIO_LCD_RS,&InitType);
     
     
     InitType.GPIO_Speed=GPIO_Speed_50MHz;//RW
     InitType.GPIO_Pin = PORT_LCD_RW;
     InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
     GPIO_Init(GPIO_LCD_RW,&InitType);
     
     InitType.GPIO_Speed=GPIO_Speed_50MHz;//EN
     InitType.GPIO_Pin = PORT_LCD_EN;
     InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
     GPIO_Init(GPIO_LCD_EN,&InitType);
     
     
      InitType.GPIO_Speed=GPIO_Speed_50MHz;//CS1
     InitType.GPIO_Pin = PORT_LCD_CS1;
     InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
     GPIO_Init(GPIO_LCD_CS1,&InitType);
     
      InitType.GPIO_Speed=GPIO_Speed_50MHz;//CS2
     InitType.GPIO_Pin = PORT_LCD_CS2;
     InitType.GPIO_Mode=GPIO_Mode_Out_PP;//数据引脚为推挽输出
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
     GPIO_Init(GPIO_LCD_CS2,&InitType);
     
     
     
  
}
//检测忙
void CheckState()        
{

  GPIO_WriteBit(GPIO_LCD_RS,
                PORT_LCD_RS,
                (BitAction)PIN_LCD_RS_ENABLE);
   GPIO_WriteBit(GPIO_LCD_RW,
                PORT_LCD_RW,
                (BitAction)PIN_LCD_RW_DISABLE);

    GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_DISABLE);        //EN下降沿
     IOInitIn();
     while(GPIO_ReadInputData(GPIOB) & 0x0100);
     GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_ENABLE);        //EN下降沿
IOInitOut();
  
}
/*写命令到LCD*/
void SendCommandToLCD(INT8U com)
{
  INT16U Tcom;
  Tcom=com;
  CheckState();//状态检测LCD是否忙
  GPIO_WriteBit(GPIO_LCD_RS,
                PORT_LCD_RS,
                (BitAction)PIN_LCD_RS_ENABLE);         //向LCD发送命令。RS=0写指令,RS=1写数据
  GPIO_WriteBit(GPIO_LCD_RW,
                PORT_LCD_RW,
                (BitAction)PIN_LCD_RW_ENABLE);//R/W="L",E="H->L"数据被写到IR或DR
//DATA=com;         //com :命令
GPIOB->ODR=(GPIOB->ODR & 0xfc0f)|((Tcom<<2)&0xfff3);
if(com&0x01)
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_ENABLE);
}
if(com&0x02)
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_ENABLE);
}
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_DISABLE);//EN下降沿
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_ENABLE);//EN下降沿
}
/*设置页0Xb8是页的首地址*/
void SetLine(INT8U page)        
{page=0xb8|page; //1011 1xxx 0<=page<=7设定页地址 --X 0-7,8行为一页64/8=8,共8页
SendCommandToLCD(page);
}
/*设定显示开始行,0xc0是行首地址*/
void SetStartLine(INT8U startline)            
{startline=0xc0|startline; //1100 0000
SendCommandToLCD(startline); //设置从哪行开始:0--63,一般从0行开始显示
}

/*设定列地址--Y 0-63,0x40为列首地址*/
void SetColumn(INT8U column)        
{column=column &0x3f; //column最大值为64,输出 0=<column<=63
column= 0x40|column; //01xx xxxx
SendCommandToLCD(column);
}
/*开关显示,0x3f是开显示,0x3e是关显示*/
void SetOnOff(INT8U onoff)           
{onoff=0x3e|onoff; //0011 111x,onoff只能为0/1
SendCommandToLCD(onoff);
}
/*写显示数据*/
void WriteByte(INT8U dat)        
{
  INT16U Tcom;
  Tcom=dat;
CheckState();//状态检查,LCD是否忙
GPIO_WriteBit(GPIO_LCD_RS,
                PORT_LCD_RS,
                (BitAction)PIN_LCD_RS_DISABLE);         //向LCD发送命令。RS=0写指令,RS=1写数据 //RS=0写指令 RS=1写数据
GPIO_WriteBit(GPIO_LCD_RW,
                PORT_LCD_RW,
                (BitAction)PIN_LCD_RW_ENABLE);//R/W="L",E="H->L"数据被写到IR或DR////R/W="L",E="H->L"数据被写到IR/DR
GPIOB->ODR=(GPIOB->ODR & 0xfc0f)|((Tcom<<2)&0xfff3);
if(dat&0x01)
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
   GPIO_WriteBit(GPIO_LCD_CMD_DATAL0_SELECT,
                DATAL0,
                (BitAction)PIN_LCD_RW_ENABLE);
}
if(dat&0x02)
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_DISABLE);
}
else
{
    GPIO_WriteBit(GPIO_LCD_CMD_DATAL1_SELECT,
                DATAL1,
                (BitAction)PIN_LCD_RW_ENABLE);
}//dat:显示数据
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_DISABLE);//EN下降沿
GPIO_WriteBit(GPIO_LCD_EN,
                PORT_LCD_EN,
                (BitAction)PIN_LCD_EN_ENABLE);//EN下降沿
}
/*选择屏幕 0全屏,1左屏 2右屏*/
void SelectScreen(INT8U screen)         
{switch(screen)
{
case 0:   GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_DISABLE);//全屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_DISABLE);
  break;
  case 1:  GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_DISABLE);//左屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_ENABLE);
  break;
  case 2: GPIO_WriteBit(GPIO_LCD_CS1,
                PORT_LCD_CS1,
                (BitAction)PIN_LCD_CS1_ENABLE);//右屏
            GPIO_WriteBit(GPIO_LCD_CS2,
                PORT_LCD_CS2,
                (BitAction)PIN_LCD_CS2_DISABLE);
  break;
}
}
//初始化液晶
void LcdDrvInit(void)
{
        //初始化端口
        IOInitOut();
        //复位液晶

        //延时
        
        //初始化变量
        memset(&gLcdDrvData,0,sizeof(LCD_DRV_DATA_STRUCT));
}

//初始化液晶端口
void LcdDrvPortInit(void)
{
        GPIO_InitTypeDef InitType;
        InitType.GPIO_Speed=GPIO_Speed_50MHz;
        //置输出上拉
          InitType.GPIO_Pin = DATAH;
        InitType.GPIO_Mode=GPIO_Mode_IN_FLOATING;
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        GPIO_Init(GPIOB,&InitType);
        
}

//延时
void LcdDrvDelay(INT16U DelayTime)
{
        for(;DelayTime>0;DelayTime--);
}

//加载对比度
void LcdDrvLoadContrastValue(INT8U ContrastValue)
{
        //对比度值越界
#if 0
        if(ContrastValue>=CONTRAST_MAX_VALUE)
                return;
        //发送对比度调节命令
        LcdDrvSendLcdData(SEND_LCD_COMMAND,
                DISPLAY_COMMAND_SET_CONTRAST_MODE);
        //发送对比度调节数据
        LcdDrvSendLcdData(SEND_LCD_COMMAND,
                ContrastValue);
#endif
}

//发送液晶数据
void LcdDrvSendLcdData(LCD_DRV_SEND_CMD_DATA_SELECT_Def SelectType,
        INT8U SendData)
{
#if 0
        INT8U i,DelayNop;
        //选择发送类型
        switch(SelectType)
        {
        //发送指令
        case SEND_LCD_COMMAND:
                GPIO_WriteBit(GPIO_LCD_CMD_DATA_SELECT,
                        PORT_LCD_CMD_DATA_SELECT,
                        (BitAction)PIN_LCD_CMD_SELECT);
                break;
        //发送数据
        case SEND_LCD_DATA:
                GPIO_WriteBit(GPIO_LCD_CMD_DATA_SELECT,
                        PORT_LCD_CMD_DATA_SELECT,
                        (BitAction)PIN_LCD_DATA_SELECT);
                break;
        default:
                return;
        }
        //片选
        GPIO_WriteBit(GPIO_LCD_CHIP_SELECT,
                PORT_LCD_CHIP_SELECT,
                (BitAction)PIN_LCD_CHIP_SELECT_ENABLE);
        //发送
        for(i=0;i<8;i++)
        {
                if((SendData&0x80)==0x80)
                        GPIO_WriteBit(GPIO_LCD_SOUT,
                                PORT_LCD_SOUT,
                                (BitAction)PIN_LCD_SOUT_HIGH);                        
                else
                        GPIO_WriteBit(GPIO_LCD_SOUT,
                                PORT_LCD_SOUT,
                                (BitAction)PIN_LCD_SOUT_LOW);                        
                //延时
                DelayNop=DelayNop;DelayNop=DelayNop;
                DelayNop=DelayNop;DelayNop=DelayNop;
                //产生时钟上升沿
                GPIO_WriteBit(GPIO_LCD_SCLK,
                        PORT_LCD_SCLK,
                        (BitAction)PIN_LCD_SCLK_HIGH);                        
                //延时
                DelayNop=DelayNop;DelayNop=DelayNop;
                DelayNop=DelayNop;DelayNop=DelayNop;
                //恢复时钟信号低电平
                GPIO_WriteBit(GPIO_LCD_SCLK,
                        PORT_LCD_SCLK,
                        (BitAction)PIN_LCD_SCLK_LOW);                        
                SendData<<=1;
        }
        //撤消片选
        GPIO_WriteBit(GPIO_LCD_CHIP_SELECT,
                PORT_LCD_CHIP_SELECT,
                (BitAction)PIN_LCD_CHIP_SELECT_DISABLE);
#endif
}


//显示半角汉字/数字/字母
void Displayen(INT8U ss,INT8U page,INT8U column,INT8U *number)
{INT8U i;//选屏参数,page选页参数,column选列参数,number选第几汉字输出
SelectScreen(ss);
column=column&0x3f;
SetLine(page);        //写上半页
SetColumn(column);
for(i=0;i<8;i++)
{WriteByte(number);}
SetLine(page+1);        //写下半页
SetColumn(column);
for(i=0;i<8;i++)
{WriteByte(number[i+8]);}
}




/*显示全角汉字*/
void Display(INT8U ss,INT8U page,INT8U column,INT8U *number)
{INT8U i;        //选屏参数,page选页参数,column选列参数,number选第几汉字输出
SelectScreen(ss);
column=column&0x3f;
SetLine(page);        //写上半页
SetColumn(column); //控制列
for(i=0;i<16;i++)  //控制16列的数据输出
{WriteByte(number);}//i+32*number汉字的前16个数据输出
SetLine(page+1);                 //写下半页
SetColumn(column);           //控制列
for(i=0;i<16;i++)          //控制16列的数据输出
{WriteByte(number[i+16]);}//i+32*number+16汉字的后16个数据输出
}


//液晶驱动
void LcdDrvLoadLcdData(INT8U lin,
        INT8U column,INT8U *LcdData,
        INT8U Len)
{
        INT8U ss=0;
        
        //×?·?
        if(Len==16)
  {
                column=column*8;
        
          //if(column<8) SelectScreen(0);        //如果列队<8(0,1,2,3,4,5,6,7)则写在第一屏上面
                 if(column<64)
            {
                                ss=1;
                    
            }
                        else  
                        {
                                ss=2;
                                column=column-64;
                        }
                lin=lin<<1;
        Displayen(ss,lin,column,LcdData);
        }        
   if(32==Len)
         {
                 column=column*16;
        

                 if(column<64)
            {
                                ss=1;
            }
                        else  
                        {
                                ss=2;
                                column=column-64;

                        }
                 lin=lin<<1;        
                  Display(ss,lin,column,LcdData);
         }
        
}

/*------------------显示边框-------------------------------*/
void frame()
{
        INT8U i;
        SelectScreen(2);
        for (i = 0;i < 8;i++)
        {
                SetLine( i);                                                         //共8页
                SetColumn( 31);                                                        //最后一页
                WriteByte(0xff);                                                                        //ff表示每页的8行全亮
         //#define Page_Add 0xb8        //起始页地址
//#define Start_Line 0xc0        //起始行地址
               
        }
}
/*清屏screen: 0-全屏,1-左屏,2-右屏*/
void ClearScreen(INT8U screen)         
{INT8U i,j;
SelectScreen(screen);
for(i=0;i<8;i++)         //控制页数0-7,共8页
{SetLine(i);
  SetColumn(0);
  for(j=0;j<64;j++)           //控制列数0-63,共64列
  {WriteByte(0x00);} //写点内容,列地址自动加1
}
}
/*初始化LCD*/
void init_lcd()           
{

        CheckState();
SelectScreen(0);
SetOnOff(0); //关显示
SelectScreen(0);
SetOnOff(1); //开显示
SelectScreen(0);
ClearScreen(0);//清屏
SetStartLine(0); //开始行:0
        
        
        
        

}

使用特权

评论回复
7
feiyang0725|  楼主 | 2016-6-17 17:12 | 只看该作者
ROOTHer 发表于 2016-6-17 11:15
应该是显示地址没有写对,错位了

代码地址是按照之前的驱动写的!!应该没有错。。。

使用特权

评论回复
8
jiangjian0206| | 2016-6-17 23:17 | 只看该作者
好像我以前 打开 画图的指令,请问画图显示关掉了吗?

使用特权

评论回复
9
Bermanrep| | 2016-6-18 09:20 | 只看该作者

驱动LCD的线上加上拉电阻了吗

使用特权

评论回复
10
feiyang0725|  楼主 | 2016-6-20 11:10 | 只看该作者
Bermanrep 发表于 2016-6-18 09:20
驱动LCD的线上加上拉电阻了吗

应该是时钟设置问题。。别人用我的代码在103上面跑起来了。。我现在在看101如何设置。。

使用特权

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

本版积分规则

31

主题

124

帖子

1

粉丝