找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 439|回复: 5
打印 上一主题 下一主题
收起左侧

求助LCD1602 CGRAM写入问题

[复制链接]
跳转到指定楼层
楼主
ID:1130445 发表于 2024-8-13 00:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CGRAM自定义字符部分,将字模写入0x40-0x80时,0x48-0x80区段正常写入读取,但是0x40写入后,读取不到写入字符,出现乱码,也就是运行WriteData(0)时出现错误;
有大佬知道是怎么回事吗,部分代码已经贴到下面了

unsigned char code Table[8][8]={
{0x04,0x0E,0x15,0x04,0x04,0x04,0x04,0x00},//↑
{0x00,0x04,0x04,0x04,0x04,0x15,0x0E,0x04},//↓
{0x00,0x04,0x08,0x1F,0x08,0x04,0x00,0x00},//←
{0x00,0x04,0x02,0x1F,0x02,0x04,0x00,0x00},//→
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
};

void LCD_SetCustomChar(char (*Table)[8])
{
        unsigned char i,j;
        for(i=0;i<8;i++){
                LCD_WriteCommand(0x40+(8*i));
                for(j=0;j<8;j++){
                        LCD_WriteData(*(*(Table+i)+j));
                }
        }
}
void LCD_ShowCustomChar(unsigned char Line,unsigned char Column,unsigned char Num)
{
        LCD_SetCursor(Line,Column);
        LCD_WriteData(Num);
}



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:69038 发表于 2024-8-13 10:46 | 只看该作者
怀疑void LCD_SetCustomChar(char (*Table)[8])这个函数有问题,或许你根本没写入到CGRAM。。
你定义的Table[8][8]是二维数组,
LCD_WriteData(*(*(Table+i)+j));//读取的是1维数据?
不知有没有错。给你个代码参考测试一下:
  1. uchar code Word1[]={
  2.                      0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,//一
  3.                      0x00,0x0E,0x00,0x00,0x00,0x1F,0x00,0x00,//二
  4.                      0x0E,0x00,0x00,0x0E,0x00,0x00,0x1F,0x00,//三
  5.                      0x1F,0x11,0x15,0x15,0x1F,0x11,0x1F,0x00,//四
  6.                      0x1E,0x08,0x08,0x1E,0x0A,0x0A,0x1F,0x00,//五
  7.                      0x04,0x1F,0x00,0x0A,0x0A,0x0A,0x1B,0x00,//六
  8.                      0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00,//日
  9.                      0x0F,0x09,0x0F,0x09,0x0F,0x09,0x13,0x00,//月
  10.                      0x08,0x1F,0x12,0x0F,0x0A,0x1F,0x02,0x00};//年



  11. void main()
  12. {   
  13.      uchar num;
  14.            uchar j;//
  15.      Lcd_1602_init();
  16.        
  17.                         Lcd_1602_write(0,0x40);        //操作CGRAM
  18.             for (j=0;j<64;j++)
  19.       Lcd_1602_write(1,Word1[j]);    //连续写入64字节,8个字符, 5*7点阵按8*8计算
  20.        


  21.                
  22.    while(1)
  23.                 {
  24.                        
  25.                        
  26.             Lcd_1602_write(0,0x83);         //指定显示地址,从第一行第3个字符开始
  27.       for(num=3;num<16;num++)
  28.     {      
  29.        Lcd_1602_write(1,table1[num]);      //连续显示16个字符
  30.        delay(3);
  31.     }
  32.     Lcd_1602_write(0,0xc0);                //第2行第1个字符开始
  33.     for(num=0;num<16;num++)
  34.     {
  35.        Lcd_1602_write(1,table2[num]);//显示另一组16个字符
  36.        delay(3);
  37.     }               
  38.                
  39.                   Lcd_1602_write(0,0x80);        //指定显示位置
  40.                         for (j=0;j<8;j++)
  41.                         {
  42.                   Lcd_1602_write(1,j);        //显示内存1个字符
  43.                   delay(100);                               
  44.                         }
  45.                         for (j=0;j<8;j++)
  46.                         {
  47.                   Lcd_1602_write(1,j);        //显示内存1个字符
  48.                   delay(100);
  49.                         }               
  50.                        
  51.             Lcd_1602_write(0,0xc0);        //指定显示位置
  52.                         for (j=0;j<8;j++)
  53.                         {
  54.                   Lcd_1602_write(1,7-j);        //显示内存1个字符
  55.                   delay(100);
  56.                         }
  57.                         for (j=0;j<8;j++)
  58.                         {
  59.                   Lcd_1602_write(1,7-j);        //显示内存1个字符
  60.                   delay(100);
  61.                         }       
  62.                 delay(1000);
  63.                         Lcd_1602_write(0,0x01);
  64.                 delay(500);       
  65.         }
  66. }
复制代码



回复

使用道具 举报

板凳
ID:57657 发表于 2024-8-13 11:57 | 只看该作者
楼主的程序不完整,缺少 LCD_WriteCommand, LCD_WriteData 函数。
回复

使用道具 举报

地板
ID:1130445 发表于 2024-8-13 19:02 | 只看该作者
npn 发表于 2024-8-13 11:57
楼主的程序不完整,缺少 LCD_WriteCommand, LCD_WriteData 函数。

void LCD_WriteCommand(unsigned char Command)
{
        LCD_RS=0;
        LCD_RW=0;
        P0=Command;
        LCD_EN=1;
        Delay1ms();
        LCD_EN=0;       
}

void LCD_WriteData(unsigned char Data)
{
        LCD_RS=1;
        LCD_RW=0;
        P0=Data;
        LCD_EN=1;
        Delay1ms();
        LCD_EN=0;       
}

LCD_WriteCommand和LCD_WriteData在这里,就是看着手册写的
回复

使用道具 举报

5#
ID:1130445 发表于 2024-8-13 21:09 | 只看该作者
zhuls 发表于 2024-8-13 10:46
怀疑void LCD_SetCustomChar(char (*Table)[8])这个函数有问题,或许你根本没写入到CGRAM。。
你定义的Tab ...

采用一维数组录入,然后读取,也是存在这个问题
上述char(*Table)[8]数据指针指向数组名,CGRAM里64个字节存储数据,所以LCD_WriteData依次遍历Table[i ][j]的数据感觉是没什么问题的

字模数据肯定有写入到CGRAM的,因为0x48后面的数据都可以正常读取到,重写和读取都可以,只有在指向0x40的时候,就显示空白或者乱码,剩余的7个自定义符号都可以,然后有尝试过将WriteData(Num)NUm范围0-7;改为WriteData(Num)Num范围1-8,第8位就不能显示;所以目前是不太清楚0x40没有写进去数据,还是说WriteData(0)这个地方0的参数有问题
回复

使用道具 举报

6#
ID:57657 发表于 2024-8-15 06:51 | 只看该作者
楼主可以参考下这个这个程序
  1. #include "STC12C5A60S2.h"                //根据单片机系列改头文件 晶振频率:12Mhz
  2. #include "intrins.h"
  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long

  6. #define Port P2
  7. sbit RS = P0 ^ 7;
  8. sbit RW = P0 ^ 6;
  9. sbit E = P0 ^ 5;

  10. sbit busy = Port ^ 7;                //忙标志位
  11. sbit LED = P1 ^ 0;                //闪烁:初始化失败 常亮:初始化正常 (低电平点亮)
  12. u8 *text = "  LCD1602 Test      \x00\x01\x02\x03\x04\x05\x06\x07    ";                //显示的字符 (固定32字节)

  13. void lcd1602_delay(){
  14.         u8 data i, j;
  15.         _nop_();
  16.         _nop_();
  17.         i = 3;
  18.         j = 231;
  19.         do
  20.         {
  21.                 while (--j);
  22.         } while (--i);
  23. }


  24. bit lcd1602_wait(){                //LCD1602查忙等待 (正常返回1,超时返回0)
  25.         u8 count = 0;

  26.                 RS = 0;
  27.                 RW = 1;
  28.                 lcd1602_delay();
  29.                 E = 0;
  30.                 lcd1602_delay();
  31.                 E = 1;
  32.                 do {
  33.                         if(!++count){
  34.                                 return 0;
  35.                         }

  36.                 } while(busy);
  37.        
  38.         return 1;
  39. }

  40. bit lcd1602_write(bit rs,u8 dat){        //写1602 (rs 0:指令 1:数据,成功返回1 失败返回0)
  41.         if(!lcd1602_wait()){
  42.                 return 0;
  43.         }

  44.         RS = rs;
  45.         RW = 0;
  46.         Port = dat;       
  47.         lcd1602_delay();
  48.         E = 0;
  49.         lcd1602_delay();
  50.         E = 1;
  51.         return 1;
  52. }

  53. u8 code lcd1602_code[] = {0x38,0x0C,0x06,0x01};
  54. bit lcd1602_init(){                //LCD1602初始化 成功返回1 失败返回0
  55.         u8 i;
  56.         for(i=0;i<4;i++){
  57.                 if(!lcd1602_write(0,lcd1602_code[i])){
  58.                         return 0;
  59.                 }
  60.         }
  61.         return 1;
  62. }

  63. /*
  64. LCD1602创建自定义图像 (成功返回1,失败返回0)
  65. ascii:字符ASCII码 范围:0~7 4表示字符:chr(4) \x04
  66. dat:8字节点阵数据数组
  67. */
  68. bit lcd1602_char(u8 ascii,u8 dat[]){
  69.         u8 i;
  70.         if(ascii > 7){
  71.                 return 0;
  72.         }
  73.                 if(!lcd1602_write(0,0x40|(ascii<<3))){                        //CGRAM 地址
  74.                         return 0;
  75.                 }
  76.         for(i=0;i<8;i++){
  77.                 if(!lcd1602_write(1,dat[i])){                        //CGRAM数据
  78.                         return 0;
  79.                 }
  80.         }
  81.         return 1;
  82. }


  83. void Delay500ms(void)        //@12MHz
  84. {
  85.         unsigned char data i, j, k;

  86.         i = 23;
  87.         j = 205;
  88.         k = 120;
  89.         do
  90.         {
  91.                 do
  92.                 {
  93.                         while (--k);
  94.                 } while (--j);
  95.         } while (--i);
  96. }

  97. u8 code Table[8][8]={
  98. {0x04,0x0E,0x15,0x04,0x04,0x04,0x04,0x00},//↑
  99. {0x00,0x04,0x04,0x04,0x04,0x15,0x0E,0x04},//↓
  100. {0x00,0x04,0x08,0x1F,0x08,0x04,0x00,0x00},//←
  101. {0x00,0x04,0x02,0x1F,0x02,0x04,0x00,0x00},//→
  102. {0,0,0,0,0,0,0,0},
  103. {0,0,0,0,0,0,0,0},
  104. {0,0,0,0,0,0,0,0},
  105. {0,0,0,0,0,0,0,0},
  106. };


  107. void main(){                //主函数
  108.         u8 i;

  109.         // CLK_DIV = 0x03;       
  110.         if(!lcd1602_init()){                //初始化失败
  111.                 while(1){
  112.                 LED = !LED;
  113.                 Delay500ms();
  114.                 }
  115.                
  116.         }
  117.         LED = 0;
  118.         for(i=0;i<8;i++){
  119.                 lcd1602_char(i,Table[i]);
  120.         }       
  121.         lcd1602_write(0,0x80);
  122.         for(i=0;i<16;i++){
  123.                 lcd1602_write(1,text[i]);
  124.         }
  125.        
  126.         lcd1602_write(0,0xC0);
  127.         for(i=16;i<32;i++){
  128.                 lcd1602_write(1,text[i]);
  129.         }

  130.         while(1);

  131.        
  132. }
复制代码
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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