Thông báo

Collapse
No announcement yet.

Giúp mình làm bài tập lớn

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Giúp mình làm bài tập lớn

    Mình có 1 bài tập lớn dùng AT89S52 như sau:
    Thiết kế bộ giao tiếp bàn phím gồm: 1 bàn phím hexa(4 hàng 4 cột), 1 màn hình LCD hiển thị giá trị của các số hexa mỗi khi nhấn phím tương ứng.
    Mình đã tìm dc 1 ít tài liệu nhưng khi gõ trên KeilC thì nó báo lỗi, nhờ các bạn chỉnh sửa giúp mình.
    Attached Files

  • #2
    cái ni là đồng chí chép trong cuốn VDK với ngôn ngữ C, hay đại loại tựa đề như thế , lúc trưa tui ở nhà ku bạn mới đọc wa chỗ này .
    Nếu BT lớn mà chỉ thế này thì wa đơn giản , chỉ 1 buổi là xong . Nhưng u include nhìu hàm có sẵn wa

    Comment


    • #3


      Code:
      #include<AT89S53.h>
      sbit RS = 0x94; // RS = P1_4
      sbit RW = 0x95; // RW = P1_5
      sbit E  = 0x96; // E  = P1_6
      
      void delay_ms( unsigned int ms )
      { unsigned int i,j;
        for (i=0;i<ms;i++)
        for (j=0;j<120;j++){};
      }
      
      void LCD_PutChar(unsigned char k )
      { P2=k ; RS=1 ; RW=0 ; E=1 ; E=0 ; delay_ms(1);}
        
      
      void LCD_PutCmd(unsigned char k )
      { P2=k ; RS=0 ; RW=0 ; E=1 ; E=0 ; delay_ms(3);}
        
      
      void int_LCD()
      { 
        LCD_PutCmd(0x38) ;	   
        LCD_PutCmd(0x0C) ;
        LCD_PutCmd(0x06) ;
        LCD_PutCmd(0x01) ;
      }
      
      void quetphim_hienthi()
      { 
        P1_0=0;P1_1=P1_2=P1_3=1; 	
        if (P0_0==0) { delay_ms(50);            
                       while(P0_0==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('0');a = '0';
                     } ;
        if (P0_1==0) { delay_ms(50);            
                       while(P0_1==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('4');a = '4';
                     } ;
        if (P0_2==0) { delay_ms(50);            
                       while(P0_2==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('8');a = '8';
                     } ;
        if (P0_3==0) { delay_ms(50);            
                       while(P0_3==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('C') ; a = 'C';
                     } ;
      
        P1_0=P1_2=P1_3=1;P1_1=0;
        if (P0_0==0) { delay_ms(50);            
                       while(P0_0==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('1');a = '1';
                     } ;
        if (P0_1==0) { delay_ms(50);            
                       while(P0_1==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('5'); a = '5';
                     } ;
        if (P0_2==0) { delay_ms(50);            
                       while(P0_2==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('9');a = '9';
                     } ;
        if (P0_3==0) { delay_ms(50);            
                       while(P0_3==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('D') ;a = 'D';
                     } ;
        
       P1_0=P1_1=P1_3;P1_2=0;
       if (P0_0==0)  { delay_ms(50);            
                       while(P0_0==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('2'); a = '2';
                     } ;
       if (P0_1==0) {  delay_ms(50);            
                       while(P0_1==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('6');a = '6';
                    } ;
       if (P0_2==0) {  delay_ms(50);            
                       while(P0_2==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('A');a = 'A';
                    } ;
       if (P0_3==0) {  delay_ms(50);            
                       while(P0_3==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('E');a = 'E';
                    } ;
      
       P1_0=P1_1=P1_2=1;P1_3=0;; 	
       if (P0_0==0) {  delay_ms(50);            
                       while(P0_0==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('3');a = '3';
                    } ;
       if (P0_1==0) {  delay_ms(50);            
                       while(P0_1==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('7');a = '7';
                     } ;
       if (P0_2==0) {  delay_ms(50);            
                       while(P0_2==0) continue ;
                       delay_ms(20);
                       LCD_PutChar('B');a  = 'B';
                    } ;
       if (P0_3==0) {  delay_ms(50);            
                       while(P0_3==0) continue ;
                       delay_ms(20);
                       LCD_PutCmd(0x01) ;		   // clearscreen
                       LCD_PutCmd(0x80) ;
      				 a = 0;
      			  } ;
      }
      
      main()
      { 
        P0 = 0xFF ; 
        P1 = 0xFF ;
        delay_ms(100);
        int_LCD();
        LCD_PutCmd(0x85) ;
       while(1) quetphim_hienthi();
      Tui ngồi viết cho u lun đó, bỏ vô mạch test thử xem ! Tui viết chay , chứ chưa test chương trình đâu nha

      Comment


      • #4
        vào đây mà xem, chẳng có include cái j hết: http://08tdt.com/forum/showthread.php?t=20&page=2

        hoặc tham khảo file đính kèm nha;

        copy cái file lcd.c vào C:\Keil\C51\INC
        Attached Files

        Comment


        • #5
          Nguyên văn bởi Zz_Bi_zZ Xem bài viết
          cái ni là đồng chí chép trong cuốn VDK với ngôn ngữ C, hay đại loại tựa đề như thế , lúc trưa tui ở nhà ku bạn mới đọc wa chỗ này .
          Nếu BT lớn mà chỉ thế này thì wa đơn giản , chỉ 1 buổi là xong . Nhưng u include nhìu hàm có sẵn wa
          Lời đầu tiên mình xin chân thành cảm ơn hai bạn đã giúp đỡ
          Bạn Zz_Bi_zZ nói đúng lắm, trình độ của mình chỉ ở mức "ai cho gì ăn nấy" chứ tự viết chương trình thì chắc po' tay. Thế nên rất mong các bạn giúp đỡ

          Comment


          • #6
            Nguyên văn bởi Zz_Bi_zZ Xem bài viết
            Tui ngồi viết cho u lun đó, bỏ vô mạch test thử xem ! Tui viết chay , chứ chưa test chương trình đâu nha
            Bạn Zz_bi_zZ ơi cho mình hỏi cái sao trong mạch của bạn lại có con max 232 và cổng ISP vậy. Mình phải nạp chương trình cho chip trước rồi mới cho lên mạch chứ.
            Bài của bạn mình cho vào KeilC thì ko tạo dc file hex. Nó báo biến a chưa khai báo nên mình thêm "char a;" và 1 dấu } ở cuối thì nó tạo dc file hex rồi nhưng mô phỏng thì ko dc
            Dưới đây là bài mình làm theo bài bạn hướng dẫn, bạn vui lòng sửa giúp mình với
            Attached Files

            Comment


            • #7
              Nguyên văn bởi tranpic Xem bài viết
              vào đây mà xem, chẳng có include cái j hết: http://08tdt.com/forum/showthread.php?t=20&page=2

              hoặc tham khảo file đính kèm nha;

              copy cái file lcd.c vào C:\Keil\C51\INC
              Chào bạn tranpic, mình đã tải bài của bạn về và thử và thấy mô phỏng rất tốt.
              Tuy nhiên chữ A và D thì ko hiển thị dc. Mình vào file lcd.c bỏ các dấu // ở trước phần của chữ A và D thì toàn bộ các kí tự đều ko hiển thị dc.
              Mình cũng ko hiểu nếu sửa bất kì chỗ nào trong bài của bạn, ví dụ như chữ LCD+keypad trong 16_6.c thì đều mô phỏng ko thành công. Chỉ có giữ nguyên như bài bạn đã làm thì mô phỏng dc nhưng thật tiếc là ko có chữ A và D.
              Rất cảm ơn bạn đã giúp đỡ và mong bạn tiếp tục sửa lỗi cho mình

              Comment


              • #8
                Nguyên văn bởi nguoiphuxe8x Xem bài viết
                Chào bạn tranpic, mình đã tải bài của bạn về và thử và thấy mô phỏng rất tốt.
                Tuy nhiên chữ A và D thì ko hiển thị dc. Mình vào file lcd.c bỏ các dấu // ở trước phần của chữ A và D thì toàn bộ các kí tự đều ko hiển thị dc.
                Mình cũng ko hiểu nếu sửa bất kì chỗ nào trong bài của bạn, ví dụ như chữ LCD+keypad trong 16_6.c thì đều mô phỏng ko thành công. Chỉ có giữ nguyên như bài bạn đã làm thì mô phỏng dc nhưng thật tiếc là ko có chữ A và D.
                Rất cảm ơn bạn đã giúp đỡ và mong bạn tiếp tục sửa lỗi cho mình
                xin lỗi bạn file lcd.c mình có sửa chút để làm việc khác nhưng quên chưa chỉnh lại, bạn chỉ cần chỉ lại như sau là ok

                #include<AT89X52.h>
                const unsigned char clr=1,home=2,d_on=15,set=56,d_off=12;
                sbit rs=P2^0; //P2_0
                sbit rw=P2^1; //P2_1
                sbit e=P2^2; //P2_2
                sbit li=P2^3; //P2_3

                //chuong trinh con tao thoi gian tre
                void delay(unsigned int time)
                {
                unsigned int x,y;
                for(x=0;x<time;x++)
                {
                for(y=0;y<33;y++);
                }
                }
                //-------------------------------------------------------

                //chuong trinh con kiem tra lcd co ban ko
                void busy()
                {
                rs=0;
                rw=1;
                P0_7=1;
                while(P0_7!=0)
                {
                e=0;
                e=1;
                }
                }
                //--------------------------------------------------------

                //chuong trinh con xuat lenh len LCD
                void lenh(unsigned char ma)
                {
                busy();

                rs=0;
                rw=0;
                e=1;
                P0=ma;
                e=0;
                }
                //---------------------------------------------------------

                //chuong trinh con xuat du lieu len LCD
                void dat(unsigned char ma)
                {
                busy();

                rs=1;
                rw=0;
                e=1;
                P0=ma;
                e=0;
                }
                //----------------------------------------------------------

                //chuong trinh di chuyen con tro
                void mov(unsigned char row, unsigned char col)
                {
                lenh(128 | (row << 6) | col); //row =0 la hang dau,=1 la hang 2
                }
                //---------------------------------------------------------

                //chuong trinh xuat ra LCD mot chuoi ki tu
                void dat_str(unsigned char *str)
                {
                while (*str!='\0')
                {
                dat(*str);
                str++;
                }
                }
                //----------------------------------------------------------

                //chuong trinh con cai dat LCD
                void int_lcd()
                {
                delay(30); //doi
                lenh(set); //8bit, 2 line
                //lenh(d_on); //display on, cursor on,blinking on
                lenh(d_off); //display on,cursor off,blinking off
                lenh(clr); //clear display
                lenh(home); //return home
                }
                //----------------------------------------------------------

                //chuong trinh giai ma ma tran phim
                unsigned char key()
                {
                char k=0,x=0,c=0;
                for(k=0;k<4;k++)
                {
                P0=~(1<<k);//muốn gắn bàn phím vào Port nào thì thay mấy chỗ này thành port đó còn vị trí các số của phím nhấn có thể thay đổi ở c='x';
                x=P0>>4;
                if(x!=15)
                {
                switch (P0)
                {
                case 238:
                c='0';
                break;

                case 237:
                c='1';
                break;

                case 235:
                c='2';
                break;

                case 231:
                c='3';
                break;

                //------------------------------------------

                case 222:
                c='4';
                break;

                case 221:
                c='5';
                break;

                case 219:
                c='6';
                break;

                case 215:
                c='7';
                break;

                //-----------------------------------------

                case 190:
                c='8';
                break;

                case 189:
                c='9';
                break;

                case 187:
                delay(100);
                c='A';
                break;


                case 183:
                c='B';
                break;
                // //---------------------------------------

                case 126:
                c='C';
                break;

                case 125:
                delay(100);
                c='D';
                break;


                case 123:
                delay(100);
                c='E';
                break;

                case 119:
                c='F';
                break;
                }
                }
                }
                return c;
                }
                //----------------------------------------------------------

                Comment


                • #9
                  Cảm ơn bạn nhiều nhiều nha. MÌnh cũng phải viết cả báo cáo nữa nên nếu bạn ko phiền thì nhờ bạn giải thích hộ mấy phần ko hiểu trong chương trình của bạn.
                  - const unsigned char clr=1,home=2,d_on=15,set=56,d_off=12;
                  dòng lệnh trên với các chỉ số ấy là có ý nghĩa thế nào hả bạn
                  - case 238:
                  cái chỉ số 238 là mã bàn phím hả bạn, cái này lấy ở đâu đấy
                  - case 125:
                  delay(100);
                  c='D';
                  break;
                  sao 1 số dòng case bạn để delay còn dòng khác thi ko

                  Cuối cùng xin cảm ơn bạn 1 lần nữa

                  Comment


                  • #10
                    Nguyên văn bởi nguoiphuxe8x Xem bài viết
                    Bạn Zz_bi_zZ ơi cho mình hỏi cái sao trong mạch của bạn lại có con max 232 và cổng ISP vậy. Mình phải nạp chương trình cho chip trước rồi mới cho lên mạch chứ.
                    Bài của bạn mình cho vào KeilC thì ko tạo dc file hex. Nó báo biến a chưa khai báo nên mình thêm "char a;" và 1 dấu } ở cuối thì nó tạo dc file hex rồi nhưng mô phỏng thì ko dc
                    Dưới đây là bài mình làm theo bài bạn hướng dẫn, bạn vui lòng sửa giúp mình với
                    - u bỏ con max đó đi , vì lúc trước làm giúp ku bạn , mạch nó có giao tiếp PC nên cần max232 .
                    - cổng ISP là để mạch cho 89S , chỉ có dòng 89Sxx mới có thể nạp chip trực tiếp trên mạch , có nghĩa u ko cần tháo chip ra khỏi mạch khi cần nạp ct . khỏe ko ?
                    - trong ct trên , tui dùng biến a để lưu số đã nhấn , với u thì xóa lun biến a đó đi . ok ?

                    Comment


                    • #11
                      Nguyên văn bởi nguoiphuxe8x Xem bài viết
                      Cảm ơn bạn nhiều nhiều nha. MÌnh cũng phải viết cả báo cáo nữa nên nếu bạn ko phiền thì nhờ bạn giải thích hộ mấy phần ko hiểu trong chương trình của bạn.
                      - const unsigned char clr=1,home=2,d_on=15,set=56,d_off=12;
                      dòng lệnh trên với các chỉ số ấy là có ý nghĩa thế nào hả bạn
                      - case 238:
                      cái chỉ số 238 là mã bàn phím hả bạn, cái này lấy ở đâu đấy
                      - case 125:
                      delay(100);
                      c='D';
                      break;
                      sao 1 số dòng case bạn để delay còn dòng khác thi ko

                      Cuối cùng xin cảm ơn bạn 1 lần nữa

                      0x01 : xóa màn hình LCD
                      0x02 : đưa con trỏ về đầu dòng
                      .... u lật sách Cấu trúc & lập trình VDK 8051( Ng Tăng Cường & Phan Quốc Thắng ) trang 189 , sẽ thấy có 1 bảng giá trị dc liệt kê cho LCD
                      - case xxx : có nghĩa trừong hợp xxx thì bạn làm cái chi đó , chứ ko phải mã phím đâu

                      Comment


                      • #12
                        Nguyên văn bởi Zz_Bi_zZ Xem bài viết
                        0x01 : xóa màn hình LCD
                        0x02 : đưa con trỏ về đầu dòng
                        .... u lật sách Cấu trúc & lập trình VDK 8051( Ng Tăng Cường & Phan Quốc Thắng ) trang 189 , sẽ thấy có 1 bảng giá trị dc liệt kê cho LCD
                        - case xxx : có nghĩa trừong hợp xxx thì bạn làm cái chi đó , chứ ko phải mã phím đâu
                        Thank Bi đã giúp mình
                        Rất tiếc mình chưa có cuốn ấy như Bi bảo, Bi có tài liệu gì về lập trình C cho 8051 thì up lên đi.
                        Còn cai case xxx thì mình muốn hỏi cái xxx ấy lấy ở đâu ra và ý nghĩa thế nào chứ tự nhiên viết ngay dc thế thế nào dc

                        Comment


                        • #13
                          Bi ơi mình đã bỏ biến a như Bi bảo nhưng mô phỏng trên proteus vẫn chưa dc
                          Bi vui lòng xem lại hộ mình tí

                          Comment


                          • #14
                            Bạn tranpic ơi, nhờ bạn giải thích hộ mình một chút về bài chút về bài làm của bạn
                            - Mình thấy có đứa nói nếu dùng Port 0 để chỉ nhập hoặc chỉ xuất thì ko cần 8 con điện trở nối lên nguồn như trong mạch bạn vẽ, còn nếu dùng Port 0 để cả nhập lẫn xuất thì cần 8 con điện trở nối lên nguồn như của bạn. Mong bạn giải thích thêm chỗ này vì sao nó lại thế.
                            - Nhờ bạn giải thích thêm đoạn code này trong bài của bạn, mình xem mà ko hiểu
                            unsigned char key()
                            {
                            char k=0,x=0,c=0;
                            for(k=0;k<4;k++)
                            {
                            P0=~(1<<k);
                            x=P0>>4;
                            if(x!=15)
                            Thanks bạn nhiều nhiều

                            Comment


                            • #15
                              Nguyên văn bởi nguoiphuxe8x Xem bài viết
                              Bạn tranpic ơi, nhờ bạn giải thích hộ mình một chút về bài chút về bài làm của bạn
                              - Mình thấy có đứa nói nếu dùng Port 0 để chỉ nhập hoặc chỉ xuất thì ko cần 8 con điện trở nối lên nguồn như trong mạch bạn vẽ, còn nếu dùng Port 0 để cả nhập lẫn xuất thì cần 8 con điện trở nối lên nguồn như của bạn. Mong bạn giải thích thêm chỗ này vì sao nó lại thế.
                              - Nhờ bạn giải thích thêm đoạn code này trong bài của bạn, mình xem mà ko hiểu
                              unsigned char key()
                              {
                              char k=0,x=0,c=0;
                              for(k=0;k<4;k++)
                              {
                              P0=~(1<<k);
                              x=P0>>4;
                              if(x!=15)
                              Thanks bạn nhiều nhiều
                              à thế này nhé, bạn hãy cố gắng đọc datasheet của 89 nha, P0 là cực thu hở, tuỳ vào ứng dụng mà bạn gắn hay ko gắn điện trở kéo lên.

                              giải thích code:

                              đây là chương trình con dùng để quét phím và có trả về giá trị(là mã ascii của phím được nhấn để xuất lên lcd)

                              ở đây mình sử dụng 4 chân P0.0->P0.3 để quét, và quét ở mức thấp,
                              sau mỗi lần cho 1 chân (P0.0->P0,3) xuống mức thấp thì kiểm tra xem có phím nào nhấn ko : bằng cách xem các chân P0.4->P0.7 có xuống mức thấp ko, nếu có tức có phím được nhấn, nếu ko thì ko có phím nào được nhấn cả.


                              như vậy chương trình được viết như sau:
                              unsigned char key()
                              {
                              char k=0,x=0,c=0;
                              for(k=0;k<4;k++) //vòng lặp 4 lần vì quét 4 chân
                              {
                              P0=~(1<<k);//cho 1 dịch trái k lần ta sẽ được các giá trị 00000001(k=0),00000010(k=1),00000100(k=2),00001000 (k=3), nhưng ta cần đưa chân quét xuống mức 0 nên phải lấy bù các giá trị ở trên rồi gán cho P0. khi đó các giá trị là 11111110(k=0),11111101(k=1),11111011(k=2),11110111 (k=3),
                              x=P0>>4;//lấy ra các bit cao của P0 để kiểm tra xem có phím nào được nhấn ko.
                              if(x!=15)//nếu có phím được nhấn tức x khác 1111(15)

                              Comment

                              Về tác giả

                              Collapse

                              nguoiphuxe8x Tìm hiểu thêm về nguoiphuxe8x

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X