mcs52 ต่อ lcd ไม่ออกช่วยหน่อยนะคะ

Started by Nattida, March 11, 2013, 05:24:30 PM

Previous topic - Next topic

Nattida


[code#include <REG51.H>                /* special function register declarations   */
#include <ABSACC.H>
#include <stdio.h>
#include <intrins.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>


sbit P33 = P3^3;
sbit P34 = P3^4;
sbit P17 = P1^7;
sbit P30 = P3^0;
sbit P15 = P1^5;
sbit P35 = P3^5;
sbit P31 = P3^1;
sbit P14 = P1^4;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit P12 = P1^2;
sbit P16 = P1^6;


unsigned char name[20],asci,key,inum[5];// MEMORY REQUEST 21 BYTE
unsigned int loop,blockinterrupt,page,digit,end_digit,counter;

void delay(int time)
{
    int i;
    for(i=0;i<time;i++)       
    {
    }
}
void lcd_ena (void)                                   
{

    P33=1;
    delay(1000);
    P33=0;
    delay(1000);
    P33=1;

}


void wrt_command(unsigned char com)
{
     P34 = 0;
     P0 = com;
     lcd_ena();
}

void set_add(char addr)
{
     P34 = 0;
     P0 = 0x80|addr;
     lcd_ena();

}

void wrt_data(unsigned char dat)
{
    P34 = 1;
    P0 = dat;
    lcd_ena();

}

void enter(char *str)
{
 
// wrt_command(0x0E);
// IE=0x01;

}

void clear_buffer(unsigned char *str,int num )
{   
   
    int i;
    for(i=0;i<num;i++)
    {   
         str[i]=0;
    }
}
void clear_screen(void)
{
    wrt_command(0x01);  //clear
set_add(0x00);
delay(1000);

}
void show (char *strings)
{
    int i,sl;
    sl=strlen(strings);

    for (i=0;i<sl;i++)
    {
        wrt_data(strings[i]);
        delay(1000);
    }
}



void page0(void)
{   
    clear_screen();
set_add(0x02);
clear_buffer(&name,20);
sprintf(name,"Mass Measuring");
show(name);

set_add(0x43);
clear_buffer(&name,20);
sprintf(name,"KPS Physics");   
show(name);

}

void page1(void)
{   
   
clear_screen();

}


void ascii_in(char index)
{
    if(page==1)
{
    asci=48+key+index;
    wrt_data(asci);          
inum[digit]=asci;
digit++;
end_digit++;
}

}

void check_key(unsigned char key)
{
     if(blockinterrupt==0)
{
switch(key)
{
case 0:  ascii_in(1);        
break;
case 1:  ascii_in(1);
break;
case 2:  ascii_in(1);
break;
case 3: //delete();
       
break;
case 4: ascii_in(0);
break;
case 5: ascii_in(0);
break;
case 6: ascii_in(0);
break;
case 7: //uppage();
         if(page>0)
     page--;  

loop=0;
break;
case 8: ascii_in(-1);
break;
case 9: ascii_in(-1);
break;
case 10: ascii_in(-1);
break;
case 11: //downpage();
         if(page<3)
    page++;

loop=0;   

break;
case 12: ascii_in(-12);
break;
case 13: //left();
       

break;
case 14: //right();
       

break;
case 15: //Enter
        loop=0;
break;
}
      blockinterrupt=1;
}
}
void Inkey(void)
{   
// wrt_command(0x0F);
// delay(1);
   
    blockinterrupt=0;

    while(loop)
    {
       delay(10000);    
    }

}


void count_show(void)
{
   counter=TH1;
   counter<<=8;
   counter|=TL1;

    clear_buffer(name,20);   
    sprintf(name,"%d",counter);
   /*  itoa(counter,name);
    set_add(0x02);   
    show(name);

clear_buffer(name,20);
    sprintf(name,"press Ent key ");
    set_add(0x42);   
show(name); */
   
show("hello");
}
void keyb()interrupt 0
{
key=P1;
key&=0x0F;
    show("test");
check_key(key);

}
void timer0() interrupt 1
{       
    TR0=0;
loop=0;
   // TR1=0;       
/* show("hello"); */
count_show(); 
   
}

int main (void)
{
   
        int i;
        digit=0;

     // P33 = 1;
    // end_digit=0;

        wrt_command(0x3C); // init LCD
        delay(1000);

        wrt_command(0x0E);   // on LCD and cursor
        delay(1000);
       
           
       
        TH0=0x0AA;//68us  50..100..150..200...250
        TL0=0x0AA;
    loop=1;
TMOD=0x0D9;
IE=0x83;
page0();

       for (i=0; i<4; i++)
   { 
      counter=0;     
          if ((i/2)==1)
             P17=1;
          else
     P17=0;

          if((i-(2*(i/2)))==1)
             P16=1;
          else
     P16=0; 
         
             
          TH1=0;
          TL1=0;
          P35=1;
  page1();
          loop=1;
  TH0=0x00;//68us  50..100..150..200...250
          TL0=0x00;
          TR0=1;
           //TR1=1;
         // delay(1);
 
 
          while(loop);
 
      }     
       
while(1);   

}]






หนูคอมไพล์ใน proteus ผ่านค่ะ แต่เวลาที่หนูไปทำในแบบจำลอง ค่ามันไม่ไม่ปรากฎที่ แอลซีดีอ่ะค่ะ ไม่ทราบว่า จะต้องแก้ปัญหาอย่างไรบ้าง
รบกวนช่วยดูให้หน่อยะนะคะ พอดีทำโปรเจคจบอยู่ค่ะ ขอบคุณค่ะ

JENG

สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

humlium

หนูต้องมีรูปประกอบด้วยน่ะคะ เอารูปวงจรใน proteus วงจรจริง รูปของหนูด้วย  ::) แล้วเวลาตั้งชื่อกระทู้ต้องให้มันพอจะบอกได้หน่อยว่ามันเกี่ยวกับอะไร เช่น mcs51 ต่อ lcd ไม่ออกช่วยหน่อยนะคะ เป็นต้น


Nattida

ขอบคุณที่ให้คำแนะนำนะค่ะ

รูปหนูฝากไว้ที่  http://i.imgur.com/yUaDqAg.png?1







JENG

หลักๆจะทำอะไรหรอ ดู source code กับวงจรแล้วเดาไม่ออกจริงๆ
สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

MicroMan

ดูวงจรแล้วไม่น่าจะออก มันมั่วได้ใจมาก พอดีเห็นแค่บางส่วน LCD เอาให้แน่จะต่อทาง Port I/O หรือ จะต่อผ่านระบบบัส
เล่นเอามายำกันแบบนี้ไม่น่าจะออกอยู่แล้ว Data ชนกันมั่ว

- RAM ต้องมีสัญญาณ CS# มาควบคุมด้วย ถ้าเล่น Active CS#,CS ไว้ตลอดเวลาแบบนั้น Address ไหนออก Data ก็โผล่มาตลอดโดยไม่สนใจจังหวะเวลาว่าเป็นช่วงตำแหน่งของตัวเองหรือเปล่า เพราะน้องไม่ได้ออกแบบ กำหนดย่าน address ของการทำงานว่าจะให้ RAM อยู่ตำแหน่งไหน และ LCD อยู่ตำแหน่งไหน
- LCD ถ้าจะต่อผ่านระบบบัส ก็ต้องถอดรหัสตำแหน่ง Address ที่เป็นตำแหน่งเฉพาะเข้ามาควบคุมการเชื่อมต่อ แต่ถ้าจะต่อแบบ I/O ก็ต้องใช้ขาสัญญาณจาก I/O เช่น P1,P3 ไม่ใช้เอา Data มาจากบัส แล้วเอา Pin Port มาควบคุม RS,E แบบนั้น



pa_ul

ไม่ทราบว่าออกแบบวงจรเองรึเปล่าครับ วงจรแบบนี้เรียกว่า memory mapped I/O มีข้อดีหลายอย่าง เช่นทำงานได้เร็ว ขยาย I/O ได้มาก แต่ผู้ออกแบบและผู้เขียนโปรแกรมควบคุมต้องมีความเข้าใจการทำงานและ timing ต่างๆ เป็นอย่างดี เนื่องจากมันจะใช้ timing ในลักษณะเดียวกับการทำงานกับ memory ซึ่งเป็นไปตามการออกแบบตัว MCU ไม่สามารถปรับแต่งใน software ได้

ดูจากวงจร(ที่ขาดส่วน CPU ไป)แล้ว คิดว่าน่าจะทำงานได้ แต่อย่าคิดว่า proteus จะทำได้ทุกอย่างนะครับ มันจะทำได้เฉพาะที่มันถูกออกแบบมาเท่านั้น การต่อวงจรในบางลักษณะอาจจะไม่สามารถซิมูเลทได้ แต่ทำงานจริงๆได้ก็เป็นไปได้นะครับ

ถ้าจะใช้วงจรนี้จริง ต้องศึกษาเรื่อง external RAM access ทั้งในแง่ timing และ คำสั่งใช้งานให้ดี เช่นการกำหนดตำแหน่ง I/O ซึ่งทำผ่าน memory จะต้องกำหนดตัวแปรให้เป็น far pointer หรือ XRAM เพื่อที่จะสามารถ access ไปยังตำแหน่งของ LCD และ RAM ได้อย่างถูกต้อง

AppleIIe

เห็นวงจรแล้ว ท่าน Nattida คงพยายามใช้ I/O ของ MCU ตามปกติ เพราะต่อ LCD(ใช้ P0.0-P0.7 และ P3.3,P3.4) , Keyboard (ใช้ P1.0-P1.3)
และส่วนวัดความถี่ใช้ P1.6-P1.7 , P3.5

แต่ไปต่อ RAM 6264 ทำให้วงจรดูมันสับสน (คิดว่าคงอยากจะขยาย RAM ออกมา) แต่ก็ต่อไม่ครบถ้วนครับ (ไม่เห็นว่าจะ RAM นี้จะ Active อะไรได้เลย เพราะต่อ CS ของ RAM ให้เป็น '1' เฉยๆ ทั้งที่ เขียน Note ว่า Decode ที่ 0000-1FFF )  จึงเดาว่าคงไปเห็นการต่อวงจรการขยายเพิ่ม RAM แล้วนำมาใส่ในวงจรไว้ก่อน ซึ่ง RAM ที่ต่อแบบนี้จะเป็น Memory mapped(ซึ่งใช้ P0.0-7,P2.0-7 และ P3.6,P3.7) ครับ ทำให้วงจรนี้ ทำงานไปใน 2 mode คือ I/O และ Memory Mapped ไปพร้อมๆกัน จึงขอเดาว่าท่าน Nattida ต้องการขยาย RAM และใช้ I/O ได้ตามปกติ แนะนำลองเปลี่ยน RAM 6264 เป็น Serial SRAM เช่น 23K640 แทนจะดีกว่า(มีข้อดีกว่าคือเดินสายน้อยลง แต่ยุ่งยากกว่าตรงเขียนโปรแกรมเพิ่มขึ้นอีก)

ซึ่งแม้การทำงานแบบ I/O และ Memory Map ไปพร้อมๆกันอาจเป็นไปได้ แต่การออกแบบนี้ มันออกจะแปลกนะครับ(ไม่ค่อยมีใครทำกัน) ลองทบทวนวงจรใหม่ดีกว่านะ ว่าจะใช้ I/O หรือแบบ Memory Map กับ MCS51
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด