Thông báo

Collapse
No announcement yet.

Dành cho người mới tìm hiểu 8051

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

  • #31
    Tuy nhiên nếu dùng phương pháp quét led 7 thanh thì số chân vdk cần dùng, công suất cần dùng chỉ bằn như trường hợp ta dùng 1 led 7 thanh mà thôi.Tại mỗi thời điểm chỉ có duy nhất 1 led 7 thanh được bật sáng mà thôi. Nhờ sự lưu ảnh trên võng mạc người mà ta cảm nhận như 6 led 7 thanh này sáng đồng thời nhau, với điều kiện tốc độ quét ảnh >24 hình/1S.
    Đây là sơ đồ mắc 2 led 7 thanh, nếu lắp 6 led 7 thanh thì hoàn toàn tương tự nhau, chỉ việc nối(a->g) của led 7 thanh với(a->g)của con 7447 chung là được.Bạn phải chú ý, khi nối 1 led 7 thanh bạn dùng trở 1 K, nhưng bây giờ để led 7 thanh sáng rõ thì bạn phải thay = 470ohm, điều này bạn có thể dễ dàng giải thích được.
    Thế giới quả là rộng lớn, và có rất nhiều việc phải làm.

    Comment


    • #32
      Bạn thấy đấy bây giờ chúng ta phải dùng thêm mấy con tranzitor A1015, mỗi led 7 thanh dùng thêm 1 con này để mở nó.A1015 là tranzitor thuận,nó mở nếu Ube<0, đóng nếu Ube>=0.Nếu E của nó->5V thì nó mở (thông bão hòa)khi cực B=0v(Mức logic 0), đóng nếu B=5v(mức logic 1).
      Để đơn giản chúng ta sẽ làm vd:hiển thị số 12 trên 2 lad 7 thanh.Cách mắc bạn có thể tham khảo hình vễ trên.Về gải thuật chương trình:Bước 1: hiển thị số 1 trên led 7 thanh đầu tiên từ trái sang(gọi là led1),Bước 2: hiển thị số 2 trên led2.Mỗi led cho hiển thị trong khoảng 5ms.bước 3:quay về bước 1.
      Để hiển thị số 1 trên led 1 ta gửi giá trị số 1qua con giải mã 7447 để yêu cầu nó hiển thị số 1, sau đó bật led1, đồng thời tắt led2.Lúc đó ta nhìn thấy led1 hiển thị sô1 còn led2 tắt.
      Tương tự đối với số 2 trên led2.
      Để bật 1 led nào đó ta cho chân B của A1015 điều khiển led đó=0v(mức O), tắt thì B=5V(mức 1).
      Theo sơ đồ lắp ráp trên , để bạt led1 thì P2_0=0(đồng thời tắt led2 bằng lệnh P2_1=1);bật led2 P2_1=0(đồng thời tắt led1 bằng lệnh P2_0=1);
      Chúng ta xem chương trình vd sau, và xem điều gì xảy ra trên 2 led 7 thanh nhé:
      ___________________________
      //P2_0 dieu khien A1015 mo cho LED1
      //P2_1 dieu khien A1015 mo cho LED2
      #include<regx51.h>
      #define Q0 P1_0
      #define Q1 P1_1
      #define Q2 P1_2
      #define Q3 P1_3
      #define led1 P2_0
      #define led2 P2_1
      //************************************************** ******
      void delay(unsigned int ms)
      {
      unsigned int i,j;
      for (i=0;i<ms;i++)
      for (j=0;j<120;j++)
      {}
      }
      //************************************************** *******
      void display(unsigned char number_dis)
      {
      switch (number_dis)
      {
      case 0:
      Q0=Q1=Q2=Q3=0;
      break;
      case 1:
      Q1=Q2=Q3=0;
      Q0=1;
      break;
      case 2:
      Q1=1;
      Q0=Q2=Q3=0;
      break;
      case 3:
      Q0=Q1=1;
      Q2=Q3=0;
      break;
      case 4:
      Q0=Q1=Q3=0;
      Q2=1;
      break;
      case 5:
      Q1=Q3=0;
      Q2=Q0=1;
      break;
      case 6:
      Q3=Q0=0;
      Q2=Q1=1;
      break;
      case 7:
      Q3=0;
      Q0=Q1=Q2=1;
      break;
      case 8:
      Q3=1;
      Q0=Q1=Q2=0;
      break;
      case 9:
      Q3=Q0=1;
      Q1=Q2=0;
      break;
      default:Q0=Q1=Q2=Q3=0;break;
      }
      }
      //************************************************** *******
      void display_led(unsigned char led,number)
      //'led' cho hien thi tren led nao?led1 hay led2
      //'number'so can hien thi tren led do
      {
      if (led==1)//cho hien thi led thu nhat(led1)
      {led1=0;led2=1;}
      else if (led==2) //cho hien thi led2
      {led2=0;led1=led3=1;}
      display(number);
      }
      //*****************************************
      main()
      {while(1)
      {
      display_led(1,1);//hiển thị số 1 trên led 1
      delay(1000); //trong thời gian là 1s
      display_led(2,2);//hiển thị số 2 trên led 2
      delay(1000); //trong thời gian là 1s

      }
      }
      __________________________________________
      Chúng ta thấy gì nào?led 1 hiển thị số 1 trong 1 s, sau đó led 2 hiển thị số 2.
      Thế giới quả là rộng lớn, và có rất nhiều việc phải làm.

      Comment


      • #33
        Bây giờ bạn giảm dần giá trị trong hàm delay thì chúng ta thấy 2 led này nhấp nháy nhanh dần, đến 1 giá trị khoảng 5ms thì chúng ta thấy 2 led này sáng đồng thời, không còn nhấp nháy nữa.
        Thế giới quả là rộng lớn, và có rất nhiều việc phải làm.

        Comment


        • #34
          hôm nay muộn quá rồi.Hôm sau chúng ta sẽ mở rộng bài toán này hơn nữa nhé, như đếm xuôi, đếm ngược trên 2 led 7 thanh.
          Thế giới quả là rộng lớn, và có rất nhiều việc phải làm.

          Comment


          • #35
            Thử cái này xem :
            cái đồng hồ đếm phút thôi , bằng ASM , không sử dụng IC giải mã , mã hóa số hiển thị trong chương trình (cái này tùy cách nối VDK với Led 7 Seg của từng người va tùy led đó là Anot chung hay Catot chung nữa .)
            --------------------------------------------------

            ORG 0
            ljmp main
            org 000bH
            ljmp time
            org 30h
            main:

            mov r0,#0
            mov r1,#0
            mov r2,#0
            mov r3,#0
            mov TMOD,#01H
            mov TH0,#high(-50000)
            mov TL0,#low(-50000)
            mov IE,#82H ; cho phep ngat time0
            setb tr0
            dis:
            Mov P3,#11111111B
            Mov A,R0
            Mov DPTR,#TAB
            Movc A,@A+DPTR
            Mov P2,A
            CLR P3.0
            Lcall Delay
            Mov P3,#11111111B
            Mov A,R1
            Mov DPTR,#TAB
            Movc A,@A+DPTR
            Mov P2,A
            CLR P3.1
            Lcall Delay
            Mov P3,#11111111B
            Mov A,R2
            Mov DPTR,#TAB
            Movc A,@A+DPTR
            Mov P2,A
            CLR P3.2
            Lcall Delay
            Mov P3,#11111111B
            Mov A,R3
            Mov DPTR,#TAB
            Movc A,@A+DPTR
            Mov P2,A
            CLR P3.3
            Lcall Delay
            sjmp dis

            Delay:
            Mov R4,#10
            back: Mov R5,#250
            loop: Djnz R5,loop
            djnz R4,back
            Ret
            time:
            clr tr0
            inc r7

            acall dem0
            acall dem1
            acall dem2
            acall dem3
            acall dem4
            clr tf0
            mov TH0,#high(-50000)
            mov TL0,#low(-50000)
            setb tr0

            reti
            dem0:
            cjne r7,#20,lap0
            mov r7,#0
            inc r0
            lap0:
            ret

            dem1:
            cjne r0,#10,lap1
            mov r0,#0
            inc r1
            lap1:
            ret
            dem2: cjne r1,#6,lap2
            mov r0,#0
            mov r1,#0
            inc r2
            lap2:
            ret
            dem3: cjne r2,#10,lap3
            mov r0,#0
            mov r1,#0
            mov r2,#0
            inc r3
            lap3:
            ret
            dem4: cjne r3,#10,lap4
            mov r0,#0
            mov r1,#0
            mov r2,#0
            mov r3,#0
            lap4:
            ret
            ORG 300h
            TAB:
            DB 10h,7dh,22h,28h,4dh,88H,80h,3ch,00h,09h
            End
            -----------------
            Trong chương trình chính chỉ là phần hiển thị (quét led) , ngắt timer sẽ tăng các biến đếm và cập nhật số liệu .
            Sorry , mình viết thường ít chú thích nên chắc các bạn mới tiếp cận khó hiểu .
            Chỉ muốn đóng góp thôi .
            Khi dần quen rồi mình nghĩ là các huynh đệ nên tự xây dựng lại từ đầu chương trình nào đó mới mau lên tay , còn các chương trình mẫu tham khảo để biết thuật toán của người ta thôi .

            Comment


            • #36
              Góp vui với mọi người , đây là đoạn chương trình đếm thời gian, dùng thanh ghi dịch 74LS164 để hiển thị LED :

              #include <AT892051.h>
              #include <intrins.h>
              #include <stdio.h>

              #define BYTE unsigned char
              #define WORD unsigned int
              #define LED1 P1_2
              #define LED2 P1_3
              #define LED3 P1_4
              #define LED4 P1_5
              #define Data_164 P1_6
              #define Clock_164 P1_7

              char code Led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x9 0,0xF9,0xFF};

              struct time { /* structure of the time record */
              BYTE hour; /* hour */
              BYTE min; /* minute */
              BYTE sec; /* second */
              };

              BYTE dem,LedCount=0;

              struct time ctime = { 0, 0, 0 }; /* storage for clock time values */

              void Display(BYTE );

              void Tmr1Int() interrupt 3 using 2
              {

              if(++dem==200)
              {
              dem=0;
              if (++ctime.sec == 60)
              { /* calculate the second */
              ctime.sec = 0;
              if (++ctime.min == 60) /* calculate the minute */
              {
              ctime.min = 0;
              if (++ctime.hour == 24) { /* calculate the hour */
              ctime.hour = 0;
              }
              }
              }
              }

              //scan four LED 7 segs
              if (LedCount++ >=4 )
              LedCount=1;

              switch(LedCount)
              {
              case 1:
              Display(Led[ctime.sec%10]);
              LED1=0;
              LED2=1;
              LED3=1;
              LED4=1;
              break;
              case 2:
              Display(Led[ctime.sec/10]);
              LED1=1;
              LED2=0;
              LED3=1;
              LED4=1;
              break;
              case 3:
              Display(Led[ctime.min%10]);
              LED1=1;
              LED2=1;
              LED3=0;
              LED4=1;
              break;
              case 4:
              Display(Led[ctime.min/10]);
              LED1=1;
              LED2=1;
              LED3=1;
              LED4=0;
              break;
              default:
              break;
              }

              TH1=0xEC; // Interrupt 5ms
              TL1=0x78;
              // TH1=0xF4; // Interrupt 3ms
              // TL1=0x48;
              TR1=1;
              }

              /*-------------------
              main code here
              ---------------------*/
              void main()

              {
              TMOD=0x10; // timer1,mode1 (16 bit)
              TH1=0xEC; // Interrupt 5ms
              TL1=0x78;
              ET1=1; // Enable timer1 interrupt
              TR1=1;
              EA=1; //Enable global interrupt
              dem=0;
              LedCount=0;
              while(1) {};
              }

              void Display(BYTE Dulieu)
              {
              BYTE i;
              for(i=0;i<8;i++)
              {
              Data_164=Dulieu & 0x80;
              Dulieu<<=1;
              Clock_164=0; // Clock for '164
              _nop_();
              _nop_();
              Clock_164=1;
              }
              }
              Attached Files
              Last edited by trungkt; 17-11-2005, 16:25.

              Comment


              • #37
                Mình thấy hàm display(unsigned char number) của Quỳnh hơi phức tạp quá chăng. Ta chỉ cần chuyển số đó sang dạng số hex sau đó chuyển cho các chân 0->3 của port1 sau đó con 74LS47 sẽ chuyển sang các chân 1->g của led 7 segment. Tôi xin viết lại chương trình trong đó có tối ưu một vài đoạn mã. Xin các bác cho ý kiến.

                Code:
                #include "reg51x.h"
                // hàm delay
                void delay(unsigned char ms){
                     unsigned char j=120;
                    while(ms--)
                      while(j--){};
                }
                // hàm hiển thị led
                void display(unsigned char number){
                      unsigned char array[4],i;
                      for(i=0;i<4;i++){
                         array[i]=number%2;
                         number/=2;
                      };
                      P1_0=array[0];
                      P1_1=array[1];
                      P1_2=array[2];
                      P1_3=array[3];
                }
                
                // main :
                void main(){
                   unsigned char i;
                   while(1){
                       for(i=0;i<10;i++){
                             display(i);
                             delay(1000);
                       }; 
                   };
                }
                // hết code

                Các bác thấy chương trình đơn giản hơn nhiều hơn không.
                Lưu ý là 74LS47 nếu nối đất vào chân LT thì led luôn hiển thị số 8(8 đầu ra luôn tích mức cao), nối đất chân BI/RB0 thì led hiển thị 0(8 đầu ra luôn tích mức thấp bất kể đầu vào thế nào)
                Last edited by ngohaibac; 25-03-2006, 12:37.
                Technical sale at WT Microelectronics S'pore
                Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                Comment


                • #38
                  hoặc đơn giản hơn là nếu các bác chỉ muốn tiêt kiệm chân mà các chân từ 4->7 không dùng vào việc gì thì đơn giản chỉ cần viết mã là:
                  Code:
                  //display
                  inline void display(unsigned char number){
                  P1=number;
                  }
                  //

                  Tôi thấy thuật giải viết ở bài trước đơn giản có thể dùng triệt để từng chân của port1. Có thể dùng tới 2 led 7 segment( dùng 2 hàm display1 và display2 cũng đơn giản như display).
                  Last edited by ngohaibac; 25-03-2006, 12:38.
                  Technical sale at WT Microelectronics S'pore
                  Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                  Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                  Comment


                  • #39
                    Mình nghĩ giải pháp như thế này là đỉnh nhất, mã dịch ra ngắn,chẳng cần khai báo thêm mảng làm gì cho phức tạp: thực chất bạn Quỳnh làm cho số cần hiển thị với 4 bít đưa ra chẳng liên quan gì với nhau. Thực chất là nó chình là một, một dạng số 4 bít, 1 dạng là số decimal.


                    Code:
                    #include "reg51x.h"
                    // hàm delay
                    void delay(unsigned char ms){
                    unsigned char j=120;
                    while(ms--)
                    while(j--){};
                    }
                    // hàm hiển thị led
                    void display(unsigned char number){
                    P1_0=number%2;num=/2;
                    P1_1=number%2;num=/2;
                    P1_2=number%2;num=/2;
                    P1_3=number%2;num=/2;
                    }
                    
                    // main :
                    void main(){
                    unsigned char i;
                    while(1){
                    for(i=0;i<10;i++){
                    display(i);
                    delay(1000);
                    }; 
                    };
                    }
                    // hết code
                    Last edited by ngohaibac; 25-03-2006, 12:39.
                    Technical sale at WT Microelectronics S'pore
                    Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                    Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                    Comment


                    • #40
                      Hi all!
                      I have just programed a very simple program that makes the led blinking. But something was wrong with this dirty one. Pls tell me why?
                      //This pro make the led blinking every second

                      #include<reg51.h>
                      void delay(unsigned int time)
                      {
                      int i,j;
                      for(i=1;i<=time;i++)
                      {
                      for(j=1;j<=125;j++)
                      {
                      }
                      }
                      }
                      //Main program lies here
                      main()
                      Repeat: P1=0x0; //Turn the led off
                      delay(1000);
                      P1=0xFF; //Turn the led on
                      delay(1000);
                      goto Repeat;
                      }

                      //If i use while(1) to creat the unlimit loop, everything is GOOD, but when I use the command goto to make this loop, It's BAD, led don't glow at all. Pls tell me why?
                      //I am brand-new to 8051. Sorry for my stupid shrug
                      Last edited by walldavist; 01-12-2005, 08:56.

                      Comment


                      • #41
                        Nếu viết như trên thì có lẽ gần như đèn gần như ko sáng do thời gian sáng quá ít. Thử chữa lại thành.
                        main()
                        Repeat:
                        P1=0x0; //Turn the led off
                        delay(1000);
                        P1=0xFF; //Turn the led on
                        delay(1000);//Them vao de sang led có thời gian sáng
                        goto Repeat;

                        Ngoài ra lưu ý các cổng của 8951 khả năng kéo dòng tốt nhưng đẩy dòng rất kém(gần như led ko sáng)(thậm chí cổng P0 là open colector). Vậy nếu bạn ko đệm transistor thì phải mắc theo kiểu sau: nối 5V--->Led--->R=220 omh--->1 chân của cổng P1. Và như vậy thì:
                        P1=0;//Led sáng
                        P1=255;//Led tắt

                        Comment


                        • #42
                          Xin lỗi các bác vì em không thêm dòng delay(1000); vào dòng sau P1=0xFF; để led sáng trong 1s lúc post bài. Thực sự lúc viết trong Keil C em làm đúng như bài của anh Bình anh nhưng khi nạp vào lại không chạy, led chỉ sáng mà không nhấp nháy. Nhưng em để trong while(1) tạo vòng lặp vô hạn thay cho lệnh nhảy thì lại được. Tại sao lệnh nhảy tới repeat của em lại sai nhỉ?

                          Comment


                          • #43
                            ở đây thì lệnh goto tới Repeat tương đương với while(1) mà thôi. Tôi đã debug trong Keil C, chẳng có vấn đề gì cả. Tôi sửa lại mã lại như sau:
                            mỗi vòng while hay for mất 8.28us với tần số thạch anh của 8051 là 11.0592 nên để được 1ms thì cần khoảng 121 lần lặp(121*8.28us =1ms). Bạn thử lại xem nha.

                            ********************
                            Code:
                            #include<reg51.h>
                            void delay(unsigned char time){
                            	unsigned char j=121;
                            	while(time--)
                            		while(j--){};
                            }
                            //Main program lies here
                            void main(){
                            	Repeat: P1=0x0; //Turn the led off
                            	delay(1000);
                            	P1=0xFF; //Turn the led on
                            	delay(1000);
                            	goto Repeat;
                            }
                            // end of code
                            Last edited by ngohaibac; 25-03-2006, 12:36.
                            Technical sale at WT Microelectronics S'pore
                            Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                            Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                            Comment


                            • #44
                              à quên ở trong Keil C. Để bạn có thể hiểu rõ chương trình của mình thì bạn nên debug theo kiểu bình thường với mã C, sau đó hiểu về các câu lệnh Asm tương đương. Bằng cách vào View-> Disassebly Window. Bạn sẽ hiểu được các câu lệnh viết với C trong 8051 xử lí thế nào. Tương đương với ASM. Từ đó bạn có thể viết mã ASM tương đương.
                              Technical sale at WT Microelectronics S'pore
                              Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                              Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                              Comment


                              • #45
                                à quên ở trong Keil C. Để bạn có thể hiểu rõ chương trình của mình thì bạn nên debug theo kiểu bình thường với mã C, sau đó hiểu về các câu lệnh Asm tương đương. Bằng cách vào View-> Disassebly Window. Bạn sẽ hiểu được các câu lệnh viết với C trong 8051 xử lí thế nào. Tương đương với ASM. Từ đó bạn có thể viết mã ASM tương đương. Đây có thể là cách vừa học C vừa học ASM.
                                Technical sale at WT Microelectronics S'pore
                                Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                                Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X