数码之家

 找回密码
 立即注册
搜索
查看: 2503|回复: 20

[C51] 点屏再战记,成功用STC15W4K56S4点亮广发银行蓝牙key盾12864屏

[复制链接]
发表于 2023-7-26 10:22:14 来自手机浏览器 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
书接上回,废话继续,有道是失败是孩子他妈,自打上次以来,收获良多,虽然还是有些模棱两可,但起码好一点了,随着深入学习的推进,记个心得体会,要求不少于800字,嘿嘿,有没有很熟悉的感觉,领导教育我们要入脑入心入魂,做到始终坚持4个意识2个确立,确立目标,确立方向,而现如今我意识到了短处,技术,学术,艺术,我的目标就是把这屏点亮起来,方向就是学着打个板,做个usb电压电流表,时间表之类的,它又说了4个自信,咱要求的不多,一个就够了。
飞机直达,第一次失败现场
记一次失败的尝试,用STC15W4K56S4点亮农行金e顺通用K宝12864屏(排线丝印FM1420901CT06-00-B)
话不多说还是开搞硬件,还是那一堆u盾,这回又是哪个着殃,就你了,南极老寿星,元始广发天尊,对不?是不是那个大脑门托个桃的,平日里老人家过寿请出来的那位?
3下5/2,立马分离
IMG_20230726_003425.jpg
屏幕排线序号H-003744,再无其他信息
Collage_20230726_003546.jpg
按照坛友经验方法,查找和其他芯片连接情况,可以确定出SCLK和SDA,电源,背光引脚了,虽然这主控有2个时钟脚,但这里先按坛友们分享的与25Q16第5脚为SLCK再说,经验之谈一般得听。
IMG_20230724_190234.jpg
没咋专业仪器,但还是测下,1,2,3脚的开…关…待机下的电压
IMG_20230724_190903.jpg
看看,3脚开关机都是有一个明显3.3V再降为0的过程,时间间隔在1秒内,反正比较明显。2脚开机直接3.3v比较稳定,关机电压下降比较缓慢,怀疑连线上接有容阻延迟。1脚开机有3.3v,关机很快降为0。话说是不是指针表是不是更直观?数字表AD转换应该也是可以接受。
再根据这以下两位分享帖子中的引脚排位,结合上面第3脚的电压变化直接就排除掉RST,基本先确定出第2脚为RST,3脚为A0,1脚CS这里测得高电平,有点不合时序,可能记错了。不行就按坛友说的,排列组合123脚,软件编程也只需改6次就确定了。
驱动U盾LCD屏---代码初步解析
农行U盾液晶屏再利用DIY(附代码) IMG_20230724_192924.jpg
接下来还是继续开搞软件,这回没那么莽了,先好好研究驱动再说,按照网上的总结,12864的驱动大体分为4类,如下图。
Screenshot_20230720_080238.jpg
每种驱动的时序,指令也会不同,差比很大,比如这种分高低4传的。
Screenshot_20230724_222948.jpg
那么再按照新老站坛友分享的来讲,还是大概率是ST7565驱动的多,那么接下来再细看下ST7565的数据手册串行连接这页的介绍。
ST7565S.PDF (719.27 KB, 下载次数: 0)
Screenshot_20230724_211130.jpg
①当选择了串行接口(P/S=“L”)时,当芯片处于激活状态(/CS1=“L”和CS2=“H”)时可以接收串行数据输入(SI)和串行时钟输入(SCL)。串行数据按顺序在串行时钟D7、D6到D0的上升沿中从串行数据输入引脚读取。该数据在第八串行时钟的上升沿被转换为8位并行数据以进行处理。→→→(此屏无并行引脚,无需理会P/S选择,按坛友说的CS,低电平使能,也只需看CS1的时序便可,也就是时序图中第2条无需理会,CS头顶个杠的,数电基础中的非,取反,真真假假,假假真真,就问你是真还是假?也说明低电平片选使能。)
②A0输入用于确定串行数据输入是显示数据还是命令数据;当A0=“H”时,数据为显示数据,当A0=”L”时,则数据为命令数据。在芯片变为有效之后,A0输入被读取并用于串行时钟的每8个上升沿的检测。图1是串行接口信号图。
③在串行接口模式下无法读取。(只能mcu往lcd写,单向,无并行也无需判断驱动忙碌位)
不急不急,接下来了解下驱动相关存猪器基本概念先。以下为一款有字库的12864的介绍,简单来讲就好比如火车站的寄存箱之类的,你要显示什么,我这里有的你只管一指我就给你显示什么,这就行了,复杂来讲,就是我也不懂什么讲,但是我就是知道用。
Screenshot_20230725_094908.jpg
ST7565的好像一个display data ram, 通俗来讲应该就是所谓的显存了,也是往这里面写什么,就显示什么。
Screenshot_20230725_095417.jpg
也算差不多了,什么页,列地址之类,看前面帖子坛友分享的够我用了,特别注意下就是列地址是要先高4位后低4位,跟把大象放进冰箱一样色的。
再来看控制指令表,数据手册这里有写到,复位后直接回默认的值,有些我们用不上的没必要去搞它了,比如什么电阻比还是咋之类那些,手册里似乎挺复杂,不是咋能说的通的。
Collage_20230725_112826.jpg
其他的可参考手册或下图,不废话了。
1d08c2a24b544b0ea808ca2a6c37a00c.png
亦或者,直接参考这贴程序里面的介绍,还是很细腻的,大婶似乎喜欢留个小八哥,嘿嘿
教大家如何点亮建行网银盾的液晶屏2.0(以代码为主)
别人的始终还是别人的,腿再长,脸太美,牵不到手的总是在跳动,程序还是自己理解了自己码,也没多少条,远记得,干啥啥不行,抄作业第一名。(小吐槽一下STC—ISP,你家软件延迟自动生成咋没有个生成个带参数的,印象中我记得有那么一个小工具的呀。)按引脚需求软硬连接上,继续开搞。
IMG_20230726_003821.jpg
这回脚位宽点,好焊多了。
IMG_20230725_172358.jpg
编译,下载,排错,一气呵成,前前后后改了10多次,对比度,和指令修改,对比度取值不当容易进坑里了,以为没点亮,经验之说就是最大最小中间来一遍,看变化再来修改合适值,就问亮了没有??亮了。
IMG_20230726_092813.jpg
又问成了没有??有8分成了,剩下有2成,留着点下个屏时再来折腾显示汉字,数字,字母,取模建立ASCII码字库,图片等。背光加上,顺手串个电阻太亮,换一个又不够亮,不扯腾了。
Collage_20230726_092932.jpg
鼠鼠,是我鸭!^m^ ……^﹏^都看到这里了,赏点M吧,入不敷出了,就这样,谢谢观看。
===================我是分割线=============
===================代码====================
  1. /*================================*/
  2. /*          点屏测试                                */
  3. /*      2023.7.25   V1.8                      */
  4. /*        目前状态 :                            */
  5. /*操作成功 !(2023-07-25 22:41:17)*/
  6. /*==============================*/

  7. #include <STC15.H> //头文件,直接STC-ISP添加到keil
  8. #include "intrins.h" //库函数,以便调用空函数延时用

  9. typedef unsigned int uint;//宏定义
  10. typedef unsigned char uchar;

  11. sbit CS   = P0^0; //片选使能脚
  12. sbit RST  = P0^1; //复位脚
  13. sbit A0   = P0^2; //数据或指令选择脚,也有叫RS
  14. sbit SCLK = P0^3; //时钟脚
  15. sbit SDA  = P0^4; //数据脚,也有叫SI,DO

  16. /*延时函数,直接从stc-isp里自动生成*/
  17. void Delay1000ms()  //@11.0592MHz
  18. {
  19.         uchar data i, j, k;
  20.   _nop_();
  21.         _nop_();
  22.         i=43;
  23.         j=6;
  24.         k=203;
  25.         do
  26.         {
  27.                 do
  28.                 {
  29.                         while (--k);
  30.                 } while (--j);
  31.         } while (--i);
  32. }

  33. void Delay5ms()  //@11.0592MHz
  34. {
  35.         uchar data i, j;
  36.         i=54;
  37.         j=199;
  38.         do
  39.         {
  40.                 while (--j);
  41.         } while (--i);
  42. }

  43. void Delay200ms()  //@11.0592MHz
  44. {
  45.         uchar data i, j, k;
  46.         _nop_();
  47.         _nop_();
  48.         i=9;
  49.         j=104;
  50.         k=139;
  51.         do
  52.         {
  53.                 do
  54.                 {
  55.                         while (--k);
  56.                 } while (--j);
  57.         } while (--i);
  58. }

  59. /*写指令到LCD12864函数*/
  60. /*参数cmd:命令字节    */
  61. void LcdWriteCommand(uchar cmd)
  62. {  
  63.     uchar i;
  64.     CS=0; //片选脚使能
  65.     SCLK=0; //时钟准备
  66.     A0=0; //低电平传的是指令
  67.     for(i=0;i<8;i++) //串行按位传送
  68.       {
  69.         if(cmd&0x80) //取出最高位,高位在先
  70.           {
  71.             SDA=1;
  72.           }
  73.         else
  74.           {  
  75.             SDA=0;
  76.           }
  77.       
  78.         SCLK=1; //时钟上升沿,写入一位
  79.         SCLK=0; //时钟再准备传下一位
  80.         cmd=cmd<<1; //左移1位,下一位放到最高位
  81.       }
  82.     CS=1; //传完,使能停止
  83.     SCLK=0; //时钟关,或者说再准备
  84. }

  85. /*写数据到LCD12864函数*/
  86. /*参数byte:数据字节   */
  87. void LcdWriteData(uchar byte)
  88. {
  89.     uchar i;
  90.     CS=0; //同上
  91.     SCLK=0;
  92.     A0=1; //写入的是数据
  93.     for(i=0;i<8;i++)
  94.       {
  95.         if(byte&0x80)
  96.           {
  97.             SDA=1;
  98.           }
  99.         else
  100.           {
  101.             SDA=0;
  102.           }
  103.       
  104.         SCLK=1;
  105.         SCLK = 0;
  106.         byte=byte<<1;
  107.       }
  108.     CS=1;
  109.     SCLK=0;
  110. }

  111. /*LCD12864初始化函数*/
  112. void LcdInit()
  113. {
  114.     RST=1;        
  115.     Delay5ms();
  116.     RST=0;        
  117.     Delay5ms();
  118.     RST=1;//复位脚,高电平复位
  119.     Delay200ms();  
  120.     LcdWriteCommand(0xE2); //软复位
  121.     LcdWriteCommand(0x23); //电阻比,对比度粗调
  122.     LcdWriteCommand(0x81); //对比度精调,双指令,必须跟下面一条连着
  123.     LcdWriteCommand(0x2D); //对比度精调取值,双指令,必须跟上面一条后面,此参数根据屏幕不同设置不同
  124.     LcdWriteCommand(0x2F); //电源升压设置,(Ox2E)
  125.     LcdWriteCommand(0xAF); //显示
  126.     Delay5ms();
  127.     Delay5ms();
  128. }

  129. /*    清屏函数        */
  130. /*每个点填入0,所有点熄灭*/
  131. /*
  132. void LcdClear()
  133. {
  134.     uchar page,column;
  135.     for(page=0;page<8;page++) //按页写入
  136.      {
  137.         LcdWriteCommand(0xB0+page); //设置页地址,从第0页开始
  138.         LcdWriteCommand(0x10); //设置列地址高4位,
  139.         LcdWriteCommand(0x00); //设置列地址低4位,列地址自动会+1,高低加起来0x10,从第0列开始
  140.         for(column=0;column<128;column++)
  141.           {
  142.              LcdWriteData(0x00);//写入数据0,熄灭所有点
  143.           }
  144.      }
  145. }
  146. */

  147. /*  显示测试函数    */
  148. void LcdTest(uchar ph,uchar pl)
  149. {
  150.     uchar page,column;
  151.     for(page=0;page<8;page++)
  152.       {
  153.          LcdWriteCommand(0xB0+page);//参考上面清屏函数
  154.          LcdWriteCommand(0x10);
  155.          LcdWriteCommand(0x00);
  156.          for (column=0;column<64;column++)
  157.           {
  158.              LcdWriteData(ph);
  159.              LcdWriteData(pl);  //连续写入2个字节数据,128/2=64,循环64次
  160.           }
  161.       }
  162.       
  163. }

  164. /*主函数*/
  165. void main()
  166. {
  167.     LcdInit();
  168.     while(1)
  169.      {
  170.         LcdTest(0x00,0x00);  //清屏,全屏熄灭测试,也可以用清屏函数
  171.         Delay1000ms();
  172.         LcdTest(0xFF,0x00);  //测试竖线
  173.         Delay1000ms();
  174.         LcdTest(0x00,0x00);  
  175.         Delay1000ms();
  176.         LcdTest(0x00,0xFF);  //换列测试
  177.         Delay1000ms();
  178.         LcdTest(0x00,0x00);  
  179.         Delay1000ms();
  180.         LcdTest(0x55,0x55);  //测试横线
  181.         Delay1000ms();
  182.         LcdTest(0x00,0x00);  
  183.         Delay1000ms();
  184.         LcdTest(0xAA,0xAA);  //换行测试
  185.         Delay1000ms();
  186.         LcdTest(0x00,0x00);  
  187.         Delay1000ms();
  188.         LcdTest(0xFF,0xFF);  //全屏点亮测试
  189.         Delay1000ms();
  190.       }
  191. }
复制代码

打赏

参与人数 8家元 +217 收起 理由
nokia5320 + 30
亲爱的混蛋 + 30
kkdkj + 30 謝謝分享
cushion + 30 原創內容
IlovePLC + 30 優秀文章
t3486784401 + 30 優秀文章
作死的家伙 + 7 謝謝分享
jf201006 + 30 優秀文章

查看全部打赏

发表于 2023-7-26 11:30:00 | 显示全部楼层
厉害,论坛里果然大神多。
回复 支持 反对

使用道具 举报

发表于 2023-7-26 13:23:24 来自手机浏览器 | 显示全部楼层
都是技术专家啊
回复 支持 反对

使用道具 举报

发表于 2023-7-26 15:07:13 | 显示全部楼层
果然厉害,但我更喜欢用那二十几的逻辑分析仪
回复 支持 反对

使用道具 举报

发表于 2023-7-26 15:25:47 | 显示全部楼层
学会了,
LCD写命令();
LCD写数据();
OK了,可以了
回复 支持 反对

使用道具 举报

发表于 2023-7-26 15:42:48 | 显示全部楼层
STC芯片不是有硬件SPI吗?用硬件SPI驱动,CPU就没那么忙了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-26 17:19:53 来自手机浏览器 | 显示全部楼层
mmxx2015 发表于 2023-7-26 15:42
STC芯片不是有硬件SPI吗?用硬件SPI驱动,CPU就没那么忙了。

恩,我先研究研究,下次先吧,慢慢来,这涉及到的寄存器有点多,总不能一步向青天…
回复 支持 反对

使用道具 举报

发表于 2023-7-27 01:39:27 | 显示全部楼层
兔包公 发表于 2023-7-26 17:19
恩,我先研究研究,下次先吧,慢慢来,这涉及到的寄存器有点多,总不能一步向青天… ...

楼主研究好硬件SPI后,能否把经验分享给我一下,我也在学习
回复 支持 反对

使用道具 举报

发表于 2023-7-27 08:26:12 | 显示全部楼层
技术牛人,专家级分析。
回复 支持 反对

使用道具 举报

发表于 2023-7-27 08:39:36 | 显示全部楼层
厉害!论坛有力更精彩
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2023-7-27 08:51:17 | 显示全部楼层
STC32G8K64-35I-TSSOP20(含税2.5),带CAN, Lin,DMA支持(TFT彩屏接口,串口,SPI,ADC,I2C),支持SWD仿真,64K的FLASH,8K的SRAM。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-27 08:52:09 来自手机浏览器 | 显示全部楼层
IlovePLC 发表于 2023-7-27 01:39
楼主研究好硬件SPI后,能否把经验分享给我一下,我也在学习

我认为为大婶@jf201006分享的已经够透彻的了 学习一下常用的串行通信协议(UART/IIC/SPI)
回复 支持 反对

使用道具 举报

发表于 2023-7-27 09:20:34 | 显示全部楼层
表示看不懂,但是很钦佩
回复 支持 反对

使用道具 举报

发表于 2023-7-27 09:41:54 | 显示全部楼层
这技术帖写的太棒了,诙谐幽默,真是有趣的灵魂万里挑一啊
回复 支持 反对

使用道具 举报

发表于 2023-7-27 15:40:25 | 显示全部楼层
IlovePLC 发表于 2023-7-27 01:39
楼主研究好硬件SPI后,能否把经验分享给我一下,我也在学习

硬件SPI挺简单的。
在main()函数里设置一下引脚,然后把代码里的引脚改一下就行了
    P_SW2 |= 0x80; // 使能访问XFR
    // P_SW1 = 0x00;  //0000:SS-P1.2orP5.4, MOSI-P1.3, MISO-P1.4, SCLK-P1.5 SPI功能脚切换
    // P_SW1 = 0x04;  //0100:SS-P2.2, MOSI-P2.3, MISO-P2.4, SCLK-P2.5 SPI功能脚切换
    // P_SW1 = 0x08;  //1000:SS-P5.4, MOSI-P4.0, MISO-P4.1, SCLK-P4.3 SPI功能脚切换
    P_SW1 = 0x0c; // 1100:SS-P3.5, MOSI-P3.4, MISO-P3.3, SCLK-P3.2 SPI功能脚切换
    SPI_init();   // 初始化硬件SPI

  1. /********************引脚定义区********************/
  2. sbit    LCD_CS =  P3 ^ 7; //片选                   CS
  3. sbit    LCD_RST = P3 ^ 6; //复位                   RST
  4. sbit    LCD_RS =  P3 ^ 5; //数据指令           A0/DC
  5. sbit    LCD_CLK = P3 ^ 2; //串行时钟           SCL
  6. sbit    LCD_DAT = P3 ^ 4; //串行数据           SDA
  7. //   7       6       5       4       3       2       1       0            Reset Value
  8. //        SSIG        SPEN        DORD        MSTR        CPOL        CPHA        SPR1        SPR0                0x00
  9. #define        SSIG                1        //1: 忽略SS脚,由MSTR位决定主机还是从机                0: SS脚用于决定主从机。
  10. #define        SPEN                1        //1: 允许SPI,                                                                0:禁止SPI,所有SPI管脚均为普通IO
  11. #define        DORD                0        //1:LSB先发,                                                                0:MSB先发
  12. #define        MSTR                1        //1:设为主机                                                                0:设为从机
  13. #define        CPOL                1        //1: 空闲时SCLK为高电平,                                        0:空闲时SCLK为低电平
  14. #define        CPHA                1        //
  15. #define        SPR1                0        //SPR1,SPR0   00: fosc/4,     01: fosc/8
  16. #define        SPR0                0        //            10: fosc/16,    11: fosc/32 or fosc/2(快速SPI模式时)
  17. #define        SPEED_4                0        // fosc/4
  18. #define        SPEED_16        1        // fosc/8
  19. #define        SPEED_64        2        // fosc/16
  20. #define        SPEED_2         3        // fosc/32 or fosc/2(快速SPI模式时)
  21. //#define        SPEED_128        3        // fosc/32

  22. //sfr SPSTAT  = 0xCD;        //SPI状态寄存器
  23. //   7       6      5   4   3   2   1   0            Reset Value
  24. //        SPIF        WCOL        -        -        -        -        -        -
  25. #define        SPIF        0x80                //SPI传输完成标志。写入1清0。
  26. #define        WCOL        0x40                //SPI写冲突标志。写入1清0。
  27. /*********************************
  28. 函数名称:SPI_init
  29. 功能:SPI初始化
  30. 输入:无
  31. 输出:无
  32. 备注:无
  33. *********************************/
  34. void        SPI_init(void)       
  35. {
  36.         SPCTL = (SSIG << 7)+(SPEN << 6)+(DORD << 5)+(MSTR << 4)+(CPOL << 3)+(CPHA << 2)+SPEED_2;
  37. }

  38. /*********************************
  39. 函数名称:Lcd_write_byte
  40. 功能:LCD通过硬件SPI发送一个字节
  41. 输入:写入内容
  42. 输出:无
  43. 备注:硬件SPI串口
  44. *********************************/
  45. void Lcd_write_byte(unsigned char Byte)
  46. {
  47.     SPDAT = Byte;                //发送一个字节
  48.     while((SPSTAT & SPIF)==0)        ;        //等待发送完成
  49.     SPSTAT = SPIF+WCOL;                        //清0 SPIF和WCOL标志
  50. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2023-7-27 15:46:39 | 显示全部楼层
我写了一个手推车的微秒带参数延时函数,需要的话可以到坛子里找桃源客大神双路电压电流表那个帖子里找一下。每调用一次比实际需求多5个机器周期。你这个毫秒级的应该比较好写,随便改一下软件自动生成的那个代码或者网上能找到现成的函数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-27 18:48:35 来自手机浏览器 | 显示全部楼层
xueyeteng 发表于 2023-7-27 15:46
我写了一个手推车的微秒带参数延时函数,需要的话可以到坛子里找桃源客大神双路电压电流表那个帖子里找一下 ...

有个小工具可以自动生成,我赖的找而已,不过还是谢谢了…
回复 支持 反对

使用道具 举报

发表于 2023-7-27 21:23:59 | 显示全部楼层
image.png
回复 支持 反对

使用道具 举报

发表于 2023-7-27 23:46:35 | 显示全部楼层
只有看看的份,不会
回复 支持 反对

使用道具 举报

发表于 2023-7-28 01:52:04 来自手机浏览器 | 显示全部楼层
专家级别的大神!膜拜了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-28 14:34 , Processed in 0.234001 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表