这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 请教STC8F2K16S2单片机驱动LCD控制器HT1621B老是出现乱码的问题

共5条 1/1 1 跳转至

请教STC8F2K16S2单片机驱动LCD控制器HT1621B老是出现乱码的问题

工程师
2021-07-01 22:29:15     打赏
我用的是STC8F2K16S2单片机
连接液晶显示  SEG9-SEG27    COM0-COM3

#include "STC8F.H"
#include "absacc.h"
#include "intrins.h"
#include "stdio.h"
#define uint unsigned int
#define uchar unsigned char
#define BIAS 0X52 //必须跟硬件电路的COM匹配,1个或者2个COM 0x42  3个COM 0X4A 4个COM 0x52  1/3LCD驱动器偏压 4个公共端口COM
#define RC256 0X30
#define SYSTEN 0x02
#define SYSDIS 0x00
#define LCDON 0X06
void sendbitHT1621(uchar nbit,uchar n);//发送一个字节中的n位到HT1621里,驱动程序的最底层部分
void write_com(uchar cmdcode);//写命令到LCD
void init_lcd();//初始化LCD屏
void seg_display(uchar col,uchar pag);//显示基本单位点
void scerrn_clear();//清空屏幕的内容
void delay();  //5s
//说明:凡是输出IO后缀都是_dr,凡是输入后缀都是_sr
sbit ht162x_data_dr=P0^0;
sbit ht162x_cs_dr=P0^2;
sbit ht162x_wr_dr=P0^3;
void main()
{
  init_lcd();  

}
//发送一个字节中的N位到HT1621里,驱动程序的最底层部分//
void sendbitHT1621(uchar nbit,uchar n)
{
uchar i;
for(i=0;i<n;i++)
{
  ht162x_wr_dr=0;
  if(nbit&0x80) //判断最高位
  {
   ht162x_data_dr=1;
  }
  else
  {
   ht162x_data_dr=0;
  }
  _nop_();
  _nop_();
  _nop_();
  ht162x_wr_dr=1;
  _nop_();
  _nop_();
  _nop_();
  nbit<<=1;   
}
}
//写命令到LCD,驱动液晶程序的一部分//
void write_com(uchar cmdcode)
{
ht162x_cs_dr=0; //选通HT1621
_nop_();
_nop_();
sendbitHT1621(0x80,4);   //写入命令
sendbitHT1621(cmdcode,8);  //写入控制命令
_nop_();
_nop_();
ht162x_cs_dr=1;
_nop_();
_nop_();
_nop_();
}
void init_lcd()
{
ht162x_data_dr=1;
ht162x_cs_dr=1;
ht162x_wr_dr=1;
write_com(SYSTEN); // 打开系统振荡器
write_com(RC256); //启动内部256K RC振荡器
write_com(BIAS);  //1/3LCD驱动器偏压 4个公共端口COM
write_com(LCDON); //开启LCD
}
//核心内容  显示基本单位点,col代表X轴,X轴的数据用位来表示,一个字节中的高4位来表示,pag表示Y轴
void seg_display(uchar col,uchar pag)
{
// pag<<=2;
ht162x_cs_dr=0;
_nop_();
_nop_();
sendbitHT1621(0XA0,3); //发送写数据模式 高位101   101为6 位RAM 地址,
sendbitHT1621(pag<<2,6);  //写入地址数据
sendbitHT1621(col,4);  //写入数据
ht162x_cs_dr=1;
_nop_();
_nop_();
}
//清空屏幕内容
void screen_clrar()
{
uchar i;
uchar y=0;
for(i=0;i<32;i++)
{
  seg_display(0X00,y);
  y=y+1;
}
}

注:这个还有一个毛病就是每次烧完程序之后 要断电很久屏幕才会发生变化,这个也搞不清是什么原因 





关键词: STC8F2K16S2     单片机     HT1621B     L    

工程师
2021-07-01 22:53:58     打赏
2楼

正好我做过,给你一个测试程序参考:

#include <STC89C5xRC.H>

//宏定义新LCD的操作命令

#define ComMode  0x52    //4COM,1/3bias                1000 0101 0010

//#define ComMode  0x50  //4COM,1/2bias          1000 0101 0000

#define RCosc    0x30    //内部RC振荡器(上电默认)1000 0011 0000

#define LCD_on   0x06    //打开LCD显示 偏压发生器1000 0000 0110

#define LCD_off  0x04    //关闭LCD显示(上电默认)

#define Sys_en   0x02    //系统振荡器开 1000 0000 0010

#define Ctrl_cmd 0x80    //写控制命令   1000 

#define Data_cmd 0xa0    //写数据命令   1010 

// 端口声明

sbit DIPIN=P3^7; 

sbit CLKPIN=P3^6; 

sbit CSPIN=P3^5;  


/**-------------------------------------------------------------------------

Name: SendBit_1621(送数据程序)

---------------------------------------------------------------------------*/

void SendBit_1621(unsigned char sdata,unsigned char cnt) //sdata 的高cnt 位写入HT1621,高位在前

{

        unsigned char i;

        for(i=0;i<cnt;i++)

        {

                CLKPIN=0;         

                if(sdata&0x80) 

                        DIPIN=1;

                else DIPIN=0;

                CLKPIN=1;

                sdata<<=1;

        }

}

/*-------------------------------------------------------------------------

Name: SendCmd(送命令)

写入标志码"100"和9位comma命令,由于没有使用到更改时钟输出等命令

为了编程方便直接将command 的最高位写"0"

---------------------------------------------------------------------------*/

void SendCmd_1621(unsigned char command)//写命令

{//3位标志码 + 9位命令,共12位

        CSPIN=0; //执行一个下降沿                                        

        SendBit_1621(0x80,4);    //写入标志码"100"和9位comma命令的最高1位共4位

        SendBit_1621(command,8); //写入9位comma命令的后8位,组成1000 xxxx xxxx

        CSPIN=1;//送数完成后置高电平

}


/**-------------------------------------------------------------------------

Name: Write_1621(送命令和数据程序)

写入标志码"101"和6位addr地址码和8位sdata显示数据。

---------------------------------------------------------------------------*/

void Write_1621(unsigned char addr,unsigned char sdata,unsigned char len)//写数据

{//3位标志码 + 6位写数据命令 + len(4/8)位数据,共13/17位

        addr<<=2;//高6位有效

        CSPIN=0; //执行一个下降沿

        SendBit_1621(0xa0,3);                //写入标志码"101"    写数据命令101

        SendBit_1621(addr,6);                //写入addr 的高6位   写数据命令xxxx xx

        SendBit_1621(sdata,len);        //写入8/4位 sdata数据  len=8/4

        CSPIN=1;//送数完成后置高电平

}

/**-------------------------------------------------------------------------

Name: Init_1621(初始化1621)

-------------------------------------------------------------------------*/

void LCD_Init()                                                //初始化

{//程序输入100 0+8=9位命令

        SendCmd_1621(Sys_en);//Sys_en 0x02 系统振荡器开          100 0 0000 0010

        SendCmd_1621(RCosc); //RCosc 0x30 内部RC振荡器(上电默认) 100 0 0011 0000

        SendCmd_1621(ComMode);//4COM,1/3bias                     100 0 0101 0020

        SendCmd_1621(LCD_on);//LCD_on 0x06 打开LCD显示 偏压发生器100 0 0000 0110

}

/*-------------------------------------------------------------------------

Name: lcdwd1(点亮1621全部Seg)

-------------------------------------------------------------------------*/

void lcdwd1(unsigned char num)

        unsigned char i;

        unsigned char addr=0;//寄存器起始地址0x00

        for(i=0;i<num;i++)//num有效地址数

        {

                Write_1621(addr,0xff,8);//addr为地址,0xff为数据,8为8位数据

                addr+=2;//顺延2个4位地址码

        }

}

void main()

{

        LCD_Init();

        while(1)

        {

                lcdwd1(16); 

        }

}




工程师
2021-07-01 23:11:10     打赏
3楼

换个屏试试以排除硬件故障。


工程师
2021-07-01 23:24:07     打赏
4楼

 我遇到过,后来知道怎么应对各种不同PCB的HT1621了。
1针对不同的HT1621必须确定是2COM、还是4COM,1COM(静态驱动)、3COM的较少。
2、必须确定段码地址,你可以写一个TEST_seg(),扫描各个段,每段停一下并记下地址
3、根据段码编写码表,心里要理清对应的位。
搞清楚上述两点基本就不会乱码了,不是硬件问题,基本是程序问题。 另外2com是一次地址写两段,4com是一次写4段,HT1621每次就是写4个bit的,刚好方便。2com的麻烦一些。


工程师
2021-07-14 23:56:23     打赏
5楼

大家讲的都非常不错的


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]