关于12864屏幕

2019-03-23 18:35发布

我用的是stm8单片机,不知道为什么现在就是不能画任意点,要么是没有显示要么是乱码。我想估计是读写程序出现了问题,


uchar readdat(void)

{

        uchar Rdata;

        Check12864state();

        PB_ODR=0xff;

        LCD_RS = 1;

        LCD_RW = 1;

  LCD_EN = 0;

        delayNOP();

        LCD_EN = 1;

        delayNOP();

        PB_DDR= 0x00;

        PB_CR1 = 0x00;

        Rdata=PB_IDR;

        LCD_EN = 0;

        delayNOP();

        return Rdata;

}


能帮我看一下有什么问题吗?谢谢。
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
jishuaihu
1楼-- · 2019-03-24 02:27
/ 我估计也是。估计是你读的数据和写进去的数据位置不一样。先试试画8bit的线试试
d907814868
2楼-- · 2019-03-24 06:57
 精彩回答 2  元偷偷看……
d907814868
3楼-- · 2019-03-24 11:00
d907814868 发表于 2015-5-28 22:50
这个“读的数据和写进的数据位置不一样”是怎么回事?我是菜鸟不太懂。

那么这个读操作程序没问题?
jplzl10000
4楼-- · 2019-03-24 11:05
显示乱码,起码是有显示了,一般就是你写入的地址和数据,与屏本身的显示RAM排列不一致。
比如说,你自己的字模是 先取完一行,再取下行,即一个字节8bit是按行排列的。
但可能屏显示要求的是,先取一列,再取下一列,即一个字节8bit是按列排列的。
这样就会导致显示乱码。一般有显示了的话,读取操作就不会有什么问题了
只是字模的规划错了
huaiqiao
5楼-- · 2019-03-24 15:25
 精彩回答 2  元偷偷看……
d907814868
6楼-- · 2019-03-24 18:46
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
//#include"stm8s.h"
#include"stm8s105s4.h"
#include"stdio.h"
#define uchar unsigned char
#define uint unsigned int
_Bool   LCD_RS  @PC_ODR:2;
_Bool   LCD_RW  @PC_ODR:3;
_Bool   LCD_EN  @PE_ODR:6;
_Bool   LCD_PSB  @PC_ODR:1;
_Bool   LCD_RST  @PE_ODR:5;
_Bool   DOT    @PC_ODR:1;
void delayNOP(void)
{_asm("nop");_asm("nop");_asm("nop");_asm("nop");_asm("nop");}
void delaynms(unsigned int di) //延时
{
unsigned int da,db;
for(da=0;da<di;da++)
   for(db=0;db<10;db++);
}
void GPIO_Init1(void)
{
        PB_DDR= 0xff;
        PB_CR1 = 0xff;
        PC_DDR= 0x0e;
        PC_CR1 = 0x0e;
        PE_DDR= 0x60;
        PE_CR1 = 0x60;

}
void delay(int ms)
{
    while(ms--)
        {
      uchar i;
          for(i=0;i<250;i++);
          
        }
}               
void delay0(uchar x)    //x*0.14MS
{
  uchar i;
  while(x--)
{
  for (i = 0; i<113; i++);
}
}
//12864检查状态
void Check12864state(void)
{
        PB_ODR=0xff;
        LCD_EN = 0;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_EN = 1;
        while((PB_IDR&0x80)==0x80);//等待空闲
        LCD_EN = 0;
        LCD_RS = 1;
        LCD_RW = 0;
}
void lcd_wdat(const uchar dat)
{                          
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    PB_ODR= dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
                        delay(100);
}
void lcd_wcmd(const uchar cmd)
{                          
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;

    _asm("nop");
    _asm("nop");
    PB_ODR  = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
                delay(100);
}
void lcd_pos(uchar X,uchar Y)
{                          
   uchar  pos;
   if (X==0)
     {X=0x80;}
   else if (X==1)
     {X=0x90;}
   else if (X==2)
     {X=0x88;}
   else if (X==3)
     {X=0x98;}
   pos = X+Y ;  
   lcd_wcmd(pos);     //显示地址
}

void lcd_init(void)
{

    LCD_PSB = 1;         //并口方式
    LCD_RST=1;
                LCD_RST=0;
                LCD_RST=1;
    lcd_wcmd(0x34);      //扩充指令操作
    delay(5);
    lcd_wcmd(0x30);      //基本指令操作
    delay(5);
    lcd_wcmd(0x0C);      //显示开,关光标
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay(5);
                lcd_wcmd(0x06);
/*指定在资料写入或读取时,光标的移动方向,DDRAM的地址计数器(AC)加1。*/               
                delay(5);               
}
void lcd_init2(void)           //LCD显示图片(扩展)初始化程序
{
  delaynms(10); //启动等待,等LCM讲入工作状态

  lcd_wcmd(0x34);
  lcd_wcmd(0x36);  //扩充指令集
  lcd_wcmd(0x3E);   //(DL=8BITS,RE=1,G=1)
  lcd_wcmd(0x02);  //清DDRAM
}

/*****************图像显示***************************/
void photodisplay(uchar *bmp)
{
  uchar i,j;
  lcd_wcmd(0x34);//写数据时,关闭图像显示
  for(i=0;i<32;i++)
  {
   lcd_wcmd(0x80+i);//先写入水平坐标值
   lcd_wcmd(0x80);//写入垂直坐标值
   for(j=0;j<16;j++)
      lcd_wdat(*bmp++);
   delaynms(1);
  }
  /********显示下半屏内容*****************/
  for(i=0;i<32;i++)
  {
   lcd_wcmd(0x80+i);//先写入水平坐标值
   lcd_wcmd(0x88);//写入垂直坐标值
   for(j=0;j<16;j++)
     lcd_wdat(*bmp++);
   delaynms(1);
  }
  lcd_wcmd(0x36);//写完数据,开图像显示
  lcd_wcmd(0x30);//回到基本指令集
}
void lcdtest(void)        //图形方式下屏幕全黑
{
unsigned char i,j;
for(i=0;i<32;i++)
  { lcd_wcmd(0x80+i);lcd_wcmd(0x80);
    for(j=0;j<16;j++) lcd_wdat(0xff);
  }

for(i=0;i<32;i++)
  { lcd_wcmd(0x80+i);lcd_wcmd(0x88);
    for(j=0;j<16;j++) lcd_wdat(0xff);
  }
}

void lcdcls(void)  //图形方式下清屏
{
unsigned char i,j;
for(i=0;i<32;i++)
  { lcd_wcmd(0x80+i);lcd_wcmd(0x80);
    for(j=0;j<16;j++) lcd_wdat(0x00);
  }

for(i=0;i<32;i++)
  { lcd_wcmd(0x80+i);lcd_wcmd(0x88);
    for(j=0;j<16;j++) lcd_wcmd(0x00);
  }
}
uchar readdat(void)

{

        uchar Rdata;

        Check12864state();

        PB_ODR=0xff;

        LCD_RS = 1;

        LCD_RW = 1;

  LCD_EN = 0;

        delayNOP();

        LCD_EN = 1;

        delayNOP();

        PB_DDR= 0x00;

        PB_CR1 = 0x00;

        Rdata=PB_IDR;

        LCD_EN = 0;

        delayNOP();

        return Rdata;

}
//填充GDRAM数据
void fill_GDRAM(uchar dat)//dat为填充数据
{
        uchar i,j,k;
        uchar GDRAM_X=0x80;//GDRAM水平地址
        uchar GDRAM_Y=0x80;//GDRAM垂直地址
        for(i=0;i<2;i++)
{
          for(i=0;i<2;i++)
    {
             for(k=0;k<8;k++)
                        {
               lcd_wcmd(0x34);
                                 lcd_wcmd(GDRAM_Y+j);
                                 lcd_wcmd(GDRAM_X+k);
               lcd_wdat(dat);
                                lcd_wdat(dat);
      }
    }
GDRAM_X=0x88;
}
lcd_wcmd(0x36);
lcd_wcmd(0x30);
}
void Fill_point(uchar x,uchar y,uchar color)
{
        uchar x_Dyte,x_byte;//定义地址的字节在哪一位
        uchar y_Dyte,y_byte;
        uchar GDRAM_hbit,GDRAM_lbit;
        lcd_wcmd(0x36);
        //--XY坐标互换,及普通的X,Y坐标
        x_Dyte=x/16;//计算在18个字节中的哪一位
        x_byte=x&0x0f;//计算该字节中的哪一位
        y_Dyte=y/32;//0为上屏,1位下屏
        y_byte=y&0x1f;//计算在0——31中的哪一行
        lcd_wcmd(0x80+y_byte);//设定行地址(Y坐标),即垂直地址
        lcd_wcmd(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通8*y_Dyte选定上下屏,及水平地址
        readdat();
        GDRAM_hbit=readdat();
        GDRAM_lbit=readdat();
        delay(1);
        lcd_wcmd(0x80+y_byte);//设定行地址(Y坐标),即垂直地址
        lcd_wcmd(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通8*y_Dyte选定上下屏,及水平地址
        delay(10);
        if(x_byte<8)//判定其再高八位还是在低八位
{
         if(color==1)
         {
         lcd_wdat(GDRAM_hbit|(0x01<<(7-x_byte)));
        }
    else
   {
     lcd_wdat(GDRAM_hbit|(0x01<<(~(7-x_byte))));
     lcd_wdat(GDRAM_lbit);//显示GDRA区低八位
    }
        if(x_byte>=8)
{
        lcd_wdat(GDRAM_hbit);
        if(color==1)
  {
                lcd_wdat(GDRAM_hbit|(0x01<<(15-x_byte)));
        }
        else
  {
                lcd_wdat(GDRAM_hbit|(0x01<<(~(15-x_byte))));
        }
}
lcd_wcmd(0x30);

}
}
  main()
{
    uchar i;
                GPIO_Init1();
        //PB_ODR = 0xff;
        //WELK = 0;
        //DULK = 1;
        delay(10);                 //延时
        lcd_init();                //初始化LCD
        //lcdtest();
        //lcdcls();
        fill_GDRAM(0x00);
        Fill_point(1,1,1);
        while (1);
       
}
这是程序

一周热门 更多>