历史上的今天
返回首页

历史上的今天

今天是:2024年11月28日(星期四)

正在发生

2020年11月28日 | 基于stm32的 ucGUI 12864下的移植

2020-11-28 来源:eefocus

ucGUI是纯C写的的,移植需要定义点阵数,颜色数,和画点函数

以下是ucGUI 12864下的移植

基于ST7920控制的12864液晶用于字符显示很方便的,但网友说用它显示图形并不合适,原因就是它绘图时先要关闭显示,绘完后又要打开,速度会较慢。我没有用过别的液晶,手中只有这一款,摆弄了几天,掌握了一点东西,写出来共享。  
首先,我们知道,图形都是由像素点组成的,绘图的基础其实就是画点。只要我们能点亮液晶的任意一个像素点,那么绘图就不是什么难事了。万丈高楼平地起嘛,先要做的,当然是要打好基础。  
ST7920提供了用于绘图的GDRAM(graph display RAM)。共 64×32,64是 个字节的空间(由扩充指令设定绘图 RAM 地址),64是行数,32是每行对应的字节数(16bit/2 *16),最多可以控制 256列×64行点阵的二维绘图缓冲空间。在它的Datasheet给出了GDRAM的坐标地址对照表:

wpsB1D4.tmp


(这个就是坐标图,有的分上下两个平屏0-31和32-64) 
用坐标表示,就是这样:

wpsB1D5.tmp 
它的横坐标(列)每一个地址都是16位bit的。共16x16横坐标(列),256位。每次读写操作是16Bit。 
很明显,ST7920能控制256*64像素的液晶屏,而我们的只是128*64像素液晶屏,显然只用到它的一部分。  
市面上的12864液晶屏的点阵布局是这样的:分上半屏128x32 + 下半屏128x32,

wpsB1E5.tmp

只要我们清楚了它的GDRAM和屏幕上像素点的映射(对应)关系,点亮对应的像素点就容易多了。

要点亮某一个像素点,就是将这个像素点在GDRAM中对应的位置1,这个相信没人会不知道吧?  
我们先讨论一下思路,再一步步写代码。我觉得,思路要比代码重要的多,只要你的思路通了,正确了,那么写出代码肯定会很容易。

首先,给你x,y的坐标,要你点亮一个点,要怎么做呢?从上面的图我们知道,它是分为两个半屏的,首先,我们要确定这个点是在上半屏还是下半屏,然后确定它是在那一行(纵坐标Y),再确定它是在哪一个字节的哪一个位(也就是确定它在那一列,即横坐标X)。这些都确定后我们就定位到某一个具体的位上了,只就将这个位置1,就OK了。

 

在知道了12864点对应的坐标布局后,还需要知道怎么网12864 内部写这些命令和数据:它们分别是读、写命令、写数据、读忙状态,这个可以参考手册

 

需要强调的是打点流程是这样的:

打开绘图模式

1.  先将垂直的字节坐标(Y)写入绘图 RAM 地址。 
     2.  再将的水平坐标(X)写入绘图 RAM 地址。 
     3.  将 D15〜D8 写入到 RAM ㆗(写入第㆒个 Bytes)。 
     4.  将 D7〜D0 写入到 RAM ㆗(写入第㆓个 Bytes)。 绘图显示的内存对应分布请参考

需要发送4个字节

 

ucgui 在12864下的移植:

#ifndef __LCD12864_H

#define __LCD12864_H



#include "LCDConf.h"   

#include

#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "stm32f10x_gpio.h"

#include "stm32GpioBit.h"




#define LCD_DELAY  10000


#define LCD_RCC  RCC_APB2Periph_GPIOD


#define LCD_PORT GPIOD


#define LCD_DATA_PIN  GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7


//RST

#define LCD_RST_PIN    GPIO_Pin_12  

#define LCD_RST_PORT   GPIOC

#define LCD_RST_RCC    RCC_APB2Periph_GPIOC


//PSB

#define LCD_PSB_PIN    GPIO_Pin_9

#define LCD_PSB_PORT   GPIOA

#define LCD_PSB_RCC    RCC_APB2Periph_GPIOA


//EN

#define LCD_EN_PIN     GPIO_Pin_10

#define LCD_EN_PORT    GPIOA

#define LCD_EN_RCC     RCC_APB2Periph_GPIOA


//RW

#define LCD_RW_PIN     GPIO_Pin_11

#define LCD_RW_PORT    GPIOC

#define LCD_RW_RCC     RCC_APB2Periph_GPIOC


//RS

#define LCD_RS_PIN     GPIO_Pin_10

#define LCD_RS_PORT    GPIOC

#define LCD_RS_RCC     RCC_APB2Periph_GPIOC



/*DB7 busy信号位控制   //PD7 CRH的最高4bit为控制位,=0x33... out   =0x44...in */

#define LCM_BUSY_PIN_IN()    LCD_PORT->CRL = (LCD_PORT->CRL & 0x0fffffff)|0x40000000

#define LCM_BUSY_PIN_OUT()   LCD_PORT->CRL = (LCD_PORT->CRL & 0x0fffffff)|0x30000000



#define SetLcdRS             LCD_RS_PORT->BSRR  =  LCD_RS_PIN

#define ResetLcdRS           LCD_RS_PORT->BRR  =  LCD_RS_PIN

                             

#define SetLcdRW               LCD_RW_PORT->BSRR = LCD_RW_PIN

#define ResetLcdRW           LCD_RW_PORT->BRR  =  LCD_RW_PIN

                                               

#define SetLcdEN               LCD_EN_PORT->BSRR = LCD_EN_PIN

#define ResetLcdEN           LCD_EN_PORT->BRR  = LCD_EN_PIN

                             

#define SetLcdRST               LCD_RST_PORT->BSRR = LCD_RST_PIN

#define ResetLcdRST          LCD_RST_PORT->BRR  = LCD_RST_PIN

                                                 

#define SetLcdPSB               LCD_PSB_PORT->BSRR = LCD_PSB_PIN

#define ResetLcdPSB          LCD_PSB_PORT->BRR  = LCD_PSB_PIN



#define LCM_WAIT_FOR_BUSY()  do{                               

                                 LCM_BUSY_PIN_IN();               

                                                         ResetLcdRS;                     

                                                         SetLcdRW;                       

                               while(LCD_PORT->IDR & 0x0080)   

                                                               __nop();                       

                                 LCM_BUSY_PIN_OUT();             

                                                     }while(0)                      

                            


void _SetPixel(uint32_t x, uint32_t y,  uint8_t color);

void GUI_Line(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint8_t color);

uint32_t LCD_GetPoint(uint32_t x, uint32_t y);

void LCM_Init( void );  

                                                         

                                                         

#endif


/******************************************************************************    

  模块名称:st7920 串行方式驱动12864液晶驱动  

  

  串行硬件(IO模拟SPI)连接方式:

  

   1   GND   GND    

   2   VCC   3V3

   3   VO    NC

   4   RS    CS     PD7

   5   RW    SDI    PD6

   6   E     SCK    PD5

   7   D0    NC

   8   D1    NC

   9   D2    NC

   10  D3    NC

   11  D4    NC

   12  D5    NC

   13  D6    NC

   14  D7    NC

   15  PSB   L

   16  NC    NC

   17  RST   NC    如果IO足够应该用软件复位

   18  VOUT  NC

   19  LEDA  3V3

   20  LEDK  GND

   

     worldsing.cnblogs.com

******************************************************************************/    

#include "lcd12864.h"

#include "LCD_Private.h"      /* private modul definitions & config */

#include "GUI_Private.h"

#include



//STM32硬件移植修改

#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "stm32f10x_gpio.h"

#include "stm32GpioBit.h"


#include



//EN - SCK

#define  SCK_PORT       D

#define  SCK_BIT        5


//RW - SID

#define  SID_PORT       D

#define  SID_BIT        6


//RS - CS

#define  CS_PORT        D

#define  CS_BIT         7


#define  NOP()          __nop()



#define  GetSID()      GET_GPIO_BIT(SID_PORT, SID_BIT)            //<- SID (RW)

#define  CS(value)     OUT_GPIO_BIT(CS_PORT,  CS_BIT, value)      //-> CS  (RS)

#define  SID(value)    OUT_GPIO_BIT(SID_PORT, SID_BIT, value)     //-> SID (RW)

#define  SCK(value)    OUT_GPIO_BIT(SCK_PORT, SCK_BIT, value)     //-> SCK (E )



/* 定义LCM操作的命令字 */

#define LCM_BE_DISABLE 0X30   /*基本指令模式*/

#define LCM_BE_ENABLE  0x34   /* 扩充指令集模式*/

#define LCM_BEG_ENABLE 0x36      /*扩充指令集模式且绘图显示*/

#define LCM_STARTROW   0x02   /* 显示起始行0,可以用LCM_STARTROW+x设置起始行。(x<64) */

#define LCM_ADDRSTRX   0x80   /* 页起始地址,可以用LCM_ADDRSTRX+x设置当前页(即X)。(x<15) */

#define LCM_ADDRSTRY   0x80   /* 列起始地址,可以用LCM_ADDRSTRY+y设置当前列(即Y)。(x<64) */

推荐阅读

史海拾趣

Delphi Connection Systems公司的发展小趣事

Delphi Connection Systems公司自创立之初,就致力于在电子行业中的连接器技术上进行创新。公司投入大量研发资源,开发出一种新型的高性能连接器,这种连接器具有更小的体积、更高的可靠性和更低的传输损耗。这一创新成果迅速获得了市场的认可,为公司带来了大量的订单和合作机会。

恒连电子(EVERCOM)公司的发展小趣事

恒连电子成立于XX年代初,当时正值电子行业的快速发展期。创始人张先生凭借对电子技术的敏锐洞察力和对市场趋势的精准把握,决定投身于电子行业。然而,初创时期的公司面临着资金短缺、技术团队匮乏以及市场竞争激烈等多重挑战。张先生带领团队日夜兼程,通过自主研发和不断创新,逐渐在市场中站稳脚跟。他们首先推出了几款性能稳定、价格合理的电子产品,赢得了客户的信赖。随着产品的逐步推广,恒连电子逐渐在市场中打开了局面。

芯佰微(Corebai)公司的发展小趣事

作为一家有社会责任感的企业,芯佰微始终关注环境保护和可持续发展。公司积极推广绿色生产技术和资源循环利用方案,减少生产过程中的能源消耗和废弃物排放。同时,芯佰微也积极参与社会公益活动,为社区和环境贡献自己的力量。这些举措不仅体现了公司的社会责任担当,也为其赢得了更多客户和合作伙伴的信任和支持。

Edcon Components Netherlands Cv公司的发展小趣事

随着全球环保意识的提高,Edcon Components Netherlands Cv积极响应绿色生产的号召。公司采用环保材料和工艺进行生产,减少废弃物排放和能源消耗。同时,公司还加强了员工的环保意识培训,鼓励员工积极参与环保活动。这些举措不仅有助于提升企业的社会责任感,也为公司的可持续发展奠定了坚实基础。

CALMIRCO公司的发展小趣事

CALMIRCO公司注重企业文化的塑造,倡导“创新、协作、务实、进取”的企业精神。公司通过定期举办员工培训、团队建设等活动,提升员工的职业素养和团队协作能力。同时,CALMIRCO公司还建立了完善的激励机制,鼓励员工积极创新、勇于担当。这些举措使得CALMIRCO公司的团队凝聚力不断增强,为公司的持续发展提供了有力保障。

Hasco Relays and Electronics International Corp公司的发展小趣事

Harris公司最初成立于1890年代,起初以无线电通信技术为核心业务。在早期,公司凭借其创新的无线电通信技术,在通信领域迅速崭露头角。这一时期,Harris不仅为军事领域提供了关键的通信解决方案,还逐步拓展到商业和民用市场,为当时的电话、电报等通信方式带来了革命性的变化。通过不断的技术研发和产品创新,Harris逐渐奠定了其在电子行业的重要地位。

问答坊 | AI 解惑

PC式硬盘录像机死机全接触(一)

PC式硬盘录像机死机全接触 在使用PC式的硬盘录像机的过程中,难免会遇到许多诸如死机等突发故障,对于平时工作正常的较新机子而言,其中大多数死机都是软件停止了响应造成的,只要强制关闭了这些停止响应的软件,电脑即可恢复正常工作,方法是先按 ...…

查看全部问答>

求助,在5502中SDRAM的写入过程要用210ns,如何提升速度

在TMS320VC5502中,对SDRAM写操作,居然要210ns,简直无法干活,请教前辈,怎样解决这个问题?我对EMIF的相关寄存器进行设置,如WRITE SETUP 、WRITE STROBE 、WRITE HOLD ,对写操作消耗时间一点都没变化,很郁闷呀,在论坛上有说这是5502本身问题 ...…

查看全部问答>

关于磁珠、磁环的选用

磁珠  磁珠专用于抑制信号线、电源线上的高频噪声和尖峰干扰,还具有吸收静电脉冲的能力。磁珠是用来吸 收超高频信号,像一些RF电路,PLL,振荡电路,含超高频存储器电路(DDR SDRAM,RAMBUS等)都需要在电源输入部分加磁珠,而电感是一种蓄能元 ...…

查看全部问答>

指尖“控制”生活的数字家居

几年前,智能化的生活在大多数人看来是一种遥不可及的梦幻,近年来随着相关产业和技术的成熟,经过大量厂家和房地产开发商的宣传推广,越来越多的住宅小区开始配套相对完善的智能家居系统,人们智能化生活的梦想慢慢变成了现实。在南京,已经有数十 ...…

查看全部问答>

WinCE6.0 系统定制及应用开发 问题

在定制WinCE操作系统的时候,我想添加对C#的支持。可是选项中有 .NET Compact Framework 2.0  跟  .NET Compact Framework 2.0-headless两个选择项目。 请问各位大侠,两个有什么不同呢? 还有就是我刚开始添加的是前者,编 ...…

查看全部问答>

射极跟随器问题

本帖最后由 paulhyde 于 2014-9-15 09:04 编辑 我想用三极管打一个射极跟随器  应该选取什么型号三极管 …

查看全部问答>

关于port1 中断

对于不同的pin中断该如何区分呢?有没有类似P1IV这样的register ?谢谢…

查看全部问答>

看门狗定时时间到,怎么跳不出循环

#include void main(void) { WDTCTL=WDT_ADLY_1000;//设置看门狗定时时间1000ms IE1|=WDTIE;         //WDT使能 P5DIR|=0x02;        //P5.1输出 P5OUT=0X02; _EINT();//中断 ...…

查看全部问答>