panhai0101 发表于 2014-10-17 11:51:56

ATmaga16三线法驱动12864,为什么不显示?

如题。代码如下。
主函数:
#include <iom16v.h>
#include <macros.h>
#include "lcd12864.h"
void main(void)
{
          
       Lcd_Init();
       Lcd_Str(1,5,"是否调整参数?");
}
.C文件
#include "lcd12864.h"

unsigned charN[]={"0123456789"};
//const prog_uchar img[]={};//定义128*64的图像

void delay_lcd_us(unsigned int xus)/*us延时函数 8*0.125=1us*/
{
    int i,j;
        for(j=0;j<8;j++)
        {
          for (i=0;i<xus;i++)
          NOP();
        }
}
void delay_lcd_ms(unsigned int xms)/*ms延时函数*/
{
    while(xms--)
    {                        
          unsigned int j;               
      for(j=1;j<=1332;j++);                                            
    }
}

/*********************
LCD送命令子函数
********************/
unsigned char Read_data(void)   
{
unsigned char i,dat;
unsigned char temp1=0,temp2=0;
CS_off;        
SID_off;       
CS_on;        
dat=0xfc;
for(i=0;i<8;i++)
{
          if((dat&0x80)==0x80)   SID_on;
          if((dat&0x80)==0x00)   SID_off;
          SCLK_off;       
          SCLK_on;       
          dat<<=1;
       }
       for(i=0;i<8;i++)
       {
          temp1<<=1;
          DATA_IN_lcd;
          //Lcd_Data_Ddr|=~RW;
          if(LCD_READ_DATA==1)
                  temp1|=0x01;
           else
          temp1&=0xfe;
       DATA_OUT_lcd;
       SCLK_off;       
       SCLK_on;
       }
       for(i=0;i<8;i++)
       {
          temp2<<=1;
          DATA_IN_lcd;
          //Lcd_Data_Ddr|=~BIT(RW);
          if(LCD_READ_DATA==1)
                  temp2|=0x01;
          else temp2&=0xfe;
          DATA_OUT_lcd;
          SCLK_off;       
          SCLK_on;       
       }
       
       //CS_off;SID_on;SCLK_off;
          return ((temp1&0xf0)+(temp2>>4));
}

void BUSY(void)
{
while((Read_data()&0x80)==0x80);
}

void Write_com(unsigned char lcd_com)   //LCD送命令子函数
{
unsigned char i,dat;
BUSY();
CS_off;
SID_off;       
CS_on;
dat=0xf8;//写命令
for(i=0;i<8;i++)
{
if((dat&0x80)==0x80)   SID_on;
if((dat&0x80)==0x00) SID_off;
SCLK_off;       
SCLK_on;
dat<<=1;
}
dat=(lcd_com&0xf0);
for(i=0;i<8;i++)//写高四位
{
if((dat&0x80)==0x80)   SID_on;
if((dat&0x80)==0x00) SID_off;
SCLK_off;
SCLK_on;       
dat<<=1;
}
dat=(lcd_com&0x0f);
dat<<=4;
for(i=0;i<8;i++)//写低四位
{
if((dat&0x80)==0x80)   SID_on;
if((dat&0x80)==0x00)   SID_off;
SCLK_off;
SCLK_on;
dat<<=1;
}

}
//-----------------------------------------------------------
void Write_data(unsigned char lcd_com)//LCD送显示数据子函数
{
unsigned char i,dat;
BUSY();
CS_off;
SID_off;
CS_on;
dat=0xfa;//写数据
for(i=0;i<8;i++)
{
if((dat&0x80)==0x80)    SID_on;
if((dat&0x80)==0x00) SID_off;
SCLK_off;       
SCLK_on;       
dat<<=1;
}
dat=(lcd_com&0xf0);
for(i=0;i<8;i++)//写高四位
{
if((dat&0x80)==0x80)   SID_on;
if((dat&0x80)==0x00)   SID_off;
SCLK_off;       
SCLK_on;       
dat<<=1;
}
dat=(lcd_com&0x0f);
dat<<=4;
for(i=0;i<8;i++)//写低四位
{
if((dat&0x80)==0x80)   SID_on;
if((dat&0x80)==0x00)   SID_off;
SCLK_off;       
SCLK_on;
dat<<=1;
}
}


/***********初始化************/
void Lcd_Init(void)

{
        //JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD
        //RCC->APB2ENR|=1<<2;    //使能PORTC时钟
        //SetPin(myGPIOA,myPIN1,GPIO_Out_PP|GPIO_50MHZ);
        //SetPin(myGPIOA,myPIN2,GPIO_Out_PP|GPIO_50MHZ);
        //SetPin(myGPIOA,myPIN3,GPIO_Out_PP|GPIO_50MHZ);
Lcd_Data_Ddr|=RS|RW|E;
SCLK_off;
Write_com(0x30);
    delay_lcd_ms(10);
Write_com(0x30);
    delay_lcd_ms(15);
Write_com(0x0c);
    delay_lcd_ms(15);
Write_com(0x0c);//开显示,不显示光标
    delay_lcd_ms(15);
Write_com(0x06);//写一个字符后地址指针自动加1
    delay_lcd_ms(15);
Write_com(0x01);//清屏
    delay_lcd_ms(20);
}


/***************清屏命令*********************/   
void Lcd_Clear(void)
{
   Write_com(0x01);
   delay_lcd_ms(10);
   }
   
   

/******************显示图片***************
void Disp_Img(unsigned char *img)
{
        unsigned int j=0;
    unsigned char x,y,i;
        Write_com(0x34);
       for(i=0;i<9;i+=8)
             for(y=0;y<32;y++)
             for(x=0;x<8;x++)
                 {
            Write_com(y+0x80);      //行地址
            Write_com(x+0x80+i);      //列地址
            Write_data(pgm_read_byte(&img));
            Write_data(pgm_read_byte(&img));
         }   
                  Write_com(0x36);          //扩充指令集
            Write_com(0x30);
}
***/
//画点函数
/*
void Lcd_DrawPoint(unsigned char x,unsigned char y,unsigned char sty)
{
    unsigned char i,j;
        unsigned char t1,t2;
        y=63-y;//从下面向上为0-63
        i=x/16;
        j=x%16;
        if(x/8%2==0){
    t1=BUF;
        t2=BUF; }
        else{
    t1=BUF;
        t2=BUF; }
        Write_com(0x34);
        Write_com(0x36);
    if(y<32)
        {        
   Write_com(y+0x80);//行地址
   Write_com(i+0x80); //列地址
       }   
        else
        {
         Write_com(y-32+0x80);    //行地址
         Write_com(i+0x88);       //列地址
               }   
    if(j<8)
        {
        if(sty==1)
       t1|=(0x80>>j);
    else if(sty==0) t1&=(~(0x80>>j));
       Write_data(t1);
   Write_data(t2);
        }
        else
        {
        if(sty==1)
       t2|=(0x80>>(j-8));
    else if(sty==0)t2&=~(0x80>>(j-8));
   Write_data(t1);
   Write_data(t2);
        }
    Write_com(0x30);
if(x/8%2==0)
{
BUF=t1;
BUF=t2; }
else
{
BUF=t1;
BUF=t2; }
}

*/
/****************清整个GDRAM空间*****************/
void LCD_ClearGDRAM(void)
{      
    unsigned char x,y;
    for(y=0;y<64;y++)
   for(x=0;x<16;x++)
   {
               Write_com(0x34);
      Write_com(y+0x80);   //行地址
      Write_com(x+0x80);   //列地址
      Write_com(0x30);
      Write_data(0x00);
      Write_data(0x00);
       }
   }
         

/*********************显示位置*********************/
void Lcd_Loc(unsigned char x,unsigned char y)
{
       switch(x)
       {
           case 1:Write_com(0x80+y-1);break;
               case 2:Write_com(0x90+y-1);break;
               case 3:Write_com(0x88+y-1);break;
               case 4:Write_com(0x98+y-1);break;
       }
}


/*************************显示汉字**********************/
void Lcd_Str(unsigned char x,unsigned char y,unsigned char*str)
{
   unsigned char a=y;
   Lcd_Loc(x,y);
   while(*str)
   {
             Write_data(*str);
          a++;
          if(a-1==16)
          {
           a=1;       
              Lcd_Loc(++x,1);
   }
      str++;
delay_lcd_ms(1);
          }
}


/******************显示数字(最多五位,除后两位外非零保留)************************/
void Lcd_Num(unsigned char x,unsigned char y,long signed int Data)
{
       unsigned int G,S,B,Q,W;        //个、十、百、千、万
Lcd_Loc(x,y);
if(Data<0)
{
Data=-Data;
Write_data('-');
}
       W=Data/10000;
       Q=Data%10000/1000;
       B=Data%10000%1000/100;
       S=Data%10000%1000%100/10;
       G=Data%10000%1000%100%10;
       if(W!=0) {
                                                        Write_data(N);
                                                        Write_data(N);
                                                        Write_data(N);
                                                        Write_data(N);
                                                        Write_data(N);
                    }
       if(W==0&&Q!=0)
                    {
                                                        Write_data(N);
                                                        Write_data(N);
                                                        Write_data(N);
                                                        Write_data(N);
//                                                        Write_data(' ');       
                                     }
       if(W==0&&Q==0&&B!=0)
                {
                    Write_data(N);
                    Write_data(N);
                    Write_data(N);
//                                                        Write_data(' ');
//                                                        Write_data(' ');
                                                 }
       if(W==0&&Q==0&&B==0&&S!=0)
                {
                    Write_data(N);
                    Write_data(N);
//                                                        Write_data(' ');
//                                                        Write_data(' ');
//                                                        Write_data(' ');
                                     }
          if(W==0&&Q==0&&B==0&&S==0)
                 {
                    Write_data(N);
                    Write_data(N);
//                                               Write_data(' ');
//                                               Write_data(' ');
//                                               Write_data(' ');
                                               }
}
/**************************显示浮点数(浮点数小于1000,保留两位小数)*********************/
//999.99
void Lcd_Float(unsigned char x,unsigned char y,float Data)
{
          long a;
          unsigned int B,S,G,SF,BF;//百、十、个、十分、百分位
//       unsigned int QF;
          Lcd_Loc(x,y);
if(Data<0)
{
   Data=-Data;
   Write_data('-');
   }
          a=Data*1000;
          B=a/100000;
          S=a%100000/10000;
          G=a%100000%10000/1000;
          SF=a%100000%10000%1000/100;
          BF=a%100000%10000%1000%100/10;
//          QF=a%100000%10000%1000%100%10;

           if(B!=0)
           {
           Write_data(N);
           Write_data(N);
           Write_data(N);
           Write_data('.');
           Write_data(N);
           Write_data(N);
//           Write_data(N);
           }
           if(B==0&&S!=0)
           {
           Write_data(N);
           Write_data(N);
           Write_data('.');
           Write_data(N);
           Write_data(N);
//           Write_data(N);
               Write_data(' ');
           }
           if(B==0&&S==0)
           {
           Write_data(N);
           Write_data('.');
           Write_data(N);
           Write_data(N);
//           Write_data(N);
               Write_data(' ');
               Write_data(' ');
           }
       }


/*****************自定义一个字符代码********************
****unsigned char x   :        显示行坐标
****unsigned char y   :        显示列坐标
****unsigned char N          :        定义的第N个字符
****unsigned char *zk :        定义的字符点阵数组
*********************************************************/
void Lcd_Def(unsigned char x,unsigned char y,unsigned char N,unsigned char *zk)
{   
       int i;
   Write_com(0x30);
       switch(N)
       {
                  case 1:Write_com(0x40);break;//第一个字符的位置为0x40
                case 2:Write_com(0x50);break;//第二个字符的位置为0x50
                case 3:Write_com(0x60);break;//第三个字符的位置为0x60
                case 4:Write_com(0x70);break;//第四个字符的位置为0x70
       }   
   for(i=0;i<16;i++)
   {
          Write_data(zk);
      Write_data(zk);
      }
          Lcd_Loc(x,y);
          Write_data(0x00);
          switch(N)
          {
           case 1:Write_data(0x00);break; //第一个自定义显示字符编码为:0x00
           case 2:Write_data(0x02);break; //第二个自定义显示字符编码为:0x02
           case 3:Write_data(0x04);break; //第三个自定义显示字符编码为:0x04
           case 4:Write_data(0x06);break; //第四个自定义显示字符编码为:0x06
          }                            
}
.h文件
/******12864带中文字库显示器-串行方式********/
#ifndef __LCD12864_H
#define __LCD12864_H
/*
#define RS PAout(1)
#define RW PAout(2)
#define E PAout(3)
*/
#include <iom16v.h>
#include <macros.h>

#define Lcd_Data_Port PORTA
#define Lcd_Data_PinPINA
#define Lcd_Data_DdrDDRA

#define RS BIT(1)
#define RW BIT(2)
#define EBIT(3)

#define CS_on   {Lcd_Data_Ddr|=RS;Lcd_Data_Port|=RS;}
#define CS_off    {Lcd_Data_Ddr|=RS;Lcd_Data_Port|=~RS;}
#define SID_on    {Lcd_Data_Ddr|=RW;Lcd_Data_Port|=RW;}
#define SID_off   {Lcd_Data_Ddr|=RW;Lcd_Data_Port|=~RW;}
#define SCLK_on   {Lcd_Data_Ddr|=E;Lcd_Data_Port|=E;}
#define SCLK_off{Lcd_Data_Ddr|=E;Lcd_Data_Port|=~E;}
/*
#define DATA_IN_lcd SetPin(myGPIOA,myPIN2,GPIO_IPDU);
#define DATA_OUT_lcd {SetPin(myGPIOA,myPIN2,GPIO_Out_PP|GPIO_50MHZ);myGPIO_SetBit(myGPIOA,myPIN2);}
#define LCD_READ_DATA PAin(2)
*/

//8M环境下
#define DATA_IN_lcd   Lcd_Data_Ddr|=~RW
#define DATA_OUT_lcd    {(Lcd_Data_Ddr|=RW);(Lcd_Data_Port|=RW);}
#define LCD_READ_DATA   (Lcd_Data_Pin&RW)

//#define LCD_W 128
//#define LCD_H 64
void delay_lcd_us(unsigned int xus);
void delay_lcd_ms(unsigned int xms);

void BUSY(void);
void Write_com(unsigned char cmdcode);
void Write_data(unsigned char DispData);
unsigned char Read_data(void);
void Lcd_Init(void);
void Lcd_Clear(void);
void LCD_ClearGDRAM(void);
void Lcd_Loc(unsigned char x,unsigned char y);
void Lcd_Str(unsigned char x,unsigned char y,unsigned char*str);
void Lcd_Num(unsigned char x,unsigned char y,long signed int Data);
void Lcd_Float(unsigned char x,unsigned char y,float Data);
void Disp_Img(unsigned char*img);
void Lcd_Def(unsigned char x,unsigned char y,unsigned char N,unsigned char *zk);
void Lcd_DrawPoint(unsigned char x,unsigned char y,unsigned char sty);



#endif

panhai0101 发表于 2014-10-17 15:17:41

调试成功,犯了个小小错误。上传自己整理的东东。测试成功。

panhai0101 发表于 2014-10-17 15:19:01

三线串行驱动,节约I/O的资源。压榨单片机的资源是目标,玩到极限,才有乐趣。谢谢之前坛友的指导。

陶新成 发表于 2014-10-17 15:43:17

我用的是两线,片选让我直接接到高电平了

panhai0101 发表于 2014-10-17 16:16:25

陶新成 发表于 2014-10-17 15:43
我用的是两线,片选让我直接接到高电平了

哇,这都行啊。。。。坛友牛人辈出
页: [1]
查看完整版本: ATmaga16三线法驱动12864,为什么不显示?