数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 134|回复: 10

[STM] 工行U盾屏幕驱动

[复制链接]
发表于 7 小时前 | 显示全部楼层 |阅读模式

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

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

x
不知道有没有人点过,恰巧手里有一个这玩意,就点了一下。

地上捡了个工行u盾,开机显示金融@家,然后就什么也不动了,不知道好坏,决定拆屏幕玩玩
外壳这样

背面

屏幕共10pin,测得4脚为gnd,其他未知
一古脑飞线出所有的pin,接逻辑分析仪

开机捕获波形,然后得出结果如下(含之后stm8接线):




然后拆下来焊转接板上,接stm8,刷固件点亮,一次成功:



驱动程序如下
  1. /*
  2. * STM8S105K4T6 — ST7565-family SPI driver for FPC-G18019E-ZH-10pin
  3. *
  4. * Init sequence captured from original board boot (see ../notes/LA_BOOT.md).
  5. * Default pins: CS=PC3 A0=PC4 SCLK=PC5 MOSI=PC6 RST=PC7
  6. */

  7. #include <stdint.h>

  8. #define _SFR(addr) (*(volatile uint8_t *)(addr))

  9. #define CLK_CKDIVR _SFR(0x50C6)
  10. #define PC_ODR     _SFR(0x500A)
  11. #define PC_DDR     _SFR(0x500C)
  12. #define PC_CR1     _SFR(0x500D)

  13. #define LCD_W 128u
  14. #define LCD_H 64u
  15. #define LCD_PAGES (LCD_H / 8u)

  16. /* PC3..PC7 */
  17. #define PIN_CS   (1u << 3)
  18. #define PIN_A0   (1u << 4)
  19. #define PIN_SCLK (1u << 5)
  20. #define PIN_MOSI (1u << 6)
  21. #define PIN_RST  (1u << 7)
  22. #define PIN_ALL  (PIN_CS | PIN_A0 | PIN_SCLK | PIN_MOSI | PIN_RST)

  23. static void delay_ms(uint16_t ms)
  24. {
  25.     /* Rough busy-wait after CKDIVR=0 (fCPU ≈ 16 MHz HSI). */
  26.     while (ms--) {
  27.         uint16_t n = 1600u;
  28.         while (n--) {
  29.             __asm__("nop");
  30.         }
  31.     }
  32. }

  33. static void gpio_init(void)
  34. {
  35.     CLK_CKDIVR = 0x00u; /* fCPU = fHSI = 16 MHz */
  36.     PC_DDR |= PIN_ALL;
  37.     PC_CR1 |= PIN_ALL;
  38.     PC_ODR |= PIN_CS | PIN_A0 | PIN_SCLK | PIN_RST;
  39.     PC_ODR &= (uint8_t)~PIN_MOSI;
  40. }

  41. static void spi_write_byte(uint8_t v)
  42. {
  43.     uint8_t i;
  44.     for (i = 0u; i < 8u; i++) {
  45.         if (v & 0x80u)
  46.             PC_ODR |= PIN_MOSI;
  47.         else
  48.             PC_ODR &= (uint8_t)~PIN_MOSI;
  49.         PC_ODR |= PIN_SCLK;
  50.         __asm__("nop");
  51.         __asm__("nop");
  52.         PC_ODR &= (uint8_t)~PIN_SCLK;
  53.         v <<= 1;
  54.     }
  55. }

  56. static void lcd_cmd(uint8_t c)
  57. {
  58.     PC_ODR &= (uint8_t)~PIN_CS;
  59.     PC_ODR &= (uint8_t)~PIN_A0;
  60.     spi_write_byte(c);
  61.     PC_ODR |= PIN_CS;
  62. }

  63. static void lcd_data(uint8_t d)
  64. {
  65.     PC_ODR &= (uint8_t)~PIN_CS;
  66.     PC_ODR |= PIN_A0;
  67.     spi_write_byte(d);
  68.     PC_ODR |= PIN_CS;
  69. }

  70. static void lcd_data_buf(const uint8_t *p, uint8_t n)
  71. {
  72.     PC_ODR &= (uint8_t)~PIN_CS;
  73.     PC_ODR |= PIN_A0;
  74.     while (n--)
  75.         spi_write_byte(*p++);
  76.     PC_ODR |= PIN_CS;
  77. }

  78. static void lcd_set_pos(uint8_t page, uint8_t col)
  79. {
  80.     lcd_cmd((uint8_t)(0xB0u | (page & 0x0Fu)));
  81.     lcd_cmd((uint8_t)(0x10u | ((col >> 4) & 0x0Fu)));
  82.     lcd_cmd((uint8_t)(0x00u | (col & 0x0Fu)));
  83. }

  84. /* Exact command sequence from original boot capture */
  85. static void lcd_init(void)
  86. {
  87.     PC_ODR |= PIN_RST;
  88.     delay_ms(10u);
  89.     PC_ODR &= (uint8_t)~PIN_RST;
  90.     delay_ms(5u);
  91.     PC_ODR |= PIN_RST;
  92.     delay_ms(10u);

  93.     lcd_cmd(0xE2u); /* SW reset */
  94.     delay_ms(10u);
  95.     lcd_cmd(0xA2u); /* bias 1/9 */
  96.     lcd_cmd(0xA0u); /* ADC normal */
  97.     lcd_cmd(0xC8u); /* COM reverse */
  98.     lcd_cmd(0xA4u); /* display from RAM */
  99.     lcd_cmd(0xA6u); /* normal (not reverse video) */
  100.     lcd_cmd(0x24u); /* regulator resistor ratio */
  101.     lcd_cmd(0x81u); /* electronic volume */
  102.     lcd_cmd(0x25u);
  103.     lcd_cmd(0xF8u); /* booster ratio */
  104.     lcd_cmd(0x00u);
  105.     lcd_cmd(0x2Cu);
  106.     delay_ms(5u);
  107.     lcd_cmd(0x2Eu);
  108.     delay_ms(5u);
  109.     lcd_cmd(0x2Fu); /* power all on */
  110.     delay_ms(10u);
  111.     lcd_cmd(0x40u); /* start line 0 */
  112.     lcd_cmd(0xAFu); /* display ON */
  113. }

  114. static void lcd_fill(uint8_t v)
  115. {
  116.     uint8_t page;
  117.     uint8_t col;
  118.     uint8_t line[LCD_W];

  119.     for (col = 0u; col < LCD_W; col++)
  120.         line[col] = v;

  121.     for (page = 0u; page < LCD_PAGES; page++) {
  122.         lcd_set_pos(page, 0u);
  123.         lcd_data_buf(line, LCD_W);
  124.     }
  125. }

  126. static void lcd_checkerboard(void)
  127. {
  128.     uint8_t page;
  129.     uint8_t col;
  130.     uint8_t line[LCD_W];

  131.     for (page = 0u; page < LCD_PAGES; page++) {
  132.         for (col = 0u; col < LCD_W; col++) {
  133.             uint8_t on = ((col >> 3) ^ page) & 1u;
  134.             line[col] = on ? 0xFFu : 0x00u;
  135.         }
  136.         lcd_set_pos(page, 0u);
  137.         lcd_data_buf(line, LCD_W);
  138.     }
  139. }

  140. /* 5x7 glyphs in 8-tall pages; columns packed MSB=top unused bit0..6 used */
  141. static const uint8_t FONT5[][5] = {
  142.     { 0x3E, 0x51, 0x49, 0x45, 0x3E }, /* 0 */
  143.     { 0x00, 0x42, 0x7F, 0x40, 0x00 }, /* 1 */
  144.     { 0x42, 0x61, 0x51, 0x49, 0x46 }, /* 2 */
  145.     { 0x21, 0x41, 0x45, 0x4B, 0x31 }, /* 3 */
  146.     { 0x18, 0x14, 0x12, 0x7F, 0x10 }, /* 4 */
  147.     { 0x27, 0x45, 0x45, 0x45, 0x39 }, /* 5 */
  148.     { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, /* 6 */
  149.     { 0x01, 0x71, 0x09, 0x05, 0x03 }, /* 7 */
  150.     { 0x36, 0x49, 0x49, 0x49, 0x36 }, /* 8 */
  151.     { 0x06, 0x49, 0x49, 0x29, 0x1E }, /* 9 */
  152.     { 0x7E, 0x11, 0x11, 0x11, 0x7E }, /* A */
  153.     { 0x7F, 0x49, 0x49, 0x49, 0x36 }, /* B */
  154.     { 0x3E, 0x41, 0x41, 0x41, 0x22 }, /* C */
  155.     { 0x7F, 0x41, 0x41, 0x22, 0x1C }, /* D */
  156.     { 0x7F, 0x49, 0x49, 0x49, 0x41 }, /* E */
  157.     { 0x7F, 0x09, 0x09, 0x09, 0x01 }, /* F */
  158.     { 0x3E, 0x41, 0x49, 0x49, 0x7A }, /* G */
  159.     { 0x7F, 0x08, 0x08, 0x08, 0x7F }, /* H */
  160.     { 0x00, 0x41, 0x7F, 0x41, 0x00 }, /* I */
  161.     { 0x20, 0x40, 0x41, 0x3F, 0x01 }, /* J */
  162.     { 0x7F, 0x08, 0x14, 0x22, 0x41 }, /* K */
  163.     { 0x7F, 0x40, 0x40, 0x40, 0x40 }, /* L */
  164.     { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, /* M */
  165.     { 0x7F, 0x04, 0x08, 0x10, 0x7F }, /* N */
  166.     { 0x3E, 0x41, 0x41, 0x41, 0x3E }, /* O */
  167.     { 0x7F, 0x09, 0x09, 0x09, 0x06 }, /* P */
  168.     { 0x3E, 0x41, 0x51, 0x21, 0x5E }, /* Q */
  169.     { 0x7F, 0x09, 0x19, 0x29, 0x46 }, /* R */
  170.     { 0x46, 0x49, 0x49, 0x49, 0x31 }, /* S */
  171.     { 0x01, 0x01, 0x7F, 0x01, 0x01 }, /* T */
  172.     { 0x3F, 0x40, 0x40, 0x40, 0x3F }, /* U */
  173.     { 0x1F, 0x20, 0x40, 0x20, 0x1F }, /* V */
  174.     { 0x3F, 0x40, 0x38, 0x40, 0x3F }, /* W */
  175.     { 0x63, 0x14, 0x08, 0x14, 0x63 }, /* X */
  176.     { 0x07, 0x08, 0x70, 0x08, 0x07 }, /* Y */
  177.     { 0x61, 0x51, 0x49, 0x45, 0x43 }, /* Z */
  178.     { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* space */
  179. };

  180. static uint8_t glyph_index(char c)
  181. {
  182.     if (c >= '0' && c <= '9')
  183.         return (uint8_t)(c - '0');
  184.     if (c >= 'A' && c <= 'Z')
  185.         return (uint8_t)(10u + (c - 'A'));
  186.     if (c >= 'a' && c <= 'z')
  187.         return (uint8_t)(10u + (c - 'a'));
  188.     return 36u; /* space */
  189. }

  190. static void lcd_draw_char(uint8_t page, uint8_t col, char c)
  191. {
  192.     uint8_t idx = glyph_index(c);
  193.     lcd_set_pos(page, col);
  194.     lcd_data_buf(FONT5[idx], 5u);
  195.     lcd_data(0x00u);
  196. }

  197. static void lcd_draw_str(uint8_t page, uint8_t col, const char *s)
  198. {
  199.     while (*s) {
  200.         lcd_draw_char(page, col, *s++);
  201.         col = (uint8_t)(col + 6u);
  202.         if (col > LCD_W - 6u)
  203.             break;
  204.     }
  205. }

  206. static void lcd_hline_page(uint8_t page, uint8_t col0, uint8_t col1, uint8_t mask)
  207. {
  208.     uint8_t col;
  209.     lcd_set_pos(page, col0);
  210.     for (col = col0; col <= col1; col++)
  211.         lcd_data(mask);
  212. }

  213. void main(void)
  214. {
  215.     gpio_init();
  216.     lcd_init();

  217.     lcd_fill(0x00u);
  218.     delay_ms(200u);

  219.     lcd_draw_str(0u, 8u, "G18019E");
  220.     lcd_draw_str(2u, 8u, "ST7565");
  221.     lcd_draw_str(4u, 8u, "128x64");
  222.     lcd_hline_page(6u, 0u, 127u, 0x18u);

  223.     delay_ms(4000u);
  224.     lcd_checkerboard();

  225.     for (;;) {
  226.         delay_ms(2500u);
  227.         lcd_fill(0xFFu);
  228.         delay_ms(500u);
  229.         lcd_fill(0x00u);
  230.         delay_ms(500u);
  231.         lcd_draw_str(1u, 16u, "OK");
  232.         lcd_draw_str(3u, 4u, "STM8S105");
  233.         delay_ms(2500u);
  234.         lcd_checkerboard();
  235.     }
  236. }
复制代码


发表于 6 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 6 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 6 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 4 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 4 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 半小时前 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

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

本版积分规则

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

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-8-5 21:46 , Processed in 0.156000 second(s), 8 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

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