搜索
bottom↓
回复: 10

大家帮帮忙..HT1621点亮了,控制不了-.-

[复制链接]

出0入0汤圆

发表于 2010-3-14 09:18:03 | 显示全部楼层 |阅读模式
执行完lcd_init()后,就显示了全部字符.清屏也清除不了.
初始化只设置 1/2bias,4comm 和 启动内部振荡器, 不打开显示的话, 上电的一瞬间会有几个笔段亮了,很快又暗了. 内部振荡器不启动的话则不会.
用的是AVR mega 16,11.0592M晶振,-0s优化(用-00的话居然需要占103%的空间.....)
tCLK最大要125us,我延时都设置成200us了啦

#include <avr/io.h>
#include <util/delay.h>
//#include "lcd_code.h"

#define CS_LOW    PORTC &= 0xFE
#define CS_HIGH   PORTC |= 0x01
#define RD_LOW    PORTC &= 0xFD
#define RD_HIGH   PORTC |= 0x02
#define WR_LOW    PORTC &= 0xFB
#define WR_HIGH   PORTC |= 0x04

#define DATA_LOW  PORTC &= 0xF7
#define DATA_HIGH PORTC |= 0x08

//下面是驱动程序定义的一个显示缓冲区,共16个字节,128位
volatile unsigned int lcd_buffer[8]={0,0,0,0,0,0,0,0};

//这个函数可以向HT1621B写入一个命令;用户可能需要在语句间增加必要的延时
void send_lcd_command(unsigned char command)
{
   CS_LOW;
   _delay_us(5);

   WR_LOW;        //PRESENT 100 COMMAND CODE
   DATA_HIGH;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
   
   WR_LOW;
   DATA_LOW;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
     
   WR_LOW;
   DATA_LOW;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
   
   for (unsigned short int i =0;i<=7;i++)
    {
       WR_LOW;
       if ((command & 0x80) !=0) DATA_HIGH; else DATA_LOW;
           _delay_us(200);
       WR_HIGH;
           _delay_us(5);
       command = command << 1;
    }

   WR_LOW;
   _delay_us(200);
   WR_HIGH;
   
   _delay_us(5);
   CS_HIGH;
}

//这个函数可以将显示缓冲区刷新到HT1621B;用户可能需要在语句间增加必要的延时
void flood_lcd_data(void)
{
  unsigned int temp_data;
  CS_LOW;
  _delay_us(5);

   WR_LOW;        //PRESENT 101 DATA CODE
   DATA_HIGH;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
   
   WR_LOW;
   DATA_LOW;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
   
   WR_LOW;
   DATA_HIGH;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);
   
  for (unsigned short int i =0;i<=5;i++)
    {
       WR_LOW;
       DATA_LOW;
           _delay_us(200);
       WR_HIGH;
           _delay_us(5);
    }
   
  for (unsigned short int i =0;i<=7;i++)
    {
      temp_data = lcd_buffer;
      for (unsigned short int j=0;j<=15;j++)
      {
       WR_LOW;
       if ((temp_data & 0x01) !=0) DATA_HIGH; else DATA_LOW;
       _delay_us(200);
       WR_HIGH;
           _delay_us(5);
       temp_data = temp_data >> 1;
      }
    }  

   _delay_us(5);
   CS_HIGH;
}

//初始化HT1621B
void lcd_init(void)
{
   send_lcd_command(0x28); //1/2bias,4comm
   send_lcd_command(0x03); //启动内部振荡器
   send_lcd_command(0x01); //打开显示
}

//清除全部液晶的显示,同时清空显示缓冲区
void lcd_clr()
{
  for (int i=0; i<=7;i++) lcd_buffer=0;
  flood_lcd_data();   
}

int main()
{
    DDRA = 0xff;
    PORTA = 0x00;
    DDRC = 0xFF;
    PORTC = 0xFF;
    lcd_init();
    flood_lcd_data();
        /*
        lcd_clr();
        for(int i=0;i<=127;i++) lcd_char(i,1);
        */
        PORTA = 0xff;
        while (1);
}

出0入0汤圆

发表于 2010-3-14 11:01:07 | 显示全部楼层
几个疑点
1,估计延时程序出问题
  WR_LOW;
   DATA_HIGH;
   _delay_us(200);
   WR_HIGH;
   _delay_us(5);  
改成
   WR_LOW;
   DATA_HIGH;
     WR_HIGH;
   _delay_us(25);  反而更好

2,上拉电阻阻值
3,串在LVCD那里的阻值不适合,对比度没有调好,亮灭状态亮度相差不大。

下面是我在ATmega128 16MHZ 上调试通过的程序(原创是白沙),我用的是四个COM口,及SEG8到SEG20希望对你有用
//=====================================================================
//这里是符号对应的显示顺序,也就对应了在HT1621B数据寄存器内的位置
#define                LCD_COL                        32
#define                LCD_FULL_LIGHT                33
#define                LCD_HALF_LIGHT                34
#define                LCD_OFF_LIGHT                35
#define           LCD_OFF_TXT                 44
#define                LCD_CLOCK                        36
#define                LCD_TIMET                        37
#define                LCD_ALARM_GUI                38
#define                LCD_ALARM_TXT                39

#define                LCD_1A                                40
#define                LCD_1F                                41
#define                LCD_1G                                42
#define                LCD_1E                                43
#define                LCD_1B                                45
#define                LCD_1C                                46
#define                LCD_1D                                47

#define                LCD_2A                                48
#define                LCD_2F                                49
#define                LCD_2G                                50
#define                LCD_2E                                51
#define                LCD_2B                                53
#define                LCD_2C                                54
#define                LCD_2D                                55

#define                LCD_3A                                56
#define                LCD_3F                                57
#define                LCD_3G                                58
#define                LCD_3E                                59
#define                LCD_3B                                61
#define                LCD_3C                                62
#define                LCD_3D                                63

#define                LCD_4A                                64
#define                LCD_4F                                65
#define                LCD_4G                                66
#define                LCD_4E                                67
#define                LCD_4B                                69
#define                LCD_4C                                70
#define                LCD_4D                                71

#define                LCD_V3                                72
#define                LCD_V2                                73
#define                LCD_V1                                74
#define                LCD_VOL                                75
#define                LCD_V4                                76
#define                LCD_V5                                77
#define                LCD_V6                                78
#define                LCD_V7                                79
#define                LCD_BLUE                        80
#define                LCD_V10                                81
#define                LCD_V9                                82
#define                LCD_V8                                83
//硬件接口
#define                DDR_LCD                                DDRA
#define                PORT_LCD                        PORTA
#define                CS_HT1621                        0X00
#define                WR_HT1621                        0X01
#define                DATA_HT1621                        0X02
#define                INTIT_PIN_HT1621        {PORT_LCD&=~BIT(CS_HT1621);PORT_LCD&=~BIT(WR_HT1621);PORT_LCD&=~BIT(DATA_HT1621);}

#define                 CS_LOW                                (DDR_LCD|=BIT(CS_HT1621))
#define         CS_HIGH                                (DDR_LCD&=~BIT(CS_HT1621))

#define         WR_LOW                                (DDR_LCD|=BIT(WR_HT1621))
#define         WR_HIGH                                (DDR_LCD&=~BIT(WR_HT1621))

#define         DATA_LOW                        (DDR_LCD|=BIT(DATA_HT1621))
#define                 DATA_HIGH                        (DDR_LCD&=~BIT(DATA_HT1621))

//下面是驱动程序定义的一个显示缓冲区,共16个字节,128位
unsigned int lcd_buffer[8]={0,0,0,0,0,0,0,0};
//这个函数可以向HT1621B写入一个命令;用户可能需要在语句间增加必要的延时
void send_lcd_command(unsigned char command)
{
   CS_LOW;  
   

   WR_LOW;        //PRESENT 100 COMMAND CODE
   DATA_HIGH;
   WR_HIGH;
   NOP();
   NOP();
   
   WR_LOW;
   DATA_LOW;
   WR_HIGH;
   NOP();
   NOP();

   WR_LOW;
   DATA_LOW;
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   for (unsigned char i =0;i<=7;i++)
    {
       WR_LOW;
       if ((command & 0x80) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       command = command << 1;
    }
   
   WR_LOW;
   NOP();
   NOP();
   NOP();
   NOP();
   WR_HIGH;   
   CS_HIGH;
}

//这个函数可以向HT1621B写入一个数据;用户可能需要在语句间增加必要的延时
void send_lcd_data(unsigned char address,unsigned char data)
{
   CS_LOW;
  
   WR_LOW;        //PRESENT 101 DATA CODE
   DATA_HIGH;  
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   WR_LOW;
   DATA_LOW;
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   WR_LOW;
   DATA_HIGH;
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   address = address << 2;
   for (unsigned char i =0;i<=5;i++)
    {
       WR_LOW;
       if ((address & 0x80) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       address = address << 1;
    }
   
    for (unsigned char i =0;i<=3;i++)
    {
       WR_LOW;
       if ((data & 0x01) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       data = data >> 1;
          
    }  
   
   CS_HIGH;
}
//这个函数可以将显示缓冲区刷新到HT1621B;用户可能需要在语句间增加必要的延时
//刷屏
void flood_lcd_data(void)
{
  unsigned int temp_data;
  unsigned char address = 32;
   CS_LOW;
  
   WR_LOW;        //PRESENT 101 DATA CODE
   DATA_HIGH;
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   WR_LOW;
   DATA_LOW;  
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   
   WR_LOW;
   DATA_HIGH;
   WR_HIGH;
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
  
   
     for (unsigned char i =0;i<=5;i++)
    {
       WR_LOW;
       if ((address & 0x80) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       address = address << 1;
    }
  
   
  for (unsigned char i =2;i<=4;i++)
    {
      temp_data = lcd_buffer;
      for (unsigned char j=0;j<=15;j++)
      {
       WR_LOW;
       if ((temp_data & 0x01) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       temp_data = temp_data >> 1;
          
      }
    }  
       
          temp_data = lcd_buffer[5];
      for (unsigned char j=0;j<=3;j++)
      {
       WR_LOW;
       if ((temp_data & 0x01) !=0) DATA_HIGH;
        else DATA_LOW;
       WR_HIGH;
       temp_data = temp_data >> 1;
          
      }
   
   CS_HIGH;
}

//初始化HT1621B
void lcd_init(void)
{
   send_lcd_command(0x28); //1/2bias,4comm
  
   send_lcd_command(0x03); //启动内部振荡器

   send_lcd_command(0x01); //打开显示

}

//向液晶写一个符号
//name:可直接写0~127的整数,也可以写程序开始定义的标号,如:_lcd_BUSY
//display:符号
void lcd_char(unsigned char name,unsigned char display)
{
  unsigned short int i,j;
  i= name/16;//找到具体字节lcd_buffer[0]、lcd_buffer[1]、.。。。。lcd_buffer[7]
  j= name%16;//具体字节中的位      
  if (display == 1) lcd_buffer |= 1<<j;//点亮具体点比如"v3"
  else lcd_buffer &= ~(1<<j);//关闭具体点
  
}

//清除全部液晶的显示,同时清空显示缓冲区
void lcd_clr(void)
{
  for (int i=2; i<=5;i++) lcd_buffer=0X0000;
  flood_lcd_data();   
   
}

//向液晶的数位处写一个0~9的数  
//数位为大数码的左至右为0~5,小数码的右至左为6~9;
//number:想显示的数 0~9
//position:显示的数位
//display:显示开关,0 关闭该数位显示(此时number值无效),1 显示该数位数字
void lcd_number(unsigned char number,unsigned  char position,unsigned char display)
{
  switch (position)
  {
    case 0:
    {
                if (display == 0)
                {
                  lcd_buffer[2] &= 0x10ff;
                }
                else
                {
                   lcd_buffer[2] &= 0x10ff;
                  switch (number)
                  {
                        case 0:lcd_buffer[2] |= 0xEB00;
                          break;
                        case 1:lcd_buffer[2] |= 0x6000;
                          break;
                        case 2:lcd_buffer[2] |= 0xAD00;
                          break;
                        case 3:lcd_buffer[2] |= 0xE500;
                          break;
                        case 4:lcd_buffer[2] |= 0x6600;
                          break;
                        case 5:lcd_buffer[2] |= 0xC700;
                          break;
                        case 6:lcd_buffer[2] |= 0xCF00;
                          break;
                        case 7:lcd_buffer[2] |= 0x6100;
                          break;
                        case 8:lcd_buffer[2] |= 0xFF00;
                          break;
                        case 9:lcd_buffer[2] |= 0xE700;
                          break;      
                  }
                }
                break;
    }
    case 1:
    {
                if (display == 0)
                {
                  lcd_buffer[3] &= 0xff00;
                }
       else
       {
          lcd_buffer[3] &= 0xff00;
                  switch (number)
                  {
                        case 0:lcd_buffer[3] |= 0x00EB;
                          break;
                        case 1:lcd_buffer[3] |= 0x0060;
                          break;
                        case 2:lcd_buffer[3] |= 0x00AD;
                          break;
                        case 3:lcd_buffer[3] |= 0x00E5;
                          break;
                        case 4:lcd_buffer[3] |= 0x0066;
                          break;
                        case 5:lcd_buffer[3] |= 0x00C7;
                          break;
                        case 6:lcd_buffer[3] |= 0x00CF;
                          break;
                        case 7:lcd_buffer[3] |= 0x0061;
                          break;
                        case 8:lcd_buffer[3] |= 0x00FF;
                          break;
                        case 9:lcd_buffer[3] |= 0x00E7;
                          break;      
                  }
          
           }
      break;
    }
    case 2:
        {
      lcd_buffer[3] &= 0x00ff;
      if (display == 0) break;
      else
          {
              switch (number)
                  {
                        case 0:lcd_buffer[3] |= 0xEB00;
                          break;
                        case 1:lcd_buffer[3] |= 0x6000;
                          break;
                        case 2:lcd_buffer[3] |= 0xAD00;
                          break;
                        case 3:lcd_buffer[3] |= 0xE500;
                          break;
                        case 4:lcd_buffer[3] |= 0x6600;
                          break;
                        case 5:lcd_buffer[3] |= 0xC700;
                          break;
                        case 6:lcd_buffer[3] |= 0xCF00;
                          break;
                        case 7:lcd_buffer[3] |= 0x6100;
                          break;
                        case 8:lcd_buffer[3] |= 0xFF00;
                          break;
                        case 9:lcd_buffer[3] |= 0xE700;
                          break;           
          }
          }
      break;
        }
    case 3:
        {
                lcd_buffer[4] &= 0xFF00;
                if (display == 0) break;
        else
                {
           switch (number)
           {
                        case 0:lcd_buffer[4] |= 0x00EB;
                          break;
                        case 1:lcd_buffer[4] |= 0x0060;
                          break;
                        case 2:lcd_buffer[4] |= 0x00AD;
                          break;
                        case 3:lcd_buffer[4] |= 0x00E5;
                          break;
                        case 4:lcd_buffer[4] |= 0x0066;
                          break;
                        case 5:lcd_buffer[4] |= 0x00C7;
                          break;
                        case 6:lcd_buffer[4] |= 0x00CF;
                          break;
                        case 7:lcd_buffer[4] |= 0x0061;
                          break;
                        case 8:lcd_buffer[4] |= 0x00FF;
                          break;
                        case 9:lcd_buffer[4] |= 0x00E7;
                          break;         
           }
                }
        break;
        }
   
  }   
}



void LCD_Vlume(unsigned char temp )
{
   
    lcd_buffer[4] &= 0x08FF;
        lcd_buffer[5] &= 0x0001;
        switch (temp)
           {
               
                case 1:lcd_buffer[4] |= 0x0C00;
                  break;
                case 2:lcd_buffer[4] |= 0x0E00;
                  break;
                case 3:lcd_buffer[4] |= 0x0F00;
                  break;
                case 4:lcd_buffer[4] |= 0x1F00;
                  break;
                case 5:lcd_buffer[4] |= 0x3F00;
                  break;
                case 6:lcd_buffer[4] |= 0x7F00;
                  break;
                case 7:lcd_buffer[4] |= 0xFF00;
                  break;
                case 8:lcd_buffer[4] |= 0xFF00,lcd_buffer[5]|=0X0008;
                  break;
                case 9:lcd_buffer[4] |= 0xFF00;lcd_buffer[5]|=0X000C;
                  break;
                case 10:lcd_buffer[4] |= 0xFF00;lcd_buffer[5]|=0X000E;
                  break;      
        default:break;   
           }
}

void LCD_Light_Off(void)
{
   lcd_buffer[2] &= 0xEFF1;
   lcd_buffer[2] |=0X1008 ;
}

void LCD_Light_Half(void)
{
   lcd_buffer[2] &= 0xEFF1;
   lcd_buffer[2] |=0X0004;  
}

void LCD_Light_Full(void)
{
   lcd_buffer[2] &= 0xEFF1;
   lcd_buffer[2] |=0X0002;  
}

void LCD_Alarm_On(void)
{
   lcd_buffer[2] |=0X00C0;  
}

void LCD_Alarm_Off(void)
{
   lcd_buffer[2] &= 0xFF3F;
}

void LCD_Time_On(void)
{

   lcd_buffer[2] |=0X0030 ;
}

void LCD_Time_Off(void)
{

   lcd_buffer[2] &=0Xffcf ;
}

出0入0汤圆

发表于 2010-3-14 11:05:54 | 显示全部楼层
烂手机拍的效果很差

(原文件名:moto_0112.jpg)

出0入0汤圆

 楼主| 发表于 2010-3-14 11:26:53 | 显示全部楼层
【1楼】 guihong
1, 改为
   WR_LOW;
   DATA_LOW;
   WR_HIGH;
   _delay_us(25);
没能解决
2,上拉电阻阻值
datasheet上说的"接一上拉电阻"居然是外部接啊...  我还以为是内部上拉呢..  不过MCU推挽输出,不接上拉也可以的吧?
3, 我按白沙所说,VLCD和VDD短路(16 17脚)  突然发现,zlg的中文HT1621的ssop引脚图和白沙的英文1621引脚图不同!! 还我之前看的英文引脚图, 一看那个错的引脚图就觉得怪怪的

出0入0汤圆

发表于 2010-3-14 11:45:24 | 显示全部楼层
【1楼】 guihong  
1, 改为
   WR_LOW;
   DATA_LOW;
   WR_HIGH;
   _delay_us(25);
没能解决
===========================
看来我没有说明白,我的意思是
   WR_LOW;
   DATA_LOW; ----------------------------------这里可以不用加延时(至少我的板上可以)
   WR_HIGH;
   _delay_us(25); -----------------------------这里的延时要适合
=============================================
不过MCU推挽输出,不接上拉可以的吧?--------------------如果是像我这样写就不可以因为IO口要不断的转换输入输出方向,你那种写法我没有试过。
==========================================
VLCD和VDD短路(16 17脚) 短了就是亮灭状态的亮度几乎一样

出0入0汤圆

 楼主| 发表于 2010-3-14 11:55:22 | 显示全部楼层
我接上上拉试一试
白沙的LCD支持包里的"LCD介绍.pdf"说"偏压电阻可直接短接并获得清晰的显示效果"

出0入0汤圆

 楼主| 发表于 2010-3-14 12:03:40 | 显示全部楼层
上拉不试了, guihong用的是开漏输出,当然要上拉...

出0入0汤圆

 楼主| 发表于 2010-3-14 15:25:54 | 显示全部楼层
问题已经解决, VLCD 改为串一个30k电阻到vdd,没问题了 (5V)
看来白沙用的3.3V, VLCD短路没什么问题...

出0入0汤圆

发表于 2010-3-14 16:30:04 | 显示全部楼层
恭喜,哈哈下次记得好好看数据手册,这个在数据手册是写有的。

出0入0汤圆

发表于 2010-8-5 16:44:20 | 显示全部楼层
回复【1楼】guihong
-----------------------------------------------------------------------

内部寄存器是怎么定义的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2022-6-27 22:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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