⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1620.c

📁 串行数码管驱动集成芯片MAX7219的驱动和LCD12864液晶驱动
💻 C
字号:


/*****************************************************

TS1620-1的控制器为HD47780,其引脚功能如下:
Pin  1    2    3     4   5    6   7~17      15     16
功能 GND VDD   VO   RS   RW   E   DB0~7     BL+    BL-
说明:
1 GND:电源地。
2 VDD:电源正 +5V DC。
3 VO:LCD偏压信号,用来对调整对比度,一般接10K电位器/电阻到地。
4 RS:数据/命令选择,用来选择DB0~7输入的是显示数据还是控制字信息
5 RW:读写选择.
6 E: 使能端,控制DB0~7的数据/命令的写入或者读取,上升或下降沿有效。
7-14 DB0~7:数据I/O,可选择8位数据或者4位数据(分两次传输)。
15 BL+:背光电源正输入 +5V DV。
16 BL-:背光电源地。

*连线图:
* DB0---DPROT.0 DB4---DPROT.4 RS-------------P2.5
* DB1---DPROT.1 DB5---DPROT.5 RW-------------P2.6
* DB2---DPROT.2 DB6---DPROT.6 E--------------P2.7
* DB3---DPROT.3 DB7---DPROT.7 VLCD 接10K 可调电阻到GND*

1基本操作时序:
1.1读状态:输入:RS=L, RW=H, E=H                     输出:D0~D7=状态字
1.2写指令:输入:RS=L, RW=L, D0~D7=指令码,E=高脉冲  输出:无
1.3读数据:输入:RS=H, RW=H, E=H                     输出:D0~D7=数据
1.4写数据:输入:RS=H, RW=L, D0~D7=数据,E=高脉冲    输出:无

2基本指令:
指令及编码        功能  
           01H    显示清屏: 1.数据指针清零2.所有显示清零
           02H    显示回车: 1.数据指针清零
0011 1000  38H	  显示模式设置: 16X2显示,5X7点阵,8位数据接口

3显示开/关及光标设置指令
指令及编码        功能
000001 NS         N=1当读或写一个字符后地址指针加一,且光标加一
                  N=0当读或写一个字符后地址指针减一,且光标减一
                  S=1当写一个字符,整屏显示左移((N=1)或右移(N=0)
                  S=0当写一个字符,整屏显示不移动 
000001 00  04H    当写一个字符后光标减一,整屏显示不移动
000001 01  05H    当写一个字符,整屏显示右移
000001 10  06H    当写一个字符后光标加一, 整屏显示不移动
000001 11  07H    当写一个字符,整屏显示左移

00001 DCB          D=1开显示;  D=0关显示
                   C=1显示光标;C=0不显示光标
                   B=1光标闪烁;B=0光标不闪烁            
00001 000  08H    关显示; 不显光标; 光标不闪
00001 001  09H    关显示; 不显光标; 光标闪烁
00001 010  0AH    关显示; 显示光标; 光标不闪
00001 011  0BH    关显示; 显示光标; 光标闪烁
00001 100  0CH    开显示; 不显光标; 光标不闪
00001 101  0DH    开显示; 不显光标; 光标闪烁
00001 110  0EH    开显示; 显示光标; 光标不闪
00001 111  0FH    开显示; 显示光标; 光标闪烁 
 
1xxxx xxx  80H+ 地址码  设置数据地址指针
           0-27H        第一行
           40H-67H      第二行
**************************************************************/


/***********************************************
.modle name:        头文件包含
.description:
************************************************/
#include<reg51.h>
#include<absacc.h>
#include <intrins.h>

/***********************************************
.modle name:       macros
.description:      宏定义
************************************************/
#define DPORT P0

/***********************************************
.modle name:        函数原型声明
.description:
************************************************/
unsigned Xpos; //列方向地址指针
unsigned Ypos; //行方向地址指针
void LcdWcn(unsigned);
void LcdWc(unsigned);
void WriteChar(unsigned);
void LcdPos();
void LcdWd(unsigned);
void LcdWdn(unsigned);
void posclear(unsigned char Xpos1);
void mDelay(unsigned long Delay);

/***********************************************
.modle name:        变量定义
.description:
************************************************/
sbit RS = P2^5;
sbit RW = P2^6;
sbit E  = P2^7;
sbit BacklightP  = P3^0;
sbit BacklightN  = P3^1;
unsigned char TimerReg;
unsigned char Second;//秒
unsigned char Minute;//分
unsigned char Hour;  //小时
unsigned int dischar[]={'0','1','2','3','4','5','6','7','8','9'};

/***********************************************
.modle name:        函数定义
.description:
************************************************/


/***********************************************
.modle name:  mDelay     
.description: 延迟函数
************************************************/
void mDelay(unsigned long Delay)
{ 
 int i;
 for(;Delay>0;Delay--)
 { 
  for(i=100;i>0;i--)
  {;}
 }
}

/***********************************************
.modle name:  WriteChar   
.description: 在指定的行与列显示,不会自动右移
              需要自动右移显示用 LcdWd()

************************************************/

void WriteChar(unsigned c)
{ 
 LcdPos();//位置调整,目的是超过十时显示位置变化
 LcdWd(c);
}

/***********************************************
.modle name:  WaitIdle
.description: 正常读写操作之前检测LCD控制器是否忙,
              确保STA7==0.
************************************************/

void WaitIdle()
{ 
 unsigned tmp;
 DPORT=0xff;//每次检测状态时都初始化为高电平,如下时序分析。
 /*         1      2        3        4
 DPORT^7 _______       ___________         ________  
                |      |         |         |      |         
       0 ----------------------------------------------------
                |      |         |         |      |
 BF      ______________                    ________
                |      |         |         |      |
       0 -----------------------------------------------------
                |      |         |         |      |
 temp    _______                           ________
                |      |         |         |                                 
       0 -----------------------------------------------------
  
  。必须DPORT^7为高时,temp 才能反应BF的真实状态(组合1和3)*/

 RS=0;//command
 RW=1;//read         
 E=1;//Enable  BF此时才出现到总线。
 _nop_();

 for(;;)//循环:等到BF==0为止
 { 
  tmp=DPORT;//读取BF
  tmp&=0x80;//最高位为BF
  if(tmp==0)//BF为低电平时,允许进行操作,并跳出循环
   break;
 }

 E=0;//关闭, 以后每次读写都要设置为允许
}

/***********************************************
.modle name:  LcdWdn
.description:不检测忙的写数据子程序
************************************************/
void LcdWdn(unsigned c)
{
 RS=1;//data 
 RW=0;//write
 DPORT=c; //写入待写字符
 E=1;//使能
 _nop_();//wait
 E=0;
}

/***********************************************
.modle name:  LcdWd
.description: 带忙检测的写数据子程序

************************************************/

void LcdWd(unsigned c)
{ 
 WaitIdle();
 LcdWdn(c);
}

/***********************************************
.modle name:  LcdWcn
.description: 不检测忙信号的写命令控制字子程序
              初始化重复写入38H时不需检测忙信号
************************************************/
void LcdWcn(unsigned c)
{ 
 RS=0;//select command register
 RW=0;//write
 DPORT=c;//command 
 mDelay(10);
 E=1;//ennable 
 _nop_();//wait
 E=0;
}

/***********************************************
.modle name:  LcdWc
.description: 检测忙信号的写命令控制字子程序

************************************************/
void LcdWc(unsigned c)
{ 
 WaitIdle();
 LcdWcn(c);
}

/***********************************************
.modle name:  LcdPos
.description:  显示屏定位
               由行列计算内部地址

************************************************/

void LcdPos()
{ 
 unsigned tmp;
 Xpos&=0x0f; //列范围0~15
 Ypos&=0x01; //行范围是0~1

 tmp=Xpos; 
 if(Ypos==1)//第一行
 { 
  tmp+=0x40;
 }
 tmp|=0x80;//第二行
 LcdWc(tmp);//设置数据地址
}

/***********************************************
.modle name:  RstLcd
.description: ts1620-1 LCD 的复位程序

初始化过程(复位过程)
. 1  延时15ms
. 2  写指令38H(不检测忙信号)
. 3  延时5ms
. 4  写指令38H(不检测忙信号)
. 5  延时5ms
. 6  写指令38H(不检测忙信号)
. 7  (以后每次写指令、读/写数据操作之前均需检测忙信号)
. 8  写指令38H:显示模式设置
. 9  写指令08H:显示关闭
. 10 写指令01H:显示清屏
. 11 写指令06H:显示光标移动设置
. 12 写指令0FH/OCH:显示开及光标设置
************************************************/


void RstLcd()
{ 
 mDelay(10); //延时等待系统稳定
 LcdWcn(0x38);//重复写入 
 mDelay(10);//延时1s
 LcdWcn(0x38);
 mDelay(10);//延时1s
 LcdWcn(0x38);
 mDelay(10);//延时1s

 LcdWc(0x38);//显示模式设置:8位2行5x7点阵
 mDelay(10);//延时10s

 LcdWc(0x08);//显示关闭
 mDelay(1);//延时10s

 LcdWc(0x01);//显示清屏
 mDelay(1);//延时10s

 LcdWc(0x06);//显示光标移动设置(加一)
 mDelay(1);//延时10s

 LcdWc(0x0c);//显示开关及光标设置(不显示光标)
 mDelay(1);//延时10s
} 

/***********************************************
.modle name:  Disp 
.description: 在指定位置显示
************************************************/

void Disp (unsigned char time,unsigned char Xpos1)
{
 unsigned int ten=0;
 unsigned int gw=0;
 if (time<10)
 {
  Xpos=Xpos1;
  WriteChar('0');//在指定行列显示 
  LcdWd(dischar[time]);//带忙检测的写字符子程序
 }
 else
 {
  ten=time/10;   //取十位数
  gw=time-ten*10;//取个位数
  Xpos=Xpos1;
  WriteChar(dischar[ten]);//在指定行列显示过10时
                          //在该位置显示十位  
  LcdWd(dischar[gw]);     //地址自动增一 
 }
}

/***********************************************
.modle name:  posclear 
.description: 擦除指定位置
************************************************/
void posclear(unsigned char Xpos1)
{
  Xpos=Xpos1;
  WriteChar(' ');//在指定行列显示
  LcdWd(' ');//带忙检测的写字符子程序
}

/***********************************************
.modle name:  Timer0 interrupt 
.description: Timer0 ISR
************************************************/
void Timer() interrupt 1 //定时器0 中断子程序
{
 TH0=0x4c;
 TL0=0x26;//0.625/20=0.03125    49.99-0.03125=49.95875
 
 TimerReg++; 
 if (TimerReg==20)//1秒钟
 {
  TimerReg=0;//复位
  Second++;
  if (Second==60) //1分钟
  {
   Second=0;
   Minute++;
      
   if (Minute==60) //1小时
   {
    Minute=0;
    Hour++;
    if (Hour==24)//1天
    {
     Hour=0;
    }
   }
  }
 }

  /*小时显示刷新*/
  Disp(Hour,2);
   /*分显示刷新*/
  Disp(Minute,5); 
  /*秒显示刷新*/
  Disp(Second,8);
}


/***********************************************
.modle name:  main
.description: 主函数
************************************************/

void main()
{

do{
 LcdWcn(~1);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~2);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~4);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~8);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~16);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~32);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~64);//重复写入 
 mDelay(50);//延时1s
 LcdWcn(~128);//重复写入 
 mDelay(50);//延时1s
}while(1);

 /*
 TimerReg=0;
 Second=0;//秒 初始化
 Minute=0;//分 初始化
 Hour=0;  //小时 初始化
 

 //定时器初始化
 TMOD=0x21;//TMOD定时器工作方式寄存器,0x21设定为T1为方式2 T0为方式1
 TH0=0x4c; TL0=0x00; //定时器初值:50ms定时
 //TH1=0xfd; TL1=0xfd; //产生9600bps波特率,SMOD为0;
 //TR1=1;//起动定时器1
 
 TR0=1;//起动定时器0
 //中断
 ET0=1;//允许定 时器0 中断,
 //IT1=1;//允许 外部中断1
 EA=1;//总中断允许控制位,开放所有中断

BacklightP=1;
BacklightN=0;
RstLcd();   //复位LCD
LcdWc(0x01);//清屏
 
 Ypos=0;
 Xpos=4;
 WriteChar(':');
 Xpos=7;
 WriteChar(':');
  
  Disp(19,2);//小时显示刷新
 
  Disp(18,5);//*分显示刷新
  
  Disp(15,8);//秒显示刷新
  Ypos=1;
  Xpos=2;
  WriteChar('I');
  LcdWd(' ');
  LcdWd('L');
  LcdWd('O');
  LcdWd('V');
  LcdWd('E');
  LcdWd(' ');
  LcdWd('Y');
  LcdWd('O');
  LcdWd('U');
  LcdWd('!');
*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -