xunke 发表于 2020-2-12 22:28:04

分享MSP430FR2433+nokia5110 LCD屏一行汉字左移的程序

本帖最后由 xunke 于 2020-2-13 21:07 编辑

放假在家弄了一个nokia5110 LCD屏显示一行左移的程序,不过移动时显示有点抖并且移动得越快越抖,效果不如静态显示的,是不是这种LCD屏不合适动态显示?请有经验的网友指点下。
程序和效果图如下:
/*****************************************************************************
说明:
环境: IAR EW430 V6.50
硬件: 1) MSP430FR2433 + nokia5110 LCD模组.
      2) MCU系统时钟为默认DCO=1MHz,工作电压为3.3V
      3) 接口P1
      4) LCD的x为0--83Px,y为0--5page 每page宽度为1字节
作者: 448254938@qq.com , 2020年02月12

*****************************************************************************/
#include "msp430fr2433.h"
#include "5110_font.h"

#define u8 unsigned char
#define u16 unsigned int
#define CMD 0                                 //命令标志
#define DAT 1                                 //数据标志

//LCD IO定义-----------------------------------------------------------
#define LCD_CLK_P0    0x01                      //定义Pn.0引脚为LCD时钟IC
#define LCD_DIN_P1    0x02                      //定义Pn.1引脚为LCD数据IO
#define LCD_DC_P2   0x04                      //定义Pn.2引脚为LCD数据/命令选择IO
#define LCD_CE_P3   0x08                      //定义Pn.3引脚为LCD传送使能IO
#define LCD_RES_P4    0x10                      //定义Pn.4引脚为LCD复位IO
                                                                        //--以上n为MCU的端口号,如P1口,n为1
#define LcdOut   P1OUT                        //LCD输出端口
#define LCD_CLK_LLcdOut &(~LCD_CLK_P0)      //时钟输出低电平
#define LCD_CLK_HLcdOut | LCD_CLK_P0          //时钟输出高电平,上升沿有效
#define LCD_DIN_LLcdOut &(~LCD_DIN_P1)      //数据输出低电平
#define LCD_DIN_HLcdOut| LCD_DIN_P1         //数据输出高电平
#define LCD_DC_L   LcdOut & (~LCD_DC_P2)      //输出高电平,选择数据
#define LCD_DC_H   LcdOut | LCD_DC_P2         //输出低电平,选择命令
#define LCD_CE_L   LcdOut &(~LCD_CE_P3)         //输出低电平,传送使能
#define LCD_CE_H   LcdOut | LCD_CE_P3         //输出高电平,传送禁止
#define LCD_RES_LLcdOut &( ~LCD_RES_P4 )      //输出低电平,复位使能
#define LCD_RES_HLcdOut | LCD_RES_P4          //输出高电平,复位禁止

//定义内部函数-------------------------------------------------------------
#define CPU_F ((unsigned long)1000000)
#define Delay_ms(x)   __delay_cycles((unsigned long)( CPU_F*x/1000 ))

/***********************************************************************
函数: LcdWriteByte( u8 DaFlg, u8 Dat)
入参:
(1) u8 DatFlg: 写数据标志,其值为1(DAT)则表写数据,为0(CMD)则表写命令
(2) u8 Dat: 一个字节数据/命令
返参: 无
功能: 写向LCD一个字节的数据或者命令,操作时序请见手册.
***********************************************************************/
void LcdWriteByte( u8 DatFlg, u8 Dat )
{
    u8 i = 0;                      //为暂存变量
   
    //判别数据还是命令--------
    if( DatFlg )
    {
      LcdOut = LCD_DC_H;         //bDatFlg=1则为数据,LCD_CD为高电平
    }
    else
    {
      LcdOut = LCD_DC_L;         //bDatFlg=0则为命令,LCD_CD为低电平   
    }
   
    //发送准备-----------------
    LcdOut = LCD_CLK_L;            //时钟信号准备,CLK->0
    LcdOut = LCD_CE_L;             //'0'芯片传送使能,CE为低电平
   
    //数据输出-----------------
    for( i=0; i<8; i++ )          //输出8位
    {
       LcdOut = LCD_CLK_L;      //时钟信号准备,CLK->0
       if( Dat&0x80 )             //先发最高位(MSB)
       {
          LcdOut = LCD_DIN_H;   //-发"1"
       }
       else
       {
          LcdOut = LCD_DIN_L;   //-发"0"
       }
       __no_operation();          //延时   
       LcdOut = LCD_CLK_H;      //时钟上升沿有效,CLK->1
       __no_operation();
       Dat <<= 1;               //准备发送下一位
    }
   
    LcdOut = LCD_CLK_L;         //CLK->0
    LcdOut = LCD_CE_H;            //CE=1,芯片禁止传送
    LcdOut = LCD_CLK_H;         //CLK->1
    LcdOut = LCD_DC_H;            //DC=1
}


/*****************************************************************
函数: LcdSetXy( u8 x, u8 y )
入参:
    (1) u8 x : LCD的x坐标(小写),单位Px
    (2) u8 y : LCD的y坐标(小写),单位page
返参: 无
功能: 设置LCD显示的位置,x为0--83Px,y为0--5page 每page宽度为1字节

******************************************************************/
void LcdSetXy( u8 x, u8 y )
{
    LcdWriteByte( CMD, 0x80|x );
    LcdWriteByte( CMD, 0x40|y );
}

//****************************************************
#define LCD_WIDTH       84            //LCD宽度值,即x轴,单位px,1字节有8px
#define LCD_HEIGHT      6               //LCD高度值,即y轴,单位page,1page高度为1字节

void LcdShowRam( u8 x, u8 y, u8 width, u8 height, u8 *p )
{
   u8 w=0;                              //用于存求宽度(x轴)的结果,小写,单位px            
   u8 h=0;                              //用于存求高度(y轴)的结果,单位page
   u8 i=0;                              //为暂存变量
   u8 d=0;                              //为暂存变量
   u8 ww=0;                           //为暂存变量(小写)
   
   //求宽(单位px)--------------
   if( x > LCD_WIDTH )                  //超过LCD的显示区吗?
   {
      x = LCD_WIDTH;
   }   
   w = LCD_WIDTH - x;
   
   //求高(单位page)------------
   if( height&0x07 )
   {
      height = height + 0x08;         //加8,即不满1个字节则凑足1个字节
   }
   h = y + ( height>>3 );               //等价为h=y+(height/8),px转page
   if( h > LCD_HEIGHT )               //超过LCD的显示区吗?
   {
      h = LCD_HEIGHT;
   }
   //写数据,从左->右,从上->下----
   for( i=0; y+i<h; i++ )
   {
      LcdSetXy( x, y+i );
      ww = w;
      while( ww-- )
      {
          d = *p++;
          LcdWriteByte( DAT, d );         
      }
      p += x;
   }
}

//********************************************************
#define rLINE_NUB       (16/8)
#define rROW_NUB      84
#define FONT_NUB      24
#define FONT_HEIGHT   16

u8 HzShowRam[ rLINE_NUB ][ rROW_NUB ];
u8 HzShowBuf[ FONT_NUB ];

void LcdShiftLineHz( u8 x, u8 y, u16 *p )
{
    u8 i = 0;
    u8 n = 0;
    u16 TabLine = 0;
    while( *p )
    {
       i = 0;
       while( HzTab )
       {
          if( *p == HzTab )
          {   
               TabLine = HzTab;
                for( i=0; i<FONT_NUB; i++ )
               {
                  HzShowBuf = HzFontTab_12[ TabLine ][ i ];
               }
               
               for( n=0; n<(FONT_NUB/2); n++ )
               {      
                  for( i=0; i<(rROW_NUB-1); i++)
                  {
                      HzShowRam = HzShowRam[ i+1 ];
                      HzShowRam = HzShowRam[ i+1 ];
                  }            
                  HzShowRam = HzShowBuf;
                  HzShowRam = HzShowBuf[ FONT_NUB/2 + n ];
                  for( i=0; i<(FONT_NUB/2 - 1); i++ )
                  {
                     HzShowBuf[ i ] = HzShowBuf[ i+1 ];
                     HzShowBuf[ rROW_NUB/2 + i ] = HzShowBuf[ rROW_NUB/2 + i + 1 ];
                  };
                  
                  //Delay_ms( 200 );
                  i = 3;
                  while( i-- )
                  {
                      LcdShowRam( x, y, rROW_NUB, FONT_HEIGHT , (u8 *)HzShowRam );
                  }
               }
               break;
          }      
          i++;
       }
       p++;
    }
}


void LcdInitial()
{   
   LcdOut = LCD_RES_L;                //RES=0则复位
   Delay_ms(1);
   LcdOut = LCD_RES_H;               
   
   LcdWriteByte( CMD, 0x21 );         //准备发送扩展命令(CMD=1)
   LcdWriteByte( CMD, 0xd0 );         //-设置Vop电压,0xd0为最佳值
   LcdWriteByte( CMD, 0x20 );         //准备发送基本命令
   LcdWriteByte( CMD, 0x0c );         //-设置显示模式为普通模式(b2=1,b0=0)
   
}

//***************************************************************************************
const u16 Hz[]={'这','里','远','比','混','乱','的','现','实','世',
               '界','美','好', 1, '电','工','平','安','健','康',1,'\0'};

main( )
{   

    WDTCTL = WDTPW + WDTHOLD;         //关闭看门狗
   
    //所有IO为高电平输出------------------   
    P1DIR = 0xff;                     //P1口为输出模式
    P2DIR = 0xff;                     //P2口为输出模式
   
    P1OUT = 0xff;                     //P1输出高电平
    P2OUT = 0xff;                     //P2输出高电平
   
    PM5CTL0 &= ~LOCKLPM5;               //PM5模式寄存器的LOCKLPM5=0则IO工作
   
    //初始化LCD---------------------------
    LcdInitial();

    //显示一行左移的汉字-
    LcdShiftLineHz(0, 0, (u16 *)Hz );
    while(1 )
    {   
    }
}
本来注释是整齐的,贴上来就不齐了。


这个gif图可能看不出具体效果,现在老家电脑没网络发视频,手机太麻烦了、眼睛又累。
字模(包含文件)请见附件

qiqirachel 发表于 2020-2-13 03:04:07

都2020了 诺基亚屏还在诈尸

Himem 发表于 2020-2-13 03:14:45

叙述没看懂,是残影?对比度压低点试试

5110屏除了胶条时间长了会接触不良外其实挺好用的

huangqi412 发表于 2020-2-13 09:15:41

这种屏算古董了

xunke 发表于 2020-2-13 17:30:59

本帖最后由 xunke 于 2020-2-13 21:04 编辑

Himem 发表于 2020-2-13 03:14
叙述没看懂,是残影?对比度压低点试试

5110屏除了胶条时间长了会接触不良外其实挺好用的 ...

是不是残影是LCD的通病?
我这个屏也是放了很久了,有点接触不良了,有时不能显示用手按按屏又行了。
改了程序 测试一下,图1的会残影,图2的会抖动。



图2的效果视频https://www.bilibili.com/video/av88693889/

xunke 发表于 2020-2-13 17:33:11

qiqirachel 发表于 2020-2-13 03:04
都2020了 诺基亚屏还在诈尸

放假在老家手头上只有这屏了。

dongwang_fl 发表于 2020-2-13 19:47:12

我也有2片,前几天做了个板,准备把他用起来,其它元件还在路上.有差不多买了10年了.

xqn2012 发表于 2020-2-13 19:52:05

家里还有2片这种屏。MSP430,没玩过。

xunke 发表于 2020-2-13 20:58:59

huangqi412 发表于 2020-2-13 09:15
这种屏算古董了

算是吧,只能显示简单的东西,不过优点就是低功耗。

xunke 发表于 2020-2-13 21:08:30

dongwang_fl 发表于 2020-2-13 19:47
我也有2片,前几天做了个板,准备把他用起来,其它元件还在路上.有差不多买了10年了.
...

请问准备做什么电路?

NFC 发表于 2020-2-13 21:31:47

我发现5110一致性不好
以前买过10个
偶尔拿出来用一个
表现为不同的屏幕,相同的程序,对比度不一样
有的显示较浓,有的淡,甚至不显示,要调节温度参数或者对比度参数才可以

xunke 发表于 2020-2-13 22:41:09

NFC 发表于 2020-2-13 21:31
我发现5110一致性不好
以前买过10个
偶尔拿出来用一个


那是,可能都是拆机的、质量掺差不齐,所以玩玩还可以,做产品慎用。

dpzc1234 发表于 2020-2-14 08:51:42

谢谢分享

dongwang_fl 发表于 2020-2-14 13:45:55

xunke 发表于 2020-2-13 21:08
请问准备做什么电路?

做了个lora通信板,顺便做了这个屏的接口上去,就是弄来玩玩

xunke 发表于 2020-2-14 17:12:05

dongwang_fl 发表于 2020-2-14 13:45
做了个lora通信板,顺便做了这个屏的接口上去,就是弄来玩玩

LoRA用什么芯片或模块?

rengo 发表于 2020-2-14 21:05:36

超级古董屏,经济适用,价格公道, 驱动简单

dongwang_fl 发表于 2020-2-15 09:00:14

xunke 发表于 2020-2-14 17:12
LoRA用什么芯片或模块?

安信可的 LORA-02

wangdanq 发表于 2020-9-10 13:20:57

谢谢分享超级古董屏,经济适用很好的学习模块
页: [1]
查看完整版本: 分享MSP430FR2433+nokia5110 LCD屏一行汉字左移的程序