打印

LM3S811使用心得之nokia5110 LCD

[复制链接]
3677|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
baixichi|  楼主 | 2011-11-14 19:05 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 baixichi 于 2011-11-14 19:26 编辑

很遗憾,刚将5110的驱动程序写完,才看到效果,就发现811的jtag被锁死了。


本来想在LCD上边显示“Hello 21IC!”,结果一不小心将Jtag锁死了。
在上一个帖子中我就提到过,在板子复位之后,板子上的led就会点亮,为了解决这个问题,上一个程序我使用的是弱下拉。
这次,我将那几个IO口设置为输出为0,也能解决问题。不过,为了省事,直接将PC口(Jtag所在口)在类的几个IO口全部写0。
因为在程序的最初并未做防止jtag锁死处理,板子就下不进去程序了。百度之后发现,811并不支持lm flash programming解锁。
真悲剧呀!电子科大之前好像被TI加为了黑名单,现在连样片都申请不到了。。。。。。


现在来说说程序。
5110的lcd内部集成一个很小的控制器PCD8544,可以通过IO口直接控制lcd。仔细读过文档之后发现这个PCD8544是支持SPI模式的。
在看到的时候,我的程序已经写得差不多了,我是通过GPIO口控制的。不多对于50MHz的811来说,用GPIO来控制PCD8544速度已经足够了。

下面是一些宏定义和声明:


这下边是具体函数的实现:

#include "lcd.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "sysctl.h"
#include "gpio.h"
//ASCII码编码表
unsigned char font6x8[][6] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // sp
    { 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 },   // !
    { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
    { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
    { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
    { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 },   // %
    { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
    { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
    { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
    { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
    { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
    { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
    { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 },   // ,
    { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 },   // -
    { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 },   // .
    { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 },   // /
    { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0
    { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1
    { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2
    { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3
    { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
    { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
    { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
    { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
    { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
    { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
    { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
    { 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
    { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
    { 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
    { 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
    { 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
    { 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
    { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C },   // A
    { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
    { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
    { 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C },   // D
    { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 },   // E
    { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 },   // F
    { 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A },   // G
    { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H
    { 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 },   // I
    { 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 },   // J
    { 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 },   // K
    { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 },   // L
    { 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F },   // M
    { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F },   // N
    { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E },   // O
    { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 },   // P
    { 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E },   // Q
    { 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 },   // R
    { 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 },   // S
    { 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 },   // T
    { 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F },   // U
    { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F },   // V
    { 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F },   // W
    { 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 },   // X
    { 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
    { 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
    { 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
    { 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // 55
    { 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
    { 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
    { 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
    { 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
    { 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
    { 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
    { 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 },   // c
    { 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
    { 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 },   // e
    { 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
    { 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C },   // g
    { 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
    { 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
    { 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 },   // j
    { 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
    { 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
    { 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
    { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
    { 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
    { 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 },   // p
    { 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC },   // q
    { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
    { 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
    { 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 },   // t
    { 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C },   // u
    { 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C },   // v
    { 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C },   // w
    { 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 },   // x
    { 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C },   // y
    { 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 },   // z
    { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }    // horiz lines
};
//**********************************************************
//***********************延时ms
void Delay_Ms(unsigned long time)
{
  SysCtlDelay(SysCtlClockGet()/3000*time);
}

//**********************************************************
//***********************发命令
void Write_Cmd(unsigned char cmd)
{
  //CE_H        //串口被初始化
// Delay_Ms(1);
  CE_L        //串口开始接受数据
   
  DC_L        //发命令
    for(int i=0;i<8;i++)
    {
      if(cmd&0x80)
        Data_1
      else
        Data_0
         
      Clock_L
      cmd=cmd<<1;
      Clock_H
    }
  CE_H     
}
//**********************************************************
//***********************发数据
void Write_Data(unsigned char data)
{
  //CE_H        //串口被初始化
// Delay_Ms(1);
  CE_L        //串口开始接受数据
   
  DC_H        //发数据
    for(int i=0;i<8;i++)
    {
      if(data&0x80)
        Data_1
      else
        Data_0
         
      Clock_L
      data=data<<1;
      Clock_H
    }   
  CE_H  
}
//***********************************************************
//***********************初始化lcd
void LCD_Init()
{
  //***************初始化引脚
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,0xff);
  
  //***************初始化LCD
  Reset_L                 //必须复位,接通电源后,内部寄存器和RAM的内容不确定
  Delay_Ms(1);
  Reset_H
   
  CE_L
  Delay_Ms(1);
  CE_H
  Delay_Ms(1);
  
  Write_Cmd(0x21);  //LCD模式
  Write_Cmd(0xc8);  //LCD偏执电压
  Write_Cmd(0x06);  //温度校正
  Write_Cmd(0x13);  //1:48
  Write_Cmd(0x20);  //使用基本命令,V=0,水平寻址
  LCD_Clear();      //清屏
  Write_Cmd(0x0c);  //设定显示模式,正常显示
  CE_L
}
//清屏
void LCD_Clear()
{
  Write_Cmd(0x0c);
  Write_Cmd(0x80);
  for(unsigned long i=0;i<504;i++)
  {
    Write_Data(0);
  }
}
//设置坐标
void LCD_Set_XY(unsigned char x,unsigned char y)
{
  Write_Cmd(0x40|y);//0<=Y<=5
  Write_Cmd(0x80|x);//0<=x<=83
}
//显示字符
void Display_char(char c)
{
  c-=32;
  for(int line=0;line<6;line++)
  {
    Write_Data(font6x8[c][line]);
  }
}
//显示字符串
void Display_String(unsigned char x,unsigned char y,char *s)
{
  LCD_Set_XY(x,y);
  while(*s)
  {
    Display_char(*s);
    s++;
  }
}


上边的程序有参考网上51的程序,因为板子的原因,并没有优化,有待修改。

PCD8544中文版.pdf (814.48 KB)
Nokia5110LCD.pdf (438.77 KB)

SNC00689.jpg (1.22 MB )

SNC00689.jpg

相关帖子

沙发
lanzeex| | 2011-11-14 20:17 | 只看该作者
不错哦...

使用特权

评论回复
板凳
fq1110| | 2011-11-14 23:37 | 只看该作者
是啊。。我也想整个oled显示了。

使用特权

评论回复
地板
wintryer| | 2011-11-14 23:40 | 只看该作者
:)

使用特权

评论回复
5
tcwntc| | 2011-11-15 14:27 | 只看该作者
有两个问题想请教楼主 1.为何电子科大被加入黑名单 是因为恶意申请? 2. 何为JTAG锁死呢?

使用特权

评论回复
6
baixichi|  楼主 | 2011-11-15 14:57 | 只看该作者
回答5楼的问题,第一,因为爱学习的太多,申请芯片的同学也太多。第二,JTAG锁死我遇到的有两个问题,
将JTAG所在引脚当IO口操作,还有就是在配置时钟的时候,将晶振的频率配置错了,如6MHz配置为8MHz

使用特权

评论回复
7
baixichi|  楼主 | 2011-11-15 14:58 | 只看该作者

这里是对帖子的补充

本帖最后由 baixichi 于 2011-11-15 15:11 编辑

这里我将对帖子做一个补充,关于设置LCD坐标和发送显示的数据。


5110的LCD的像素点为48*84。如上图所示:
x方向可以显示14个字符,每个字符在x方向上,占6个像素点,我们在软件操作上,可以将两相邻字符相隔一个像素点。
y方向可以显示6个字符,每个字符在y方向上,占8个像素点,我们在软件操作上,可以两相邻字符相隔一个像素点。
故在void LCD_Set_XY(unsigned char x,unsigned char y)函数中,0<=x<=83,0<=Y<=5。


在向lcd写数据的时候,其实就是对每个像素点操作,写1代表显示,写0代表不显示。我们以字符“!”为例,可以发现,在数组font6x8[][6]中,
每个字符的第一个数据元素为0x00,也就是说最左边的那一列不显示,在屏幕上看到的效果就是两个字符间的空格。
细心的可以发现,数组中每个数据元素的最高位都为0,在屏幕上看到的就是上下两行有间距。
值得注意的是,
数组元素的低位,对应的是低地址。

使用特权

评论回复
8
永远的不知| | 2011-11-15 15:18 | 只看该作者
精华帖啊,写的真不错,期待baixichi 兄更多精彩**。

使用特权

评论回复
9
nayaix| | 2011-11-15 16:26 | 只看该作者
顶起阿

使用特权

评论回复
10
heziyan| | 2011-11-18 09:26 | 只看该作者
支持,向楼主学习

使用特权

评论回复
11
21小跑堂| | 2011-11-19 14:49 | 只看该作者
很不错!期待楼主更多研究成果哦!:handshake

使用特权

评论回复
12
去耦滤波| | 2011-11-19 16:51 | 只看该作者
支持楼主,再多来点研究成果给大家学学啊

使用特权

评论回复
13
baixichi|  楼主 | 2011-11-19 23:28 | 只看该作者
谢谢支持,,继续努力

使用特权

评论回复
14
hlmdd| | 2013-4-27 10:23 | 只看该作者
很好啊,学习了

使用特权

评论回复
15
meishizhaoshi| | 2013-4-28 21:49 | 只看该作者
想起我的第一个nokia手机了

使用特权

评论回复
16
someontime| | 2013-4-28 22:34 | 只看该作者
一看标题就知道是很久之前的帖子

使用特权

评论回复
17
specialfrin| | 2013-4-28 22:43 | 只看该作者
楼主好厉害

使用特权

评论回复
18
justbybing| | 2013-4-28 22:57 | 只看该作者
当初诺基亚盛行的时候楼主肯定花了不少心思在上面吧

使用特权

评论回复
19
someonewho| | 2013-4-28 23:02 | 只看该作者
有参考价值

使用特权

评论回复
20
waitingf| | 2013-4-28 23:29 | 只看该作者
楼主好强大

使用特权

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

本版积分规则

3

主题

57

帖子

1

粉丝