前言:

为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。


1.概述

128X64的LCD可以显示 128 列64 行点阵单色图片,或显示 8 个/行4 行 1616 点阵的汉字,或显示 16 个/行8 行 8*8 点阵的英文、数字、符号。驱动IC为 ST7565R。在 LCD 上排列着 128×64 点阵,128 个列信号与驱动 IC 相连,64 个行信号也与驱动 IC 相连,IC 邦定在 LCD 玻璃上( COG工艺)。

2.硬件设计

2.1 连接原理图

硬件连接:

2.2 模块的引脚功能

模块通过 SPI 进行通信,需要的引脚如下图:

2.3 点阵与 DD RAM 地址的对应

**页定义:**PAGE,与平时所讲的“页”并不是一个意思,在此表示 8 个行就是一个“页”,一个 128*32 点阵的屏分为 8 个“页”,从第 0“页”到第 7“页”。

3.软件实现

3.1 模拟SPI时序

//头文件
#ifndef _SPI_H_
#define _SPI_H_#include "nrf51.h"
#include "nrf_gpio.h"#define SPI_CLK       2
#define SPI_CLK_LOW         nrf_gpio_pin_clear(SPI_CLK)
#define SPI_CLK_HIGH        nrf_gpio_pin_set(SPI_CLK)#define SPI_MOSI      1
#define SPI_MOSI_LOW        nrf_gpio_pin_clear(SPI_MOSI )
#define SPI_MOSI_HIGH       nrf_gpio_pin_set(SPI_MOSI)#define SPI_MISO         0
#define SPI_MISO_LOW        nrf_gpio_pin_clear(SPI_MISO )
#define SPI_MISO_HIGH       nrf_gpio_pin_set(SPI_MISO)
#define SPI_MISO_READ       nrf_gpio_pin_read(SPI_MISO)void Spi_Gpio_Init(void);
void Spi_Write_Byte(uint8_t dat);
uint8_t Spi_Read_Byte(void);#endif
//源程序
#include "spi.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include <stdint.h>
#include "lcd128x64.h"//定义SPI四钟方式的0和3
#define _CPOL   0
#define _CPHA   0void Spi_Gpio_Init(void)
{nrf_gpio_cfg_output(SPI_CLK);nrf_gpio_cfg_output(SPI_MOSI);nrf_gpio_cfg_input(SPI_MISO,NRF_GPIO_PIN_NOPULL);
#if _CPOL==0SPI_CLK_LOW;
#elseSPI_CLK_HIGH;
#endif
}//模式0:CPOL=0;CPAH=0
//模拟SPI写数据
#if _CPOL==0&&_CPHA==0
void Spi_Write_Byte(uint8_t dat)
{uint8_t len;for(len=0;len<8;len++){SPI_CLK_LOW;//时钟上升沿采样传输数据//nrf_delay_ms(1);if(dat&0x80)   //发送数据{SPI_MOSI_HIGH;} else{SPI_MOSI_LOW;}SPI_CLK_HIGH;//   nrf_delay_ms(1);dat <<= 1;}
}//模拟SPI读数据
uint8_t Spi_Read_Byte(void)
{uint8_t cnt;uint8_t dat=0;for(cnt=0;cnt<8;cnt++)    {SPI_CLK_LOW;   //下降沿后读取数据nrf_delay_ms(1);dat <<= 1; //最高位已经在数据线上了if(SPI_MISO_READ)  //{dat |= 0x01;}else{dat &= 0xfe;}//dat <<= 1;注:此处最高位被移除了SPI_CLK_HIGH;nrf_delay_ms(1);}return dat;
}
#endif//模式3:CPOL=1;CPAH=1
//模拟SPI写数据
#if _CPOL==1&&_CPHA==1            //MODE  1  1
void Spi_Write_Byte(uint8_t dat)
{uint8_t len;SPI_CLK_HIGH;for(len=0;len<8;len++){SPI_CLK_LOW;//时钟上升沿输出数据//nrf_delay_ms(1);if(dat&0x80)    //发送数据{SPI_MOSI_HIGH;} else{SPI_MOSI_LOW;}SPI_CLK_HIGH;//   nrf_delay_ms(1);dat <<= 1;}
}//模拟SPI读数据
uint8_t Spi_Read_Byte(void)
{uint8_t cnt;uint8_t dat=0;SPI_CLK_LOW;for(cnt=0;cnt<8;cnt++)    {SPI_CLK_LOW;nrf_delay_ms(1);dat <<= 1;if(SPI_MISO_READ) {dat |= 0x01;}else{dat &= 0xfe;}SPI_CLK_HIGH;nrf_delay_ms(1);}SPI_CLK_HIGH;return dat;
}
#endif

模拟SPI的介绍请移步SPI专题(一)——基础知识

3.2 LCD驱动

//头文件
#ifndef __LCD128X64__H__
#define __LCD128X64__H__#include "nrf51.h"
#include "nrf_gpio.h"#define Max_Column 128
#define Max_Row     64
#define SIZE 16#define LCD_CMD  0   //写命令
#define LCD_DATA 1  //写数据#define LED_LIGHT1     28#define LCD_CS         3
#define LCD_CS_LOW          nrf_gpio_pin_clear(LCD_CS)
#define LCD_CS_HIGH         nrf_gpio_pin_set(LCD_CS)#define LCD_RST       4
#define LCD_RST_LOW         nrf_gpio_pin_clear(LCD_RST)
#define LCD_RST_HIGH        nrf_gpio_pin_set(LCD_RST)#define LCD_A0         5
#define LCD_A0_LOW          nrf_gpio_pin_clear(LCD_A0)
#define LCD_A0_HIGH         nrf_gpio_pin_set(LCD_A0)typedef enum
{FONT_5X8 = 1,FONT_8X16,FONT_16X16,FONT_128X64,SHOW_POINT,SHOW_LINE
}Typeface;void GPIO_LCD_Init(void);
void LCD_Write_Byte(uint8_t dat,uint8_t cmd);void LCD_Init(void);
void LCD_Set_Pos(uint8_t page,uint8_t column);
void LCD_Display_Clear(void);void LCD_Draw_Point(uint8_t page,uint8_t column);
void LCD_Draw_Line_Y(uint8_t page,uint8_t column);
void LCD_All_Screen(void);
void Lcd_Display_OneChar(uint8_t page,uint8_t column,uint8_t str);
void Lcd_Display_String(uint8_t page,uint8_t column,uint8_t *str);
uint32_t Lcd_Pow(uint8_t m,uint8_t n);
void Lcd_Display_Num(uint8_t page,uint8_t column,uint32_t num,uint8_t len,uint8_t size_num);void Display_128x64(uint8_t *dp);
void Display_Graphic_5x8(uint8_t page,uint8_t column,uint8_t *dp);
void Display_Graphic_8x16(uint8_t page,uint8_t column,uint8_t *dp);
void Display_Graphic_16x16(uint8_t page,uint8_t column,uint8_t *dp);void DisplayFont(uint8_t page, uint8_t column, uint8_t No, uint8_t typeface);
void display_string_8x16(uint8_t page,uint8_t column,uint8_t *text);void Lcd_Light(void);void OLED_Init(void);void LCD_Draw_Line_X(uint8_t page,uint8_t column);#endif
//源文件,相关GPIO初始化
void GPIO_LCD_Init(void)
{nrf_gpio_cfg_output(LCD_CS);nrf_gpio_cfg_output(LCD_RST);nrf_gpio_cfg_output(LCD_A0);LCD_CS_HIGH;
}

MCU向LCD的写入数据:

//LCD写数据
void LCD_Write_Byte(uint8_t dat,uint8_t cmd)
{// uint8_t len;LCD_CS_LOW;if(cmd)LCD_A0_HIGH;elseLCD_A0_LOW;Spi_Write_Byte(dat);LCD_CS_HIGH;LCD_A0_HIGH;
}
//初始化
void LCD_Init(void)
{LCD_RST_HIGH;nrf_delay_ms(20);LCD_RST_LOW;nrf_delay_ms(20);LCD_RST_HIGH;LCD_Write_Byte(0xe2,LCD_CMD);  //软复位nrf_delay_ms(20);LCD_Write_Byte(0xae,LCD_CMD);//显示关闭LCD_Write_Byte(0x2c,LCD_CMD);// open VB circuitnrf_delay_ms(20);LCD_Write_Byte(0x2e,LCD_CMD);// open VR circuitnrf_delay_ms(20);LCD_Write_Byte(0x2f,LCD_CMD);//voltage follower ON  regulator ON  booster ONnrf_delay_ms(20);LCD_Write_Byte(0x22,LCD_CMD);LCD_Write_Byte(0x81,LCD_CMD);LCD_Write_Byte(0x3f,LCD_CMD);LCD_Write_Byte(0xa2,LCD_CMD);//LCD_Write_Byte(0xa0,LCD_CMD);LCD_Write_Byte(0xc8,LCD_CMD);//com64 --> com1LCD_Write_Byte(0x10,LCD_CMD);//Set Column Address 4 higher bits = 0LCD_Write_Byte(0x00,LCD_CMD);//Set Column Address 4 lower bits = 1 , from IC SEG1 -> SEG128LCD_Write_Byte(0xb0,LCD_CMD);//Set Page Address = 0LCD_Write_Byte(0xa6,LCD_CMD);//Normal Display (not reverse dispplay)LCD_Write_Byte(0xaf,LCD_CMD);//Display ON/*LCD_Write_Byte(0xa0,LCD_CMD);  //列扫描顺序:从左到右LCD_Write_Byte(0xc0,LCD_CMD);  //行扫描顺序:C8:从下到上,c0:从上到下LCD_Write_Byte(0xa2,LCD_CMD);   //设置偏压比1/9LCD_Write_Byte(0x2f,LCD_CMD);    //控制电源LCD_Write_Byte(0x25,LCD_CMD); //粗调对比度LCD_Write_Byte(0x81,LCD_CMD);  //微调对比度,进入微调对比度命令LCD_Write_Byte(0x10,LCD_CMD);  //设置电压的参数RR值LCD_Write_Byte(0x40,LCD_CMD);  //起始行:第一行开始LCD_Write_Byte(0xaf,LCD_CMD);  //开显示*/LCD_Display_Clear();LCD_Set_Pos(0,0);
}
//坐标设置
void LCD_Set_Pos(uint8_t page,uint8_t column)
{LCD_Write_Byte(0xb0 + page,LCD_CMD);  //64行分成8个页LCD_Write_Byte(((column >> 4) & 0x0f) | 0x10,LCD_CMD);  //列地址高四位LCD_Write_Byte((column & 0x0f) | 0x01,LCD_CMD);     //设置列地址的低四位
}
//清屏
/清屏
void LCD_Display_Clear(void)
{uint8_t page,j;for(page=0;page<8;page++){LCD_Write_Byte(0xb0+page,LCD_CMD); //设置显示页地址,即横坐标LCD_Write_Byte(0X00,LCD_CMD);  //列地址的低 4 位LCD_Write_Byte(0X10,LCD_CMD);    //列地址的高 4 位for(j=0;j<128;j++){LCD_Write_Byte(0X00,LCD_DATA);//写入1则显示,写入0则清屏}}
}
//显示相关实现
/*显示128x64点阵图像*/
void Display_128x64(uint8_t *dp)
{uint8_t i,j;for(j=0;j<8;j++){LCD_Set_Pos(j+1,1);for (i=0;i<128;i++){  LCD_Write_Byte(*dp,LCD_DATA);       /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/dp++;}}
}//显示一个点
void LCD_Draw_Point(uint8_t page,uint8_t column)
{LCD_Set_Pos(page, column);LCD_Write_Byte(0x01,LCD_DATA);
}//划线
void LCD_Draw_Line_Y(uint8_t page,uint8_t column)
{uint8_t i,j;for(i=page;i<8;i++){LCD_Write_Byte(0xb0+i,LCD_CMD); //设置显示页地址,即横坐标for(j=0;j<0x08;j++){LCD_Write_Byte(0x00+j,LCD_CMD); //只加其中低或者高,相当于连续显示竖线LCD_Write_Byte(0X10+j,LCD_CMD);    //横纵坐标都同时递增,相当于竖线平移LCD_Write_Byte(0Xff,LCD_DATA);//写入1则显示,写入0则清屏}}
}//可构造斑马线
void LCD_Draw_Line_X(uint8_t page,uint8_t column)
{uint8_t i,j;LCD_Set_Pos(page, column);for(j=0;j<8;j++){LCD_Write_Byte(0xb0+j,LCD_CMD);LCD_Write_Byte(0X00,LCD_CMD); //列地址的低 4 位LCD_Write_Byte(0X10,LCD_CMD);    //列地址的高 4 位for(i=0;i<128;i++){//LCD_Write_Byte(0x0f,LCD_DATA);LCD_Write_Byte(0x01,LCD_DATA);}}
}/显示单独一个字符
void Lcd_Display_OneChar(uint8_t page,uint8_t column,uint8_t str)
{uint8_t i=0,ret=0;//ret = str -32;ret = str - ' ';//得到偏移后的值,对ASCLL码进行一个减法.即在二维数组里找它的位置  if(column>Max_Column-1){column = 0;page = page + 2;//针对16号的字符}if(SIZE == 16 ){LCD_Set_Pos(page,column);//16的字体分成两部分写入for(i=0;i<8;i++){LCD_Write_Byte(F8X16[ret*16+i],LCD_DATA);}LCD_Set_Pos(page+1,column);//页地址增加1for(i=0;i<8;i++){LCD_Write_Byte(F8X16[ret*16+i+8],LCD_DATA);}}else{LCD_Set_Pos(page,column+1);for(i=0;i<6;i++)LCD_Write_Byte(F6x8[ret][i],LCD_DATA);}
}
//字符串显示
void Lcd_Display_String(uint8_t page,uint8_t column,uint8_t *str)
{uint8_t i=0;while(str[i]!='\0'){Lcd_Display_OneChar(page,column,str[i]);column += 8;if(column>120){column = 0;page += 2;}i++;}
}//计算m的n次方
uint32_t Lcd_Pow(uint8_t m,uint8_t n)
{uint32_t ret = 1;while(n--){ret *= m;}return ret;
}//显示数字
//*num:显示的数字
void Lcd_Display_Num(uint8_t page,uint8_t column,uint32_t num,uint8_t len,uint8_t size_num)
{uint8_t t,temp;uint8_t flag = 0;for(t=0;t<len;t++){temp = (num / Lcd_Pow(10,len-t-1)) % 10;//把显示的数字一位一位取出来if(((flag==0) && t) < (len-1)){if(temp == 0){Lcd_Display_OneChar(page,column + (size_num/2) * t,'0');continue;//temp=0时,结束本次循环,进入下次循环,但不跳出循环}else{flag = 1;}}Lcd_Display_OneChar(page,column + (size_num/2) * t,temp + '0');}
}

**注:**程序中涉及的字库可通过取自摸软件得到。

NRF51822——LCD128X64驱动相关推荐

  1. [nRF51822] 1、一个简单的nRF51822驱动的天马4线SPI-1.77寸LCD彩屏DEMO

    最近用nRF51822写了个天马4线SPI的1.77寸LCD彩屏驱动,效果如下: 屏幕的规格资料为:http://pan.baidu.com/s/1gdfkr5L 屏幕的驱动资料为:http://pa ...

  2. NRF51822开发笔记-5.nRF51822裸机实验GPIO输出驱动LED

    NRF51822开发笔记-5.nRF51822裸机实验GPIO输出驱动LED 一.例程分析 1.多个GPIO输出模式配置函数 2.单个GPI0输出模式配置函数 GPIO输出高电平函数 二.程序设计 一 ...

  3. Nordic NRF51822 从零开始系列(外部设备片—MPU6050DMP驱动的移植)

    一.硬件准备 (1)开发板和软件参看  Nordic NRF51822 从零开始系列(一)开发环境的搭建 (2)mpu6050模块 二.前置知识 (1) IIC通信协议    (最好记住,以后会有很大 ...

  4. CC2540、nRF51822应用开发比较

    看了一下nRF51822 SDK里的应用程序开发,跟TI的区别比较大. TI CC2540的开发框架比较完善,从zigbee芯片CC253x起就使用这一套软件框架.到了CC2540,除了射频部分,芯片 ...

  5. Nordic NRF51822 从零开始系列(一)开发环境的搭建

    硬件准备 (1)nrf51822 开发板一块(此处使用的是青云系列的,自带jlijnk ob+usb串口芯片)或者使用nrf51822模块+jlink_ob (左为开发板 右为模块+jlinkob) ...

  6. NRF51822 小黄车智能锁 逆向工程

    笔者在夜跑时发现有人将拆下的小黄车智能锁丢弃在花园角落,于是萌生了拆解的想法. 拆开外壳后发现MCU 是NRF51822 ,并且预留了Jlink 调试接口,更萌生了逆向这个电路板的想法 下面是 各个智 ...

  7. nRF51822 TWI学习

    由于nRF51822与模块之间通过IIC总线通信,在解决问题的时候学习了TWI,现在将其总结一下. TWI(Two-wire interface),即两线通信接口,也就是我们平时常说的IIC接口. I ...

  8. nrf51822 另外一个板子

    overheat 2013年12月9日20:30到12月11日21:30,过期或售完自动下架. 对应的手册为<nRF51822上手指南.pdf> 描述: CPU:nRF51822 传感器: ...

  9. nRF51822:在 macOS 下使用 SEGGER Embedded Studio(SES)搭建开发环境

    系统环境 系统:macOS 10.13.6(Windows 和 Linux 同样适用) 网络:联网 软件环境(只能保证这个版本环境好用) 编译器环境:SEGGER Embedded Studio v3 ...

最新文章

  1. shell 中柏开机显示efi_中柏 ezpad 平板安装Fedora 21 (Linux)
  2. Javascript模块化编程(三):require.js的用法
  3. keras构建卷积神经网络(CNN(Convolutional Neural Networks))进行图像分类模型构建和学习
  4. Titanium开发环境搭建第一个坑
  5. 成功解决TypeError: object of type ‘int‘ has no len()
  6. Vue学习(组件传参)-学习笔记
  7. 计算机计算能力共享,服务器计算能力计算器
  8. 《朝花夕拾》金句摘抄(四)
  9. 什么是以太网光纤收发器,其产品特点和技术参数都有哪些?
  10. 自然语言处理实践Task6
  11. Became Jane(成为简.奥斯丁)
  12. SQL Server 2008入门系列之设置数据库服务器的访问权限
  13. [OS] 进程相关知识点
  14. Messenger Group Redesign - 缓解群组社交压力设计思考
  15. 细说ip地址与同一网段
  16. 服务器固件测试--PCI设备的介绍(集成网卡和外插网卡)
  17. UA MATH563 概率论的数学基础1 概率空间4 实数域上的概率测度
  18. GBase xdm价值
  19. 中国农大博士计算机专业考试大纲,中国农业大学考博经验
  20. 上海纽约大学计算机专业怎样,上海纽约大学王牌专业有哪些

热门文章

  1. DV-Hop算法原理
  2. 步态剪影_如何拍摄好剪影照片
  3. socks5进程代理模拟器单窗口单IP软件分享及使用教程
  4. 所谓的内存释放工具——原理
  5. spring中的事件监听机制
  6. 《阿猫阿狗2》和《芝麻开门》的相似之处
  7. linux中 ex是什么命令,Linux ex命令
  8. python软件测试书籍推荐_自学软件测试看什么书入门比较好呢?
  9. 港科夜闻|香港科大本科生科研计划奖(UROP)颁奖典礼于线上成功举办
  10. React Native 开源项目汇总