矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 7722|回复: 11

12864取模器

[复制链接]
     
发表于 2013-2-4 17:07:37 | 显示全部楼层 |阅读模式
本帖最后由 xjw01 于 2013-2-4 20:02 编辑

问题提出:
假如,你有程序设计基础,就会发现12864图文编程与1602编程基本相同。
  lcd1602最大的难题就是自定义字符的字模建立。比如,有的屏没有“欧姆”,我宁可使用w或R来表示,也不愿意为他建立一个自定义的字模,太麻烦了。
  lcd12864液晶编程,最大的难点依然是图形、汉字的字模信息处理。

一、
  有些不同的是,许多12864,显示信号的时候,使用“暗码”,而1602使用“明码”,即众所周知的ASCII字码。
  因为字码使用“暗码”,使用12864编程变的比1602困难一些。
  如果把暗码也显示出来,那么阅读12864程序时,就与1602程序差不多了。
  为此,设计了一个“12864字码浏览器”。
二、
  使用12864编程时,有些“图形文字”需要自定义字库,使用通用软件,需要保留工作文件,日后才能方便编辑与修改。
一般,只保留 0x** 这样的数据,那么就不好修改了。所以今天又设计了一个“12864取模器”,可以把0x数据导入并编辑
三、如果你初学12864,被那一大堆的 0x数据吓倒了,不要紧,你把0x数据放到这个软件中,一看就明白了
  读12864程序,会看到一大堆零 0x 相关数据,却往往不知道那些数据表示什么。用“12864字码浏览器”,也可以快速解决你的问题。
  前天,我刚刚学习12864液晶,看到一大堆零的0x,十分恼火,于是编写此程序,以便看清12864程序。


12864取模.rar (7.59 KB, 下载次数: 1407)

评分

2

查看全部评分

     
 楼主| 发表于 2013-2-4 17:16:36 | 显示全部楼层
使用脚本语言编写的。用IE浏览器即可打开。
没有调用插件、控件,所以一般的电脑都可以运行。
当然,要允许活动脚本运行。
脚本没有加载病毒,放心使用。用记事本看一下就明白了,只做字码转换。记事打开不会中毒的。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-4 17:45:37 | 显示全部楼层
有bug,更新
12864.rar (7.62 KB, 下载次数: 1166)
回复 支持 反对

使用道具 举报

     
发表于 2013-2-4 18:22:18 | 显示全部楼层
很好的资料!谢谢许老师指点我们这些单片机学习方法。
回复 支持 反对

使用道具 举报

     
发表于 2013-2-4 18:32:48 | 显示全部楼层
顶许老师的好软件
回复 支持 反对

使用道具 举报

发表于 2013-2-9 15:19:38 | 显示全部楼层
许老师太强了
回复 支持 反对

使用道具 举报

     
发表于 2013-2-9 15:41:28 | 显示全部楼层
和编程人员的习惯有关,一般来说使用点阵屏会有一个字体码表,符号其实也可以放到这个码表里面去,不过有时候符号不多就偷懒了,但我习惯用二进制表示,这样比 16 进制容易看懂,而且我也习惯写注释,不然自己过几天都看不懂了


' Cursors Draw
                        'MemLoad(VarPtr(iCursors), &b00001000, &b00011100, &b00111110, &b01111111) : DrawCursors(1, 4, 4)                                ' Display a "<" Cursors
                        'MemLoad(VarPtr(iCursors), &b01111111, &b00111110, &b00011100, &b00001000) : DrawCursors(1, 4, 4)                                ' Display a ">" Cursors
                        'MemLoad(VarPtr(iCursors), &b00000100, &b00000110, &b00000111, &b00000110, &b00000100) : DrawCursors(1, 4, 5)         ' Display a "^" Cursors
If IsTempresultSense = 1 Then
                        MemLoad(VarPtr(iCursors), &b00000110, &b00001001, &b00001001, &b000000110) : DrawCursors(31, 7, 4)                                ' Display a  Degree Cursors
                        Charat = "C" : DrawChr(37,7)
                        UpdateTempresultInfo()
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-10 12:06:07 | 显示全部楼层
写字模建议不要写为二进制且单行形式。要使用二进制,应写成多行形式,这样才可以看出字形。
要不写为16进形式就可以了,后面写好注释,基本可以解决问题。要想直观,就用“字模浏览器”查一下。

写注释的时候,多用汉语少用英语,这样别人更容易看懂程序。如果是为了练习英语表达,或团队开发中要求使用英语,那就试试E文,不过,结果是为了给外国人看代码。如果注释是写给自己看的,注释多写点还是少写点,那完全根据自己需要来定。我写注释时,硬件寄存器设置,基本是每行一个注释,算法部分注释就不一定一行一个注释,多半写一篇文章或写一本技术手册来解释算法。

此外,一个建议:VB的硬件级的数据结构表达能力(效果)不如C语言的,编写硬件驱动程序,建议使用C语言吧,这样比较轻松,也省事。C语言用于科学计算、硬件驱动等方面,还是比较合适的。Basic在这两个方面,基本没有优势。
回复 支持 反对

使用道具 举报

     
发表于 2013-2-10 16:31:33 | 显示全部楼层
没办法,C 太水皮了,只好用 BASIC

上一个我自己写的 12864(KS0108)驱动



'///////////////////////////////////////////////////////////////////////////////////////////////////

                                                                                'Screen Drive

'///////////////////////////////////////////////////////////////////////////////////////////////////

Function SetKS(Code As Byte, Channel As Byte) As Byte        ' 写指令函数
IO_SCR_DAT = Code
Select Case Channel                                                                                ' PA3 和 PA4 组合决定使用屏的区域,19264 有三个 64x64 区域
       Case 1 : IO_SCR_CSB = 0 : IO_SCR_CSA = 1
       Case 2 : IO_SCR_CSB = 1 : IO_SCR_CSA = 0
       'Case 3 : IO_SCR_CSB = 0 : IO_SCR_CSA = 1
End Select
IO_SCR_RoW = 0                                                                                                ' 设置为写状态 (0=Write,1=Read)
IO_SCR_DoI = 0                                                                                                ' 设置为指令状态 (0=指令,1=数据)
IO_SCR_STB = 1 : WaitUs 1 : IO_SCR_STB = 0 : WaitUs 1                        ' 在 En 的上升沿,指令或数据进入屏幕
Return 0
End Function

Function WriteKS(Code As Byte, Channel As Byte) As Byte        ' 写指令函数
IO_SCR_DAT = Code
Select Case Channel                                                                                ' PA3 和 PA4 组合决定使用屏的区域,19264 有三个 64x64 区域
       Case 1 : IO_SCR_CSB = 0 : IO_SCR_CSA = 1
       Case 2 : IO_SCR_CSB = 1 : IO_SCR_CSA = 0
       'Case 3 : IO_SCR_CSB = 0 : IO_SCR_CSA = 1
End Select
IO_SCR_RoW = 0
IO_SCR_DoI = 1                                                                                                ' 设置为数据状态 (0=指令,1=数据)
IO_SCR_STB = 1 : WaitUs 1 : IO_SCR_STB = 0 : WaitUs 1
Return 0
End Function

Function InitKS() As Byte
Local iC As Byte
ResetKS()
For iC = 1 To 3
    SetKS(&hc0, iC)                                                                                ' 向屏幕的三个控制 IC 写入初始化和开显示的指令
    SetKS(&h3f, iC)
Next iC
Return 0
End Function

Function ResetKS() As Byte                                                                ' 给屏幕完成上电脉冲,可用一个硬件电路来完成
IO_SCR_RST = 0
WaitMs 200
IO_SCR_RST = 1
End Function

Function ClsKS(GRAM As Byte) As Byte                                        ' 清屏函数,给整个屏幕清除显示
Local iP As Byte
Local iQ As Byte
Local iC As Byte

For iC = 1 To 3
    For iP = 0 To 7
        For iQ = 0 To 63
            SetKS(&hB8 + iP, iC)                                                ' 设置显存开始写数据的页地址
            SetKS(&h40 + iQ, iC)                                                ' 设置显存开始写数据的行地址
            WriteKS(GRAM, iC)                                                        ' 写入一个 8bit 的显存数据
        Next iQ
    Next iP
Next iC
Return 0        
End Function

Function DrawPix(x As Byte, y As Byte) As Byte                        ' 在屏幕上绘制一个点
Local xAdd As Byte
Local xChip As Byte
Local yAdd As Byte
Local yCode As Byte
Local yPage As Byte
Local iStep As Byte
yCode = 1

xChip = ((x-1)/64)+1                                                                        ' 因为屏幕是3个 64pix 区域,所以需要根据横坐标决定实际上位于哪个控制 IC 的显存的行地址
xAdd = x mod 64
If xAdd = 0 Then
   xAdd = 63
Else
   xAdd = xAdd - 1
End If

yPage = (y-1)/8                                                                                        ' KS0108 的纵坐标是 8 页每页 8 个点,据此找到页地址
yAdd = y mod 8
If yAdd = 0 Then yAdd = 8
For iStep = 1 To yAdd - 1
    yCode = yCode * 2
Next iStep
If yAdd = 1 Then yCode = 1

SetKS(&hB8 + yPage, xChip)                                                                ' 设置显存开始写数据的页地址
SetKS(&h40 + xAdd, xChip)                                                                ' 设置显存开始写数据的行地址
WriteKS(yCode, xChip)
Return 0
End Function

Function DrawPage(x As Byte, Page As Byte, Code As Byte) As Byte
Local xAdd As Byte                                                                                ' 显存一次写入整页的函数
Local xChip As Byte
xChip = ((x-1)/64)+1
xAdd = x mod 64
If xAdd = 0 Then
   xAdd = 63
Else
   xAdd = xAdd - 1
End If
SetKS(&hB8 + Page, xChip)
SetKS(&h40 + xAdd, xChip)
WriteKS(Code, xChip)
Return 0
End Function

Function DrawChr(x As Byte, Page As Byte) As Byte                ' 显示一行字符,必须是码表中存在的标准 ASCII 字符
Local is As Byte
Local iLs As Byte
Local iFn As Byte
Local iChn As Byte
Local bChr As Byte
Local xAdd As Byte

xAdd = 0
iLs = Len(Charat)

For is = 1 To iLs
    bChr = Asc(Mid(Charat,is,1)) - 32                                        ' 根据每一个字符的 ASCII 马,在码表数组中找到对应的数据,一个字符是 5x8 点的 5 个 Byte 数据
    For iFn = 0 To 4
        iChn = Ft1(bChr * 5 + iFn)
        DrawPage(x+xAdd,Page,iChn)                                                ' 将每一个字符对应的这 5 个 Byte 写到显存
        xAdd = xAdd + 1
    Next iFn
    xAdd = xAdd + 1
Next is
Return 0
End Function

Function DrawChrLarge(x As Byte, Page As Byte) As Byte                ' 显示一行字符,必须是码表中存在的标准 ASCII 字符
Local is As Byte
Local iLs As Byte
Local iFn As Byte
Local iChn As Byte
Local bChr As Byte
Local xAdd As Byte

xAdd = 0
iLs = Len(Charat)

For is = 1 To iLs
    bChr = Asc(Mid(Charat,is,1)) - 32                                        ' 根据每一个字符的 ASCII 马,在码表数组中找到对应的数据,一个字符是 6x16 点的 ? 个 Byte 数据
    For iFn = 0 To 11
        iChn = Ft2(bChr * 12 + iFn)
        If iFn < 6 Then
           DrawPage(x+xAdd,Page,iChn)                                                ' 将每一个字符对应的这 5 个 Byte 写到显存
        Else
           DrawPage(x+xAdd-6,Page + 1,iChn)        
        End If
        xAdd = xAdd + 1
    Next iFn
    xAdd = xAdd - 6
    xAdd = xAdd + 1
Next is
Return 0
End Function
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-10 17:44:37 | 显示全部楼层
你参考一下C语言代码,这是我前几天写的ks0108的完整驱动。所需的代码比basic简洁很多的。你可以参考一下。
  1. /******************************************************************
  2.    本程序供学习ks0108系列LCD使用,勿他用
  3.    许剑伟
  4. ******************************************************************/
  5. #include <reg52.h>

  6. #define lcd_DA P2    //数据口
  7. sbit lcd_cs1 = P0^7; //左屏选通
  8. sbit lcd_cs2 = P0^6; //右屏选通
  9. sbit lcd_En  = P0^3; //使能信号
  10. sbit lcd_RW  = P0^4; //读写控制
  11. sbit lcd_RS  = P0^5; //命令与数据控制
  12. sbit lcd_RST = P0^2; //复位

  13. void lcd_delay(unsigned int n) { //微秒延时
  14. unsigned int i;
  15. for(i=0;i<n;i++); //1200次约1ms
  16. }
  17. void lcd_B(char c,unsigned char d){ //写数据到LCD
  18. lcd_RS=c; lcd_RW=0;
  19. lcd_DA=d; lcd_delay(1);
  20. lcd_En=1; lcd_delay(1); //产生使能脉冲
  21. lcd_En=0;
  22. }

  23. //============================================================
  24. //                常用显示函数
  25. //============================================================
  26. void lcd_cls(){ //清屏
  27. unsigned char j,k;
  28. lcd_cs1 = lcd_cs2 = 1; //选通左右两个半屏
  29. for(k=0;k<8;k++){
  30.   lcd_B(0,0xb8+k); //行定位,列不用再定位了,因为列地址是循环移动的
  31.   for(j=0;j<64;j++)lcd_B(1,0x00); //该页64字节全部写入0
  32. }
  33. }
  34. void lcd_init(){ //初始化LCD屏
  35. lcd_RST=0; lcd_delay(10000); //复位
  36. lcd_RST=1; lcd_delay(10000);
  37. lcd_cs1 = lcd_cs2=1; //选通左右两个半屏
  38. lcd_B(0,0x3e);   //关显示
  39. lcd_B(0,0xc0+0); //显示起始行设置为第0行
  40. lcd_B(0,0xb8+0); //页定位,x=0
  41. lcd_B(0,0x40+0); //列定位,y=0
  42. lcd_B(0,0x3f);   //开显示
  43. }
  44. void lcd_goto(unsigned char x,unsigned char y){ //读写位置定位
  45.   if(x<64) { lcd_cs1=1, lcd_cs2=0;         } //选通左屏
  46.   else     { lcd_cs1=0, lcd_cs2=1, x-=64;; } //选通右屏
  47.   lcd_B(0,0xb8+y); //页定位
  48.   lcd_B(0,0x40+x); //列定位
  49. }
  50. void lcd_goto2(unsigned char x,unsigned char y){ //读写位置定位(用于左右屏显示相同内容)
  51.   lcd_cs1 = lcd_cs2=1; //选通左右屏
  52.   lcd_B(0,0xb8+y); //页定位
  53.   lcd_B(0,0x40+x); //列定位
  54. }
  55. void lcd_img(unsigned char x,unsigned char y,unsigned char code *img, unsigned char w, unsigned char h){ //在指定位置上显示一个图片
  56. unsigned char j,k;
  57. for(k=0;k<h;k++){  //扫描各页
  58.    lcd_goto(x,y+k); //定位
  59.    for(j=0;j<w;j++){ //扫描各列
  60.      if(x+j==64) lcd_goto(64,y+k); //中途换右屏
  61.      lcd_B(1,img[k*w+j]); //写数据
  62.    }  
  63. }
  64. }
  65. void lcd_putc(unsigned char x,unsigned char y,unsigned char c){  //显示6*8字符
  66.   lcd_img(x,y,Font6x8+c*6-192,6,1);
  67. }
  68. void lcd_puts(unsigned char x,unsigned char y,unsigned char *s){ //显示6*8字串
  69. char i;
  70. for(i=0;s[i];i++)
  71.    lcd_img(x+i*6,y,Font6x8+s[i]*6-192,6,1);
  72. }
  73. void lcd_hz16(unsigned char x,unsigned char y,unsigned char c){  //显示16*16汉字
  74.   lcd_img(x,y,Font16x16+c*32,16,2);
  75. }
复制代码
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-10 17:47:03 | 显示全部楼层
字库定义方法
  1. char code Font6x8[]={
  2. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // sp !
  3. 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // " #
  4. 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // $ %
  5. 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // & '
  6. 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ( )
  7. 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // * +
  8. 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // ' -
  9. 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // . /
  10. 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 0 1
  11. 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 2 3
  12. 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 4 5
  13. 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 6 7
  14. 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 8 9
  15. 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // : ;
  16. 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // < =
  17. 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // > ?
  18. 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // @ A
  19. 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // B C
  20. 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // D E
  21. 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // F G
  22. 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // H I
  23. 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // J K
  24. 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // L M
  25. 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // N O
  26. 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // P Q
  27. 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // R S
  28. 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // T U
  29. 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // V W
  30. 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // X Y
  31. 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // Z [
  32. 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // \ ]
  33. 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // ^ _
  34. 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // ' a
  35. 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, 0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // b c
  36. 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // d e
  37. 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // f g
  38. 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // h i
  39. 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // j k
  40. 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // l m
  41. 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // n o
  42. 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // p q
  43. 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // r s
  44. 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // t u
  45. 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // v w
  46. 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // x y
  47. 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14  // z 双横线
  48. };

复制代码
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-14 21:01:06 | 显示全部楼层
增加了st7920芯片的12864字模处理软件
字模.rar (16.19 KB, 下载次数: 602)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-27 03:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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