如何用12864液晶显示图片和绘制任意函数图象(打点)


本帖最后由 赛伯Man 于 2013-7-30 22:52 编辑

此贴源自http://bbs.elecfans.com/forum.ph ... 057&highlight=12864
一. 显示图片
   显示图片的要点在于:1.取模 2.利用扩展指令设置液晶 3.清楚液晶地址的概念
1.1取模   取模软件用的是“字模221”下图是他的参数设置     
               

     
这里对参数设置先解释一下,所谓横向取模就是,一张图片从图片最左上角的8位开始取模,从左向右,每次取8位二进制数据转化为16进制保存,第一排取完之后,接着到第二排最左边8位开始取模,以此类推。为什么要这样取模呢?因为12864液晶的横纵坐标就是这个取模顺序,这点在之后还会详细提到。
1.2液晶的设置   液晶显示图片必须用扩充指令集,初始化和显示字符的初始化不一样。
我用的初始化函数如下:
void init_picture() //显示图片的初始化函数
{    
    //lcd_wcmd(0x34);//写指令函数,扩充指令集,绘图关
    //lcd_wcmd(0x36);//8位数据传输,扩展指令操作,绘图开           
    lcd_wcmd(0x3E);//8位数据传输,扩展指令操作,绘图开             
    lcd_wcmd(0x01);//清屏 
    Light = 0;//打开背光
}
1.3将取出的字模写进相应地址   首先应该知道地址究竟是怎样的,结合下图讲清楚。12864液晶分为上半屏和下半屏。当你想要点亮某个地方时,必须先写这个地方的垂直地址接着写入它的水平地址水平地址液晶可以自动加1,而垂直地址不会。图中水平坐标从0x80+00到0x80+0F,一共16个,其中0x80+00到0x80+07是上半屏的坐标,其中0x80+08到0x80+0F是下半屏的坐标。水平坐标每个两字节,先写入的数据填充在高字节。垂直坐标只有0x80+00到0x80+1F,图中上半截0x80+00到0x80+1F是上半屏的垂直地址,另外的那部分一样的是下半屏垂直地址。
     每个垂直地址只确定一排,所以水平和垂直地址不能确定某个点的位置,只能确定某个两字节的位置,通过写进2字节数据确定点亮某个点或几个点
比如我们写入   [垂直地址]:  lcd_wcmd(0x80+1);    [水平地址]:  lcd_wcmd(0x80);  这就是说我们将在图中水平坐标00,垂直坐标01的位置(红圈处)输入数据。
                                                                     
知道地址的知识之后就明白为什么要横向取模了,接下来只要将取模的数据一个个按取模生成的顺序写进液晶就行了。下面是我用的代码,其中 uchar=unsigned char,uint=unsigned int。
void show_Pic(uchar* address)//显示图片函数
{                                         //address是是指向数组的指针,用法:show_Pic(XY)当中XY为数组名
    uchar i,j;
    for(i=0;i<32;i++)      //上半屏的32排依次先写满
    {
        lcd_wcmd(0x80+i); //先送垂直地址
        lcd_wcmd(0x80);   //再送水平地址,水平地址可自加1
        for(j=0;j<16;j++) //每排128个点,所以一共要16个两位16进制数(也就是8位二进制数)才能全部控制
        {
            lcd_wdat(*address);
                 address++;
        }
    }
    for(i=0;i<32;i++)     //下半屏的32排操作原理和上半屏一样
    { 
        lcd_wcmd(0x80+i);
        lcd_wcmd(0x88);
        for(j=0;j<16;j++)
        {
            lcd_wdat(*address);
                 address++;
        }
    }
}
1.4实际显示结果   下图是我显示的一个坐标系和一条龙 
 
 
   下面的代码是我的主函数,这部分加上上面我上面讲的函数和一些基本设置就是整个代码,XY是这幅坐标图片取模得到的数组
void main()
{
    init_picture();
    show_Pic(XY);
    while(1)            // 进入程序主循环
    {
     }
}
二. 用打点方式显示任意图像
    有的同学认为打点只需按照上面的显示图片的方法点亮需要的点就是了,其实这不行。因为你写进去的是八个点的控制,会影响周围的点,很容易出现乱码。比如,你写进去的是0x80,想的是只点亮左边一个点,其他的都不要影响,但是右边的7个0也是会显示的,如果在要显示0的地方原来显示的是1的话,你现在写进去的0就把1覆盖了,这样就容易产生乱码。所以我建议,你先把液晶的数据读出来,再用data &=(~(0x01<<(7-bit)))(bit是你点亮哪一位,data是读出来的数据)置0,置1也是类似的,最后再把data重新写进去就行了。   我的单片机接口是乱的,所以每一个液晶接口都用了位定义,并且用到了寄存器B,寄存器B的每一个当做一个变量的位来操作。我的具体代码如下:
bit lcd_busy()          // 读写判断数据的D7读写位,用于判断1602是否忙 
{                   
    bit result;
    D7 = 1;       // 数据口D7置1,为读状态做准备
    LCD_RS = 0;   // 选择指令寄存
    LCD_RW = 1;   // 选择读控制线
    LCD_EN = 1;   // 开使能控制线 
    delayNOP();   // 时序延时
    result = D7;  // 读D7的电平
    LCD_EN = 0;   // 关使能    return(result); // 返回值1:忙,0可以执行操作 


unsigned char readData(void) //读取数据函数  
{  
     uchar i;
      D0 = 1;       D1 = 1;
      D2 = 1;        D3 = 1; 
      D4 = 1;         D5 = 1;  
      D6 = 1;        D7 = 1;   
      lcd_busy();
      LCD_RS=1; LCD_RW=1;
      LCD_EN=0; LCD_EN=1; 
      B_0=D0;B_1=D1; B_2=D2; B_3=D3; //B_1=B^1,在程序前段有位定义
      B_4=D4;B_5=D5; B_6=D6; B_7=D7;
      for(i=1;i<=7;i++)      
             delayNOP(); //这个函数是{_nop_();_nop_();_nop_();_nop_();};
      LCD_EN=0;    
      return B;   
}

uchar DrawDots(uchar x,uchar y,uchar color)//打点函数   //x,y为128*64 点阵的坐标
{
     uchar row,xlabel,xlabel_bit; 
     uchar Read_H=0,Read_L=0;  
     lcd_wcmd(0x34);       //扩充指令 
     lcd_wcmd(0x36);       //绘图指令 
     xlabel=x>>4;            //确定水平坐标地址
     xlabel_bit=x & 0x0F; // 细分水平坐标中的第几位
     if(y<32) row=y;
     else      {         row=y-32;         xlabel+=8;      } 
     lcd_wcmd(row+0x80);
      lcd_wcmd(xlabel+0x80);
      readData();
      Read_H=readData();
      Read_L=readData();   
      lcd_wcmd(row+0x80);
      lcd_wcmd(xlabel+0x80);   //水平坐标地址+基址=显示的水平地址   
      if(xlabel_bit<8) 
     {
          switch(color)
         {
             case 0:Read_H &=(~(0x01<<(7-xlabel_bit))); break; //变暗 ,看不见
             case 1:Read_H |=(0x01<<(7-xlabel_bit)); break; //变亮  ,看得见
             case 2:Read_H ^=(0x01<<(7-xlabel_bit)); break; //反转
             default:break;
          } 
         cd_wdat(Read_H);
         cd_wdat(Read_L); 
      } 
      else 
     {
          switch(color)
          {
               case 0:Read_L &=(~(0x01<<(15-xlabel_bit))); break; //变暗    ,看不见 
               case 1:Read_L |=(0x01<<(15-xlabel_bit)); break; //变亮  ,看得见
               case 2:Read_L ^=(0x01<<(15-xlabel_bit)); break; //反转 
               default:break;
          } 
          lcd_wdat(Read_H);
          lcd_wdat(Read_L);
     } 
     lcd_wcmd(0x30);//恢复正常模式  
}
如果你的单片机和12864接口不是乱的,那可以这样写读取函数 
unsigned char readData(void)   

      uchar i ,data;
      P0=0xFF; 
       lcd_busy();
       LCD_RS=1; LCD_RW=1;
       LCD_EN=0; LCD_EN=1;
      data=P0;
      for(i=1;i<=7;i++) 
           delayNOP();
      LCD_EN=0;
      return data;   

这样,整个代码就全部讲完了,下面是显示正弦波的图片  

 
  • 31
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: STM32F030C8T6微控制器是由ST公司出品的一款高性能、低功耗的微控制器,广泛应用于多种嵌入式系统中。 LCDHT1621是一款常见的驱动LCD显示的芯片,常用于数字时钟、温度计和电压表等设备中。如果要在STM32F030C8T6微控制器上使用LCDHT1621芯片,我们需要编程实现打点函数打点函数是实现数字显示效果的重要函数之一。它可以根据需要在LCD幕上绘制不同的数字,例如时钟的小时数、分钟数等。以下是STM32F030C8T6液晶显示LCDHT1621打点函数的关键代码实现: 1. 首先需要定义一个数组用于保存数字的二进制数据,例如: Uint8 NumCode[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; 这个数组定义了0~9这十个数字的二进制码,可以根据需要自行添加其他数字的码值。 2. 接下来需要编写打点函数。下面是一个基本的打点函数实现: void Write_LCD(Uint8 Data, Uint8 BitCnt) { uint8_t i; for (i=BitCnt; i>0; i–) { SCK_L; if (Data & (1<<(i-1))) SDA_H; else SDA_L; SCK_H; } } 这个函数实现的是向LCDHT1621芯片发送数据的功能。其中,Data代表一个字节长度的数据(例如数字的二进制码),BitCnt是数据的位数。函数中使用了SCK_L、SDA_H和SDA_L等控制信号来实现数据发送功能。 3. 最后,可以在主函数中调用打点函数来实现数字的显示。例如,下面是一个基本的主函数实现: int main(void) { // 初始化LCD幕 LCD_Init(); // 显示数字7 Write_LCD(NumCode[7], 8); // 显示数字3 Write_LCD(NumCode[3], 8); // 显示数字5 Write_LCD(NumCode[5], 8); while(1); } 这个主函数实现了对数字7、3和5的显示效果,数字的显示顺序可以根据需要灵活调整。 总的来说,STM32F030C8T6液晶显示LCDHT1621打点函数是一个比较复杂的功能模块,需要仔细地设计和编程才能实现良好的显示效果。以上关键代码和主函数实现仅供参考,具体的函数实现需要根据具体的应用场景进行调整和扩展。 ### 回答2: STM32F030C8T6是一款基于ARM Cortex-M0内核的微控制器,LCDHT1621是一款数字式液晶显示控制器。在使用STM32F030C8T6驱动LCDHT1621进行液晶显示时,需要使用打点函数来实现。打点函数是指用一个像素点(Dot)代表液晶上的一个显示位,通过一系列打点函数的调用,可以实现字母、数字、符号等字符的显示。 在STM32F030C8T6上使用LCDHT1621液晶显示时,首先需要进行引脚配置,即将控制器的IO口连接至液晶的引脚上。然后需要进行LCDHT1621的初始化操作,包括设置液晶的像素点数、显示模式等。接下来就可以通过打点函数来进行字符的显示了。 例如,若要在液晶显示字符“123”,可以使用以下代码: /* 设置液晶初始状态 */ LCD_Init(); /* 显示字符“1” */ LCD_Dot(0, 0, 1); LCD_Dot(0, 1, 1); LCD_Dot(0, 2, 1); /* 显示字符“2” */ LCD_Dot(1, 0, 1); LCD_Dot(1, 1, 0); LCD_Dot(1, 2, 1); LCD_Dot(1, 3, 1); /* 显示字符“3” */ LCD_Dot(2, 0, 1); LCD_Dot(2, 1, 0); LCD_Dot(2, 2, 1); LCD_Dot(2, 3, 1); 其中,LCD_Init()函数用于初始化LCDHT1621液晶显示控制器,LCD_Dot(x, y, color)函数用于在液晶显示的第x行、第y列处显示一个像素点,color值为1时表示亮点,为0时表示灭点。 通过这样的打点函数,可以实现在液晶显示任意字符的效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值