找回密码
 注册
搜索
查看: 3965|回复: 24

[讨论] 誰有好的針對LCD驅動用C寫的程序啊?

[复制链接]
发表于 2005-10-31 11:54:00 | 显示全部楼层 |阅读模式
誰有好的針對LCD驅動用C寫的程序啊?
LCD的調試程序我一直用匯編語言編寫,很想學學用C怎麼編寫。其中有很多方面不太明白,比如在C語言中怎麼調用外部EPROM的程序?這條指令應該怎麼編寫。在匯編語言中只要用movx就可以調用了。等等
如果誰想了解點匯編的知識的也可以跟我聯絡,還望大家不吝分享你們的C資料!
先謝謝了
 楼主| 发表于 2005-10-31 17:22:00 | 显示全部楼层
<P>大家都不願意分享嗎?</P>
点评回复

使用道具 举报

发表于 2005-10-31 19:35:00 | 显示全部楼层
<P>呵呵,我现在就用的C语言。不过汇编也会。但是在目前的平台上不用而已。</P><P>感觉用C语言会更简单啊,只要控制好地址线、数据线基本就OK了。</P><P>小弟刚入行,不对之处请指正^_^</P>
点评回复

使用道具 举报

 楼主| 发表于 2005-11-1 09:01:00 | 显示全部楼层
<P>恩,安道理來說,C語言更接近人語言,應該更好學,但是我現在很缺LCM方面的C語言的指令和資料。</P><P>希望知道的仁兄們不吝賜教。教教小弟</P>
点评回复

使用道具 举报

发表于 2005-11-1 09:59:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
点评回复

使用道具 举报

 楼主| 发表于 2005-11-1 10:18:00 | 显示全部楼层
<P>謝謝版主的意見。</P><P>我現在是想在8051單片機用C來控制LCD。沒有在專業的平台上操作。</P><P>拿個具體的問題問大家吧:</P><P>我現在外擴的EPROM的起始地址是0000h,尾地址是7FFFh。用C語言,哪條指令才能讀EPROM裡面的全部數據啊?有知道的仁兄,請告知!</P>
点评回复

使用道具 举报

发表于 2005-11-2 22:15:00 | 显示全部楼层
搞个循环不就OK了?[em02]
点评回复

使用道具 举报

发表于 2005-11-3 20:45:00 | 显示全部楼层
<P>void demo(uchar d)
{
int i,j,n,l=0;
uchar d0,d1,r,g,b,t;
  uint addr;
        </P><P>      
    addr=0x0000;
             for(i=0;i&lt;64;i++)
              { </P><P>  for(j=0;j&lt;256;j++)
  {
   P1=d;
   d0=XBYTE[addr++];</P><P>      write_data(d0);
  
   }
                }
             d++;</P><P>          }
        addr=0x0000;
        for(i=0;i&lt;64;i++)
         {      </P><P>          for(j=0;j&lt;256;j++)
             {
   P1=d;
   d0=XBYTE[addr++];</P><P>           write_data(d0);
                }</P><P>        }不知道这个程序能不能解决你的问题~~~有兴趣可以接着讨论~~~</P>[br]<p align=right><font color=red>+5 RD币</font></p>
点评回复

使用道具 举报

发表于 2005-11-4 01:22:00 | 显示全部楼层
<P>你可以将外部地址定义一个数组,具体形式如:</P><P>xdata uint8 main_lcd_image_data[ 0x7ffff];</P><P>或定义一个指针,只要用好xdata就行。</P>[br]<p align=right><font color=red>+3 RD币</font></p>
点评回复

使用道具 举报

 楼主| 发表于 2005-11-4 09:11:00 | 显示全部楼层
<P>謝謝zorro7758和sincinaty的這麼好的回答,我會試驗一下的</P><P>非常感謝!</P>
点评回复

使用道具 举报

发表于 2005-11-4 15:19:00 | 显示全部楼层
<P>假如是8位数据线的LCD,假如MCU分配给它的片选地址是0X7000~0X7FFF。地址线A1决定是写命令还是数据,这根据IC时序决定。</P><P>void writedata(unsigned char data)</P><P>{*(volatile unsigned char *)0x7002=data;</P><P>}</P><P>void writecmd(unsigned char cmd)</P><P>{*(volatile unsigned char *)0x7000=cmd;</P><P>}</P><P>有了这两个基本函数,就可以进行初始化了。初始化主要是根据驱动IC写一些命令字。初始化完成后,就可以写数据了。</P>[br]<p align=right><font color=red>+5 RD币</font></p>
点评回复

使用道具 举报

 楼主| 发表于 2005-11-4 17:56:00 | 显示全部楼层
<P>先謝謝各位仁兄的指教</P><P>現在我按照zorro7758兄的做法,外部的數據是可以讀取了,但是讀取的數據不是從數據開始讀取的。請看看我寫的這段程序指出有什麼不妥之處!</P><P>#include &lt;reg51.h&gt;
#include &lt;absacc.h&gt;</P><P>sbit   cs=P3^0;          //main lcd select
sbit   resest=P3^1;
sbit   sw1=P3^5;         //change  picture
sbit   sw2=P3^4;         //
sbit   sw3=P3^3; </P><P>#define cmd XBYTE[0x0000]
#define dat XBYTE[0x0001]
//========================================================//
void   wrcmd(unsigned char i,unsigned char j);
void   wrdata(unsigned char i,unsigned char j);
void   delay(unsigned int tt);
void   wait_sw1(void);
void   show_photo();
//===========================================================//
void   main(void)
{
  show_photo();
}
//======================================================//
void  wrcmd(unsigned char i,unsigned char j)
{
   cs=0;
   P1=i;
   cmd=j;
   cs=1;
   delay(1000);
}
//=====================================================//
void   wrdata(unsigned char i,unsigned char j)
{
  cs=0;
  P1=i;
  dat=j;
  cs=1;
  //delay(10);
}
//======================================================//
void wait_sw1(void)      
{
  do
       {  
         delay(500);              
        } while(sw1);   
}   
//========================================================//
void   delay(unsigned int tt)
{
    while(tt&gt;0)
    {
        tt--;
    }
}
<FONT color=#ee1111>void  show_photo()
{
  int i,j;
  unsigned char temp1,temp2;
  unsigned int addr;</FONT></P><P><FONT color=#ee1111>      addr=0x0000 ;
      for(i=0;i&lt;160;i++)
      {
        for(j=0;j&lt;128;j++)
        {
           temp1=XBYTE[addr++];
           temp2=XBYTE[addr++];
           
            wrdata(temp2,temp1);
        }
   }
      wait_sw1();
}</FONT></P><P><FONT color=#ee1111>請指正</FONT></P>
点评回复

使用道具 举报

发表于 2005-11-5 18:45:00 | 显示全部楼层
<P>使用XBYTE需要有硬件的支持,即能支持数据/地址分时复用,否则就无法读出正确的数据。</P><P>另外,128*160=0xa000,已经超过了你的存储器容量(0x7fff).请检查硬件方面。</P>[br]<p align=right><font color=red>+3 RD币</font></p>
点评回复

使用道具 举报

发表于 2005-11-5 20:54:00 | 显示全部楼层
注意下我里面的d起的作用,今天没时间了,明天再细讲~~~
点评回复

使用道具 举报

发表于 2005-11-5 23:04:00 | 显示全部楼层
<P>which model of ur LCD Controller is? C this code based on 8051 family MCU for ST7920 LCD controllor atteched below,maybe something useful</P><P>===========================================================================</P><P>/*    Copyright (c) 2003,2005 aquasnake.</P><P>      All rights reserved.</P><P>*/</P><P>#ifndef __ST7920_C__
#define __ST7920_C__</P><P>#include &lt;W77C32.H&gt;  //or &lt;REG51.H&gt;
#include &lt;INTRINS.H&gt;
  
#define LEFT  0
#define RIGHT 1
#define DB P0</P><P>sbit DB_7=DB^7;
sbit RW=P3^6;
sbit RS=P3^4;
sbit E=P3^5;</P><P>typedef unsigned char INT8U;
typedef unsigned int INT16U;</P><P>static void LCMCheckBusy(void) small;
static void LCMWriteData(INT8U ch) small;
static void LCMWriteInst(INT8U ch) small;
static void LCMRead(INT8U ch) small;
void LCMInit(void) small;
void LCMDispChar(INT8U line,INT8U row,INT8U *ch) small;
void LCMDispLineStr(INT8U line,INT8U row,INT8U *str) small;
void LCMDispScrStr(INT8U line,INT8U row,INT8U *str) small;
void LCMDisp16Dots(INT8U y,INT8U row,INT16U bitctrlcode) small;
void LCMClrScr(void) small;
void LCMSwapColor(INT8U line) small;
void LCMSleep(void) small;
void LCMWakeUp(void) small;
void LCMCursorMove(INT8U dir) small;</P><P>/*
*************************************************************************************************
*/
void LCMInit(void) small
{
    E=0;
    LCMWriteInst(0x30);
    LCMWriteInst(0x0C);//Display status:all display on
}
/*
*************************************************************************************************
*/
static void LCMCheckBusy(void) small
{</P><P>    DB=0xFF;
    RW=1;
    RS=0;
    E=1;
    //_nop_();
    while(DB_7) {};
    E=0;
}
/*
*************************************************************************************************
*/
static void LCMWriteData(INT8U ch) small
{
    LCMCheckBusy();
    RW=0;
    RS=1;
    E=1;
    DB=ch;
    E=0;
}
/*
*************************************************************************************************
*/
static void LCMWriteInst(INT8U ch) small
{
    LCMCheckBusy();
    RW=0;
    RS=0;
    E=1;
    DB=ch;
    E=0;
}
/*
*************************************************************************************************
*/
static void LCMRead(INT8U ch) small
{
    LCMCheckBusy();
    RW=1;
    RS=1;
    E=1;
    _nop_();
    ch=DB;
    E=0;
}
/*
*************************************************************************************************
*/
void LCMDispChar(INT8U line,INT8U row,INT8U *ch) small//line:0..3;row:0..7
{
    LCMWriteInst(0x30);
    switch(line)
    {
        case 0: LCMWriteInst(0x80+row);break;
        case 1: LCMWriteInst(0x90+row);break;
        case 2: LCMWriteInst(0x88+row);break;
        case 3: LCMWriteInst(0x98+row);break;
        default: _nop_();
    }
    if(*ch&lt;0x80) LCMWriteData(*ch);
    else {LCMWriteData(*ch++);LCMWriteData(*ch);}
}
/*
*************************************************************************************************
*/
void LCMDispLineStr(INT8U line,INT8U row,INT8U *str) small
{
    INT8U i,temp;
    LCMWriteInst(0x30);
    switch(line)
    {
        case 0: temp=0x80;break;
        case 1: temp=0x90;break;
        case 2: temp=0x88;break;
        case 3: temp=0x98;break;
        default: _nop_();
    }
    for(i=row;i&lt;8;i++)
    {
        if(*str=='\0') break;
        LCMWriteInst(temp+row);
        if(*str&lt;0x80) LCMWriteData(*str);
        else {LCMWriteData(*str++);LCMWriteData(*str);}
        str++;
    }
}
/*
*************************************************************************************************
*/
void LCMDispScrStr(INT8U line,INT8U row,INT8U *str) small
{
    INT8U i,j,temp;
    LCMWriteInst(0x30);
    switch(line)
    {
        case 0: temp=0x80;break;
        case 1: temp=0x90;break;
        case 2: temp=0x88;break;
        case 3: temp=0x98;break;
        default: _nop_();
    }
    for(j=row;j&lt;8;j++)
        {
            if(*str=='\0') break;
            LCMWriteInst(temp+j);
            if(*str&lt;0x80) LCMWriteData(*str);
            else {LCMWriteData(*str++);LCMWriteData(*str);}
            str++;
        }
    for(i=line+1;i&lt;4;i++)
    {
     switch(i)
        {
            case 0: temp=0x80;break;
            case 1: temp=0x90;break;
            case 2: temp=0x88;break;
            case 3: temp=0x98;break;
            default: _nop_();
        }
        for(j=0;j&lt;8;j++)
        {
            if(*str=='\0') break;
            LCMWriteInst(temp+j);
            if(*str&lt;0x80) LCMWriteData(*str);
            else {LCMWriteData(*str++);LCMWriteData(*str);}
            str++;
        }
    }
}
/*
*************************************************************************************************
*/
void LCMDisp16Dots(INT8U y,INT8U row,INT16U bitctrlcode) small//y:0..127;row:0..15
{
    LCMWriteInst(0x34);//Extension instruction:graphic display off
    LCMWriteInst(0x80+y);LCMWriteInst(0x80+row);
    LCMWriteData((INT8U)(bitctrlcode&gt;&gt;8));
    LCMWriteData((INT8U)(bitctrlcode&amp;0xFF));
    LCMWriteInst(0x36);//Extension instruction:graphic display on
}
/*
*************************************************************************************************
*/
void LCMClrScr(void) small
{
    LCMWriteInst(0x30);
    LCMWriteInst(0x01);
}
/*
*************************************************************************************************
*/
void LCMSwapColor(INT8U line) small
{
    LCMWriteInst(0x34);
    LCMWriteInst(0x04+line);
}
/*
*************************************************************************************************
*/
void LCMSleep(void) small
{
    LCMWriteInst(0x34);
    LCMWriteInst(0x08);
}
/*
*************************************************************************************************
*/
void LCMWakeUp(void) small
{
    LCMWriteInst(0x34);
    LCMWriteInst(0x0C);
}
/*
*************************************************************************************************
*/
void LCMCursorMove(INT8U dir) small
{
    LCMWriteInst(0x30);
    if(dir) LCMWriteInst(0x14);
    else LCMWriteInst(0x10);
}
/*
*************************************************************************************************
*/
#endif
</P>
点评回复

使用道具 举报

发表于 2005-11-6 14:30:00 | 显示全部楼层
这个是别人写的ADS下的LCM 驱动
#include <stdio.h>
#include "xlcd.h"
#include "..\console.h"
#include "..\console_rpc.h"
/***** Win32 version *****/
#include <windows.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>
#define MAX_LCDEVENT_QUEUE  50
int n_lcdevents_in=0;
int n_lcdevents_out=0;
LcdEvent lcdevents[MAX_LCDEVENT_QUEUE];
int LcdModelInit(void)
{
    /* Initialise the Lcd model library */

/* Set up Remote Procedure Call (RPC) */
RPC_STATUS status;
    char * pszProtocolSequence = "ncalrpc";
    char * pszSecurity     = NULL; /*Security not implemented */
    char * pszEndpoint    = "console_rdi";
    unsigned int    cMinCalls           = 1;
    unsigned int    cMaxCalls           = 20;
    unsigned int    fDontWait           = TRUE;
RPC_BINDING_VECTOR* vec;
char buf[100];

    /*status = RpcServerUseProtseqEp((unsigned char*)pszProtocolSequence,
                                   cMaxCalls,
                                   (unsigned char*)pszEndpoint,
                                   pszSecurity);
*/
/* if we're changing model, make sure all pending calls finish first!! */
RpcMgmtWaitServerListen();
status = RpcServerUseProtseq(pszProtocolSequence, cMaxCalls, NULL);
    if (status != RPC_S_OK ) {
  // determine exactly what the error was
  wsprintf( buf, "Invalid server RPC String: status=%d", status );
  switch( status ) {
  case RPC_S_PROTSEQ_NOT_SUPPORTED:
   strcat( buf, ": Protocol sequence not supported on this host" );
   break;
  case RPC_S_INVALID_RPC_PROTSEQ:
   strcat( buf, ": Invalid protocol sequence" );
   break;
  case RPC_S_INVALID_ENDPOINT_FORMAT:
   strcat( buf, ": Invalid endpoint format" );
   break;
  case RPC_S_OUT_OF_MEMORY:
   strcat( buf, ": Out of memory" );
   break;
  case RPC_S_DUPLICATE_ENDPOINT:
   strcat( buf, ": Endpoint is duplicate" );
   break;
  case RPC_S_INVALID_SECURITY_DESC:
   strcat( buf, ": Security descriptor invalid" );
  }
        MessageBox( NULL, buf, "console.dll", MB_OK );
    }

    status = RpcServerRegisterIf(console_rpc_v1_0_s_ifspec,  
                                 NULL,   
                                 NULL);

// Get binding vector for subsequent calls
status = RpcServerInqBindings(&vec);
// Register endpoint with endpoint mapper
status = RpcEpRegister(console_rpc_v1_0_s_ifspec,
   vec,
   NULL,
   pszEndpoint);
status = RpcBindingVectorFree( &vec );
    status = RpcServerListen(cMinCalls,
                             cMaxCalls,
                             fDontWait);

return TRUE;
}
void LcdModelClose(void)
{
/* shut down the RPC server */
RPC_STATUS status;
HWND hwnd;
RPC_BINDING_VECTOR* vec;
unsigned i;
// close down the viewer window
hwnd = FindWindow( "Afx:400000:0", "ARM Virtual LCD" );
if( hwnd != NULL ) {
  SendMessage( hwnd, WM_CLOSE, 0, 0l );
}

    status = RpcMgmtStopServerListening(NULL);
if( status != RPC_S_OK )
  MessageBox( NULL, "RpcMgmtStopServerListening failed", "console.dll", MB_OK );
status = RpcServerUnregisterIf(NULL, NULL, 0);
if( status != RPC_S_OK )
  MessageBox( NULL, "RpcServerUnregisterIf failed", "console.dll", MB_OK );
status = RpcServerInqBindings( &vec );
// set vectors to NULL
for( i = 0; i < vec->Count; i++ ) {
  vec->BindingH = NULL;
}
status = RpcEpUnregister( console_rpc_v1_0_s_ifspec, vec, NULL );
if( status != RPC_S_OK )
  MessageBox( NULL, "RpcEpUnregister failed", "console.dll", MB_OK );
status = RpcBindingVectorFree( &vec );
}
LcdModel *LcdModelCreate(int XPos, int YPos, unsigned int Width, unsigned int Height)
{
    LcdModel *TheLcd;
unsigned alignment_tweak;
    TheLcd = (LcdModel *)malloc(sizeof(LcdModel));
    if (TheLcd) {
  DWORD dwErr;
        TheLcd -> PosX   = XPos;
        TheLcd -> PosY   = YPos;
        TheLcd -> Width  = Width;
        TheLcd -> Height = Height;
  alignment_tweak = 4 - Width % 4;
  if( alignment_tweak == 4 ) alignment_tweak = 0;
  /* LCD: create File Mapping object backed by system paging file */
  TheLcd->hMap = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0,
   (Width+alignment_tweak)*Height / (8/BITS_PER_PIXEL), "wince");
     dwErr = GetLastError();
  if(TheLcd->hMap == NULL) {
   char buf[100];
   sprintf(buf, "GetLastError returned %d\n", dwErr);
   MessageBox(NULL, "File mapping error", buf, MB_OK);
  }
  TheLcd->lpvFile = MapViewOfFile(TheLcd->hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
  /* Spawn LCD viewer app */
  {
   char threadidbuf[10];
   int temp = 0;
   sprintf(threadidbuf, "%d", GetCurrentThreadId());
   /* DR amended */
   /*TheLcd->ChildId = _spawnlp(_P_NOWAIT, LCD_NAME, LCD_NAME, threadidbuf, "wince", NULL);*/
   TheLcd->ChildId = _spawnlp(_P_NOWAIT, "lcd.exe", "lcd.exe", threadidbuf, "wince", NULL);
   temp = errno;
   if (TheLcd->ChildId == 0)
   {
    free(TheLcd);
    return 0;
   }
  }
    }
    return TheLcd;
}
void LcdModelDestroy(LcdModel *lcd)
{
if (lcd) {
        free(lcd);
    }
}
int LcdModelCheckEvents(LcdModel *lcd, LcdEvent *event)
{
if (n_lcdevents_out != n_lcdevents_in)
{
  *event = lcdevents[n_lcdevents_out];
  if (n_lcdevents_out == MAX_LCDEVENT_QUEUE)
   n_lcdevents_out = 0;
  n_lcdevents_out++;
}
else
  event->Type = LCDNone;
    return 0;
}
void LcdModelWrite(LcdModel * lcd, unsigned int Address, unsigned char Byte)
{
((unsigned char *)(lcd->lpvFile))[Address] = Byte;
}
// RPC stuff
void QueueKey( int keycode, int type )
{
//int scancode = getscancode(keycode);
int scancode = keycode;
if (scancode) {
  lcdevents[n_lcdevents_in].Type = (type == 0) ? LCDKeyPress : LCDKeyRelease;
  lcdevents[n_lcdevents_in].KeyScanCode = scancode;
  if (n_lcdevents_in == MAX_LCDEVENT_QUEUE)
   n_lcdevents_in = 0;
  n_lcdevents_in++;
}
}
/******************************************************/
/*         MIDL allocate and free                     */
/******************************************************/

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
    return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
    free(ptr);
}
点评回复

使用道具 举报

 楼主| 发表于 2005-11-7 09:18:00 | 显示全部楼层
<P><b><FONT color=#000066>sincinaty</FONT></b> ,謝謝你的提醒,我在硬件方面有做一個74hc373的應用電路,做到了數據/命令分時復用。(<FONT color=#5233cc>#</FONT><FONT color=#5233cc>define cmd XBYTE[0x0000</FONT><FONT color=#3333cc>];#define dat XBYTE[0x0001]),</FONT>外地尾地址是0x7FFFF,不好意思,少寫了一位!謝謝!</P><P><b><FONT color=#000066>aquasnake兄,我正在看您提供的程序,先謝謝了。不懂之處還請您明示!謝謝</FONT></b></P>
点评回复

使用道具 举报

 楼主| 发表于 2005-11-7 10:10:00 | 显示全部楼层
<b><FONT color=#000066>zorro7758兄,還在等待您的講解(d的作用),其中P1=d,我不理解。</FONT></b>
点评回复

使用道具 举报

 楼主| 发表于 2005-11-7 14:36:00 | 显示全部楼层
現在的狀況是讀取的地址也是對的了,顯示的圖片也是我想要的,但是顯示的圖片的色彩失真了,不知道什麼原因
点评回复

使用道具 举报

发表于 2005-11-7 19:33:00 | 显示全部楼层
<P>你的硬件电路是怎么接的啊,EPROM接的地址线多少根啊?把你的接法上传上来啊~~~</P><P>如果接的16根低位地址线的话,EPROM中每个区的大小就是2的16次方,也就是64K,你的图片40K能放下。如果接的地址线小于16的话,就要进行区间的转换,低位接几根地址线,高位就可以用来转换EPROM的区间。我的高位地址线接到了P1口,所以可以通过设定他来选择从EPROM的哪个区读数。</P><P>没有硬件图讲的太抽象了,你可以上传硬件图,让大家分析分析,这个命令跟硬件关系较大~~~</P>
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-5-4 04:45 , Processed in 0.059333 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表