求帮忙!12864动态显示按键按下次数的问题,就是按几下按键液晶会显示数字,自己的程序,但是就是液晶不变

2019-07-15 15:37发布

JLX12864G-086-PC的中文字库编程说明书.pdf (1.03 MB, 下载次数: 10)

#include <reg52.H>
#include <intrins.h>     
#include <Ctype.h>
#include<stdio.h>
sbit key=P2^0;      
sbit cs1=P1^1;
sbit reset=P1^0;     
sbit rs=P3^0;
sbit sclk=P3^1;      
sbit sid=P3^2;
sbit Rom_IN=P1^2;    //字库IC 接口定义:Rom_IN 就是字库IC 的SI
sbit Rom_OUT=P1^3;   //字库IC 接口定义:Rom_OUT就是字库IC 的SO
sbit Rom_SCK=P1^4;   //字库IC 接口定义:Rom_SCK就是字库IC 的SCK
sbit Rom_CS=P1^5;    //字库IC接口定义Rom_CS就是字库IC的CS#
sbit add=P2^1;
#define uchar unsigned char   
#define uint unsigned int
#define ulong unsigned long
char xianshi[5];

int p;/*记录按键次数的变量*/

void delay_us(int i)
{
    int j,k;
    for(j=0;j<i;j++)
    for(k=0;k<1;k++);
}
void delay(int i)
{
   int j,k;
   for(j=0;j<i;j++)
    for(k=0;k<110;k++);
}
void transfer_command(int data1) /*写指令*/  
{
        char i;
        cs1=0;
        rs=0;
        for(i=0;i<8;i++)
        {
                sclk=0;
        delay_us(2);
                if(data1&0x80) sid=1;
                else sid=0;
                sclk=1;
        delay_us(2);
                data1=data1<<=1;
        }
        cs1=1;
}
void transfer_data_lcd(int data1)/*写数据*/
{
        char i;
        cs1=0;
        rs=1;
        for(i=0;i<8;i++)
        {
                sclk=0;
        delay_us(1);
                if(data1&0x80) sid=1;
                else sid=0;
                sclk=1;
        delay_us(1);
                data1=data1<<=1;
        }
        cs1=1;
}
void initial_lcd()/*液晶屏初始化*/
{
        //cs1=0;
        reset=0;                //低电平复位
        delay(100);
        reset=1;                    //复位完毕
        delay(100);        
        transfer_command(0xe2);         //软复位
        delay(5);
        transfer_command(0x2c);  //升压步聚1
        delay(5);       
        transfer_command(0x2e);  //升压步聚2
        delay(5);
        transfer_command(0x2f);  //升压步聚3
        delay(5);
        transfer_command(0x24);  //粗调对比度,可设置范围0x20~0x27
        transfer_command(0x81);  //微调对比度
        transfer_command(0x1f);  //0x1a,微调对比度的值,可设置范围0x00~0x3f 与上一条是双指令上一条的0x81不动,下面的才是值
        transfer_command(0xa2);  //1/7偏压比(bias)一般不改0xa2是1/9
        transfer_command(0xc8);  //行扫描顺序:从上到下
        transfer_command(0xa0);  //列扫描顺序:从左到右
        transfer_command(0x40);  //起始行:第一行开始
        transfer_command(0xaf);  //开显示       

}
void lcd_address(uchar page,uchar column) /*显示位置,行和列的设置*/
{
column=column-1;         //我们平常所说的第 1 列,在 LCD 驱动 IC 里是第 0 列。所以在这里减去 1.
page=page-1;
transfer_command(0xb0+page);   //设置页地址。每页是 8 行。一个画面的 64 行被分成 8 个页。我们平常所说的第 1 页,在 LCD 驱动 IC 里是第 0 页,所以在这里减去1*/
transfer_command(((column>>4)&0x0f)+0x10); //设置列地址的高4 位
transfer_command(column&0x0f);    //设置列地址的低4 位
}
/*全屏清屏*/
void clear_screen()
{
unsigned char i,j;
  for(i=0;i<9;i++)
{
  lcd_address(1+i,1);
  for(j=0;j<132;j++)
{
transfer_data_lcd(0x00);

  }
}
}

//送指令到晶联讯字库IC
void send_command_to_ROM( uchar datu )
{
uchar i;
for(i=0;i<8;i++ )
{
  Rom_SCK=0;
  delay_us(10);
  if(datu&0x80)Rom_IN = 1;
  else Rom_IN = 0;
  datu = datu<<1;
  Rom_SCK=1;
  delay_us(10);
}
}

//从晶联讯字库IC 中取汉字或字符数据(1 个字节)
static uchar get_data_from_ROM( )
{
uchar i;
uchar ret_data=0;
for(i=0;i<8;i++)
{
  Rom_OUT=1;
  Rom_SCK=0;
  //delay_us(1);
  ret_data=ret_data<<1;
  if( Rom_OUT )
   ret_data=ret_data+1;
  else
   ret_data=ret_data+0;
  Rom_SCK=1;
  //delay_us(1);
}
return(ret_data);
}


//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_16x16(ulong fontaddr,uchar page,uchar column)
{
uchar i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16);  //地址的高8 位,共24 位
send_command_to_ROM((fontaddr&0xff00)>>8);   //地址的中8 位,共24 位
send_command_to_ROM(fontaddr&0xff);     //地址的低8 位,共24 位
for(j=0;j<2;j++)
{
  lcd_address(page+j,column);
  for(i=0; i<16; i++ )
     {
   disp_data=get_data_from_ROM();
   transfer_data_lcd(disp_data); //写数据到LCD,每写完1 字节的数据后列地址自动加1
  }
}
Rom_CS=1;
}

void get_and_write_8x16(ulong fontaddr,uchar page,uchar column)
{
uchar i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16);  //地址的高8 位,共24 位
send_command_to_ROM((fontaddr&0xff00)>>8);   //地址的中8 位,共24 位
send_command_to_ROM(fontaddr&0xff);     //地址的低8 位,共24 位
for(j=0;j<2;j++)
{
  lcd_address(page+j,column);
  for(i=0; i<8; i++ )
     {
   disp_data=get_data_from_ROM();
   transfer_data_lcd(disp_data); //写数据到LCD,每写完1 字节的数据后列地址自动加1
  }
}
Rom_CS=1;
}

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


ulong  fontaddr=0;
void display_GB2312_string(uchar page,uchar column,uchar *text)
{  
uchar i= 0;     
while((text>0x00))
{
  if(((text>=0xb0) &&(text<=0xf7))&&(text[i+1]>=0xa1))
  {      
   //国标简体(GB2312)汉字在晶联讯字库IC 中的地址由以下公式来计算:
   //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
   //由于担心8 位单片机有乘法溢出问题,所以分三部取地址
   fontaddr = (text- 0xb0)*94;  
   fontaddr += (text[i+1]-0xa1)+846;
   fontaddr = (ulong)(fontaddr*32);
   get_and_write_16x16(fontaddr,page,column);  //从指定地址读出数据写到液晶屏指定(page,column)座标中
   i+=2;
   column+=16;
  }
  else if(((text>=0xa1) &&(text<=0xa3))&&(text[i+1]>=0xa1))
  {      
   //国标简体(GB2312)15x16 点的字符在晶联讯字库IC 中的地址由以下公式来计算:
   //Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0
   //由于担心8 位单片机有乘法溢出问题,所以分三部取地址
   fontaddr = (text- 0xa1)*94;  
   fontaddr += (text[i+1]-0xa1);
   fontaddr = (ulong)(fontaddr*32);

   get_and_write_16x16(fontaddr,page,column);  //从指定地址读出数据写到液晶屏指定(page,column)座标中
   i+=2;
   column+=16;
  }
  else if((text>=0x20) &&(text<=0x7e))  
  {         
   fontaddr = (text- 0x20);
   fontaddr = (unsigned long)(fontaddr*16);
   fontaddr = (unsigned long)(fontaddr+0x3cf80);   

   get_and_write_8x16(fontaddr,page,column);  //从指定地址读出数据写到液晶屏指定(page,column)座标中
   i+=1;
   column+=8;
  }
  else
   i++;  
}

}

void key_add(void)/*按键加*/
{

  int H, M, S, W;

  if(add==0)
  {
     delay(10);/*延时去抖*/
         if(add==0)
         {
            while(!add);
       
                p++;
                delay(10);

         }
  }

        H=((p/1000)%10);
        M=(p/100)%10;
        S=(p/10)%10;
        W=(p%10);
        sprintf(&xianshi, "%d%d%d%d", H, M, S,W);             // 将整数转换成字符串
                       
}
void timer0_chushihua()/*定时器初始化*/
{
        TMOD=0x01;
        TH0=0x00;
        TL0=0x00;
        EA=1;
        ET0=1;
        TR0=1;
}
void timer0() interrupt 1
{          

       TH0=(65536-45536)/256;/*设定定时器初始值,定时20ms*/
       TL0=(65536-45536)%256;
        display_GB2312_string(7,33,xianshi);/*显示按键按过的次数*/
        display_GB2312_string(5,1,"∑  000000");/*显示固定字符和数字*/
        display_GB2312_string(1,1,"dshyhuf");/*显示固定字母*/
                               
}
void main(void)
{
      initial_lcd();/*液晶屏初始化*/
      clear_screen();/*液晶屏清屏*/
      timer0_chushihua();         
     while(1)
    {             
        key_add();

     }
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
10条回答
andy_wsj
2019-07-15 19:15
本帖最后由 andy_wsj 于 2015-11-16 09:30 编辑

void timer0() interrupt 1
{           

        TH0=(65536-45536)/256;/*设定定时器初始值,定时20ms*/
        TL0=(65536-45536)%256;
         display_GB2312_string(7,33,xianshi);/*显示按键按过的次数*/
         display_GB2312_string(5,1,"∑  000000");/*显示固定字符和数字*/
         display_GB2312_string(1,1,"dshyhuf");/*显示固定字母*/
                                 
}

display_GB2312_string不用放到中断里面吧?放在主循环就可以了
中断用一个变量计时,时间到了主循环就刷新显示
反而是按键扫描可以放到中断里面来



最佳答案

一周热门 更多>