前言
诺基亚5110的屏据说是从旧手机上扣下来的,但是但是,好歹是一块串口屏,且驱动简单,所以还是记录一下。
硬件准备
NOKIA 5110屏幕模块;
补充说明
诺基亚神屏由SPI方式驱动,这里我们用软件模拟的方式驱动;
接线引脚说明如下:
RST 复位
CE 片选
DC 数据/指令
DIN 串行数据线
CLK 串行时钟线
VCC 3.3V电源
BL 背光控制端,可以不接
GND 地线
程序设计
(直接贴示例程序)
5110LCD.C
//
#include"5110LCD.h"
IIC_Start();
IIC_Send_Byte(addr);
IIC_Send_Byte(data);
IIC_Stop();
//------------GPIO口设置----------------------------
void GPIO_Configuration_LCD(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); // 改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
#define WIDTH 6
#define HEIGHT 8
unsigned char lcd_display[]="0123456789";
const unsigned char font[][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
};
//****************************************************************************************************
// 写一字节
//****************************************************************************************************
void LCD_WriteByte(unsigned char dt, unsigned char command)
{
unsigned char i;
sce0; //使能LCD
if(command==0) //传送命令
dc0;
else
dc1; //传送数据
for(i=0;i<8;i++)
{
if(dt&0x80)
sdin1;
else
sdin0;
dt=dt<<1;
sclk0;
sclk1;
}
dc1;
sce1;//关闭LCD
sdin1;
}
//****************************************************************************************************
// LCD初始化
//****************************************************************************************************
void LCD_Init(void)
{
GPIO_Configuration_LCD();
sce1;
res0;//产生一个让LCD复位的低电平脉冲
delay_ms(10);
res1;
delay_ms(100);
LCD_WriteByte(0x21,0);//使用水平寻址,进入拓展指令
LCD_WriteByte(0x13, 0);//定液晶偏置系统 1:48
LCD_WriteByte(0xbb,0);//设定设置Vop,相当于亮度
LCD_WriteByte(0x20,0);//芯片活动 使用基本指令并且水平寻址
LCD_WriteByte(0x0c,0);//设定显示模式,正常显示
LCD_Clear();
}
//---------------------------------------
//名称: 设置坐标函数
//参数:X:0-83 Y:0-5
//作者:huoenlai
//邮箱:1084170961@qq.com
//日期:2011/3/28
//-----------------------------------------
void LCD_Set_XY(unsigned char X, unsigned char Y)
{
Y|=0x40;
X|=0x80;
LCD_WriteByte(Y, 0);// 列
LCD_WriteByte(X, 0);// 行
sce1;
}
//****************************************************************************************************
// LCD清屏
//****************************************************************************************************
void LCD_Clear(void)
{
unsigned char t,k;
LCD_Set_XY(0,0);
for(t=0;t<6;t++)
{
for(k=0;k<84;k++)
{
LCD_WriteByte(0x00,1);
}
}
}
//****************************************************************************************************
// 写一个字符
//****************************************************************************************************
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c)
{
unsigned char i,j ;
const unsigned char *map = &font[0][0];
c -= 32; //变换
map += c *( HEIGHT/8*WIDTH);
for(i=0;i<HEIGHT/8;i++)
{
LCD_Set_XY(X, Y+i);
for(j=0;j<WIDTH;j++)
LCD_WriteByte(*map++, 1);
}
}
//****************************************************************************************************
// 写英文字符串
//****************************************************************************************************
void LCD_WriteString(unsigned char X,unsigned char Y,unsigned char *s)
{
unsigned char i=0,j=0;
while (*s)
{
LCD_WriteChar(X, Y,*s++);
X+=WIDTH;
i++;
if(i>=(84/WIDTH))
{
X=0;
Y+=HEIGHT;
i=0;
j++;
}
if(j>=(48/HEIGHT))
{
return ;
}
}
}
//****************************************************************************************************
// 写一个任意数字
//****************************************************************************************************
void LCD_WriteNumber(unsigned char x,unsigned char y, unsigned long number)
{
unsigned char num[10]={""},i,j,k;
if(number==0) //number 0 时候
{
LCD_WriteChar(x, y,'0');
}
else
{
for(i=0;number>0;i++)
{
num[i]=lcd_display[number%10];//每位以字符表示
number/=10;
}
for(j=0;j<i/2;j++){k=num[j];num[j]=num[i-1-j];num[i-1-j]=k;}
LCD_WriteString(x,y,num);
}
}
//-----------配置各端口的高低电平------------//
}
5110LCD.H
#ifndef __5110LCD_H
#define __5110LCD_H
#include "stm32f10x.h"
#include "delay.h"
///
//------------------------------------/ //
// SCE ------------PA5 //片选 //
// RST ------------PA4 //位选 //
// D/C ------------PA3 // 1写数据,0写指令 //
// SD ------------PA2 //数据 //
// SCLK ------------PA1 //时钟 //
// LCD ------------PA0 //背光 //
///
#define res0 GPIO_ResetBits(GPIOA, GPIO_Pin_0) //复位,0复位
#define res1 GPIO_SetBits(GPIOA, GPIO_Pin_0) //复位,0复位
#define sce0 GPIO_ResetBits(GPIOA, GPIO_Pin_1) //片选
#define sce1 GPIO_SetBits(GPIOA, GPIO_Pin_1) //片选
#define dc0 GPIO_ResetBits(GPIOA, GPIO_Pin_4) //1写数据,0写指令
#define dc1 GPIO_SetBits(GPIOA, GPIO_Pin_4) //1写数据,0写指令
#define sdin0 GPIO_ResetBits(GPIOA, GPIO_Pin_5) //数据
#define sdin1 GPIO_SetBits(GPIOA, GPIO_Pin_5) //数据
#define sclk0 GPIO_ResetBits(GPIOA, GPIO_Pin_6) //时钟
#define sclk1 GPIO_SetBits(GPIOA, GPIO_Pin_6) //时钟
void LCD_WriteByte(unsigned char dt, unsigned char command);
void LCD_Init(void);
void LCD_Set_XY(unsigned char X, unsigned char Y);
void LCD_Clear(void);
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c);
void LCD_WriteString(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_WriteNumber(unsigned char x,unsigned char y, unsigned long number);
#endif
main.c示例
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
LCD_Clear();
while(1)
{
LCD_WriteString(10,0,"good");
LCD_WriteNumber(20,5, 123456);
delay_ms(1000);
}
}
总结
感觉不如OLED有机屏好用,也没有机屏好看。