Thông báo

Collapse
No announcement yet.

viết Function có chức năng như hàm DA( trong ASM) trong C cho 8051

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

  • viết Function có chức năng như hàm DA( trong ASM) trong C cho 8051

    như các bạn đã biết thì khi lập trình cho 8051 thì trong ASM có hàm DA A, là hàm hiệu chỉnh thập phân giá trị HEX trong thanh chứa A, giá trị này là phép cộng của 2 số BCD gói trước đó.

    Ví dụ viết bằng ASM chẳng hạn,
    MOV A,56H ;
    ADD A,67H ; 56h +67h = BDh , sau lenh nay cờ nhớ CF và cờ nhớ fụ AF
    ; đều được set bằng 1.

    AD A ; hiệu chỉnh thập phân já trị BDh trong thanh chứa A thành 23h
    Thực ra là mình đang cần đếm lùi và hiển thị ra Led 7 thanh qua IC 7447 nên cần lưu thông tin trên port 8 bit dưới dạng BCD gói, 4 bit cao từ 4 - 7 qua IC 7447 đưa ra LED 7 thanh thành số hàng đơn vị...4 bit thấp 0-3 là số hàng chục. do vậy cần có hàm tương tự như AD để hiệu chỉnh thập fân nhằm đưa ra hiển thị trên LED 7 thanh

    Thuật toán hiệu chỉnh như sau:
    ví dụ Port1 đang chứa kết quả fép cộng 2 số BCD :
    IF((P4-P7)>9 AND (AF=1)) THEN (P4-P7)<-(p3-P7)+6 (hàng đơn vị)
    IF((P0-P3)>9 AND (CF=1)) THEN (P0-P3)<-(p0-P3)+6 ( hàng chục )

    Mình đang cần viết trong C một Function cũng có chức năng tương tự như hàm DA trong ASM nhưng chưa biết xây dựng cấu trúc hàm cũng như truyền tham số. MOng các bạn giúp mình với

    Cảm tạ !!
    |

  • #2
    Thuật toán hiệu chỉnh như sau:
    ví dụ Port1 đang chứa kết quả fép cộng 2 số BCD :
    IF((P4-P7)>9 AND (AF=1)) THEN (P4-P7)<-(p3-P7)+6 (hàng đơn vị)
    IF((P0-P3)>9 AND (CF=1)) THEN (P0-P3)<-(p0-P3)+6 ( hàng chục )
    - Bạn không cần phải xây dựng thuật toán như là asm đâu. Trong C xử lý vấn đề này rất đơn giản. Giả sử phần cứng bạn nối 4 đầu vào của 7447 với port0 tương ứng là p0.0-->p03. thì chương trình bạn chỉ cần tách lấy số hàng đơn vị và số hàng chục rồi out dữ liệu ra port0 bình thường thôi.
    - Ví dụ chương trình mẫu thế này:
    ...
    unsigned char hangchuc,hangdonvi;
    ....
    void xuly(unsigned char byte)
    {
    hangchuc = byte/10;//tach lay hang chuc
    hangdonvi = byte%10;//tach lay hang don vi
    }
    ...
    void Display()
    {
    P0 = hangdonvi;
    Digit1 = 0;//Bat Led hang don vi
    Delay();//trong thời gian nào đó
    Digit1 = 1;//Tat Led hang don vi
    P0 = hangchuc;
    Digit2 = 0;//Bat Led hang chuc
    Delay();//trong thời gian nào đó
    Digit2 = 1;//Tat Led hang chuc
    }
    - Nếu bạn nối 4 đầu vào của 7447 với 4 bít cao của port0 thì trước khi out ra port0 bạn dịch hàng đơn vị và hàng chục sang trái 4 bít.
    void xuly(unsigned char byte)
    {
    hangchuc = byte/10;//tach lay hang chuc
    hangchuc = hangchuc << 4; //đưa nội dung lên 4 bít cao
    hangdonvi = byte%10;//tach lay hang don vi
    hangdonvi = hangdonvi << 4;//đưa nội dung lên 4 bít cao
    }
    Bạn thử xem có được không nhé.

    Thân mến,
    For a better world

    Comment


    • #3
      lại là người ae Toan.Lv trước hết chân thành cảm ơn bạn Toan.Lv đã luôn nhiệt tình jải đáp những thắc mắc của mình

      mình đã viết theo code ASM nhưng khi nạp vào vi điều khiển thì ko hiẻu sao mạch ko chạy mặc dù mình mô phỏng Proteus đã chạy ngon lành .. hỏi mấy ôg chú thì các ôg ý bảo toàn viết bằng C và cảm thấy C cũng dễ jám sát hơn nên mình quyết định chuyển sang C
      sau đây mình xin trích dẫn một đoạn trong code ASM của mình:
      DOAN11:
      PUSH ACC
      PUSH 00H
      PUSH 01H
      MOV R2,#35H
      MOV R1,#31H
      MOV P2,#00H
      LABEL:
      MOV P0,R2
      MOV P1,R1
      SETB DO1
      SETB XANH2
      LCALL DELAY
      MOV A,R2
      ADD A,#99H
      DA A
      MOV R2,A
      MOV A,R1
      ADD A,#99H
      DA A
      MOV R1,A
      CJNE R1,#99H,LABEL
      POP 01H
      POP 00H
      POP ACC
      RET
      |

      Comment


      • #4
        đoạn chưog trình này nạp vào P1 já trị tức thời 35H, P2 já trị 31H( để ở dạng BCD gói nhằm hiển thị LED 7 thanh qua con 7447) cái vòng lặp LABEL thực hiện đếm lùi dần cá já trị và xuất ra hiển thị
        cặp lệnh
        ADD A,#99H
        DA A
        thực chất là để đếm lùi và hiệu chỉnh thành já trị BCD biểu diễn kết quả thập fân chính xác.ví dụ khi A đang chưa 28H thì ADD A,99H sẽ cho A chứa já trị C8h nhưng tiêp theo lệnh DA A sẽ hiệu chỉnh C8H thành 28H(theo thuật toán ở trên).. ( BCD gói biểu diễn số thập fân 28 là kết quả của fép trừ thập fân 29-1) rồi xuất 4 bit cao ra 1 con LED 7 thanh biểu diễn số 8, 4 bit thấp ra 1 con led 7 thanh biểu diễn số 2
        như vậy ý mình làmuốn xây dựng 1 hàm có chức năng tương tự như hàm DA đó trong C
        |

        Comment


        • #5
          Mình thắc mắc bài viết của bạn ở chỗ :
          thứ nhất:
          void xuly(unsigned char byte)
          {
          hangchuc = byte/10;//tach lay hang chuc
          hangdonvi = byte%10;//tach lay hang don vi
          }
          nếu thế này thì ví dụ PO đang lưu dữ liệu là 38H (48d) thì 30H/10 = 4 , tức là 0100 cơ mà bạn , khi đưa qua 7447 lên LED sẽ hiển thị số 4
          thứ 2:
          void Display()
          {
          P0 = hangdonvi;
          Digit1 = 0;//Bat Led hang don vi
          Delay();//trong thời gian nào đó
          Digit1 = 1;//Tat Led hang don vi
          P0 = hangchuc;
          Digit2 = 0;//Bat Led hang chuc
          Delay();//trong thời gian nào đó
          Digit2 = 1;//Tat Led hang chuc
          }
          mình không hiểu cái hàm Display này sẽ hiển thị như thế nào .. tức là hiện thị xong chữu số hàng đơn vị rồi mới hiển thị chữu số hàng chục à, ??? số đếm của mình là số có 2 chữ số cơ mà bạn mình cũng ko hiểu ý bạn lắm hay bạn chưua hiểu ý mình hỏi nhỉ
          mong ngừoi ae jải đáp hộ mình
          |

          Comment


          • #6
            Có lẽ ý của machithanh là đưa dữ liệu ra thẳng 7447 qua cổng P0 (chứ o phải là quét?). Thế thì sau khi tách ra làm hangchuc và hangdonvi thì ta có thể:
            P0=(hangchuc<<4)|hangdonvi;
            !e

            Comment


            • #7
              PO đang lưu dữ liệu là 38H (48d) thì 30H/10 = 4 , tức là 0100 cơ mà bạn , khi đưa qua 7447 lên LED sẽ hiển thị số 4
              - Đầu tiên bạn lưu ý rằng hệ đếm 16, BCD, hay thập phân thì cũng là các cách biểu diễn khác nhau của cùng một giá trị. Ví dụ 30H trong hệ 16 thì cũng là 48 trong hệ 10, và là 0100 1000 trong BCD. Chúng đều biểu diễn cho một giá trị.
              - Giá trị hiển thị ra Led 7 thanh là ở hệ thập phân, gồm có các chữ số hàng đơn vị, hàng chục,...Bạn muốn hiển thị một byte ra Led 7 thanh thì bạn tách riêng hiển thị số hàng đơn vị và số hàng chục theo thuật toán ở trên.
              mình không hiểu cái hàm Display này sẽ hiển thị như thế nào
              - Nguyên tắc của quét Led 7 thanh là tại một thời điểm bạn chỉ có thể điều khiển cho sáng một digit. Bạn cho nó sáng trong một thời gian đủ dài để mắt ta có thể thấy sau đó phải tắt đi và bật digit khác lên. Vòng quét của bạn phải kéo dài liên tục trong một thời gian nào đó, thì bạn sẽ thấy 2 digit như sáng cùng một lúc. Tuy nhiên thực tế tại một thời điểm chỉ có một digit sáng mà thôi.

              - Chương trình Display tôi viết dưới dạng hàm con, khi sử dụng bạn có thể đưa nó vào vòng lặp vô tận hoặc dùng ngắt timer hoặc gọi nó ở đâu đó. Muốn hiển thị được 2 chữ số trên Led 7 thanh, bạn phải gọi liên tục hàm này (vòng lặp vô tận) hoặc cứ sau một thời gian bạn phải gọi nó một lần (ngắt timer).
              - Để hiểu rõ hơn về quét Led 7 thanh, bạn có thể tìm hiểu thêm trên diễn đàn.

              Thân mến,
              For a better world

              Comment


              • #8
                Có lẽ ý của machithanh là đưa dữ liệu ra thẳng 7447 qua cổng P0 (chứ o phải là quét?)
                - Cảm ơn đại hiệp dế mèn đã nhắc nhở. Tại tại hạ chỉ nghĩ đến trường hợp bạn machithanh sử dụng 1 con 7447 để hiển thị cho nhiều digit nên phải quét.
                - Nếu bạn machithanh sử dụng 2 con 7447 nối riêng rẽ với digit hàng chục và digit hàng đơn vị, như vậy cùng một lúc bạn có thể out ra số có 2 chữ số được. Nhưng mà nếu không quét thì cần phải thêm con chốt dữ liệu ở đầu ra của 7447 thì phải, vì hình như thằng 7447 nó không chốt được dữ liệu, tại hạ không nhớ rõ. Nhờ đại hiệp dế mèn đính chính lại giùm.

                To machithanh:
                - 7447 có 4 đường vào A B C D như thế nó có tối đa 16 tổ hợp đầu vào khác nhau. Ứng với mỗi tổ hợp đầu vào chỉ có 1 tổ hợp đầu ra xác định. Vì vậy nếu bạn nối chung 7 đường dữ liệu của digit hàng chục và digit hàng đơn vị với đầu ra của 1 con 7447 thì bạn chỉ có thể hiển thị được cùng một số trên 2 digit tại một thời điểm. Không thể hiển thị được 2 số khác nhau đâu. Nếu muốn hiển thị 2 số khác nhau thì phải quét.
                - Ngoài ra nếu sử dụng 7447 thì bạn không thể điều khiển được dấu chấm của Led 7 thanh, vì 7447 chỉ có 7 đầu ra thôi.

                Theo tôi thì nếu quet Led 7 thanh thì bạn cứ nối các đầu dữ liệu của LED 7 thanh vào port của VDK qua trở hạn dòng và quét là được.

                Thân mến,
                For a better world

                Comment


                • #9
                  Có lẽ ý của machithanh là đưa dữ liệu ra thẳng 7447 qua cổng P0 (chứ o phải là quét?)
                  Nếu bạn machithanh sử dụng 2 con 7447 nối riêng rẽ với digit hàng chục và digit hàng đơn vị, như vậy cùng một lúc bạn có thể out ra số có 2 chữ số được
                  đây là hình minh họa của mình , 4 bit thấp của port 0 là một số BCD gói xuất ra LED 7 thanh thể hiện chữ số hàng đơn vị ( chữ số 2 trong hình), 4 bit cao làm thành số hàng chục ( chữ số 4 trong hình)
                  mạch của mình sẽ đếm lùi và hiển thị
                  mình la machithanh
                  Attached Files
                  Last edited by hoang_dttd; 05-05-2009, 14:02.

                  Comment


                  • #10
                    Nhưng mà nếu không quét thì cần phải thêm con chốt dữ liệu ở đầu ra của 7447 thì phải, vì hình như thằng 7447 nó không chốt được dữ liệu, tại hạ không nhớ rõ. Nhờ đại hiệp dế mèn đính chính lại giùm.
                    hình như người ae Toan.Lv nhớ nhầm hay sao ý chứ mình có dùng bộ chốt j đâu mà nó vẫn xuất ra ngon lành mà . Nhưng mà mình viết code ASM thì mô fongr ngon nhưng mạch thật thì loạn lắm...mình chuyển sang code C thì mạch ổn định hơn nhưng đang vướng ở chỗ hàm hiệu chỉnh thập phân kết quả thôi
                    ko hiểu các ae đã hiểu ý mình hỏi chưa nhỉ
                    mình la machithanh
                    Last edited by hoang_dttd; 05-05-2009, 14:01.

                    Comment


                    • #11
                      hình như người ae Toan.Lv nhớ nhầm hay sao ý chứ mình có dùng bộ chốt j đâu mà nó vẫn xuất ra ngon lành mà . Nhưng mà mình viết code ASM thì mô fongr ngon nhưng mạch thật thì loạn lắm...mình chuyển sang code C thì mạch ổn định hơn nhưng đang vướng ở chỗ hàm hiệu chỉnh thập phân kết quả thôi
                      ko hiểu các ae đã hiểu ý mình hỏi chưa nhỉ
                      - Chắc là tôi nhầm, bởi vì khi làm với LED 7 thanh, tôi toàn phang thẳng vào port thôi chứ ít khi dùng 7447 lắm. chỉ nhớ mang máng thôi. Với cả tui toàn làm với VXL, ít khi làm với IC số, nên cũng ít đụng chạm tới con này.

                      Nhưng mà mình viết code ASM thì mô fongr ngon nhưng mạch thật thì loạn lắm...mình chuyển sang code C thì mạch ổn định hơn nhưng đang vướng ở chỗ hàm hiệu chỉnh thập phân kết quả thôi
                      ko hiểu các ae đã hiểu ý mình hỏi chưa nhỉ
                      - Việc chương trình chạy sai không phải lỗi do ngôn ngữ lập trình đâu, nó chỉ sai do phần cứng mình thiết kế sai hoặc phần mềm chưa đúng thuật toán thôi.
                      - Còn việc hiệu chỉnh thì bạn cứ tách lấy số hàng chục và số hàng đơn vị rồi out ra port là được.

                      Bạn thử lại xem có được không.

                      Thân mến,
                      For a better world

                      Comment


                      • #12
                        - Còn việc hiệu chỉnh thì bạn cứ tách lấy số hàng chục và số hàng đơn vị rồi out ra port là được.
                        hình như h mình đã hiểu ý của bạn Toan.Lv
                        PO đang lưu dữ liệu là 38H (48d) thì 30H/10 = 4 , tức là 0100 cơ mà bạn , khi đưa qua 7447 lên LED sẽ hiển thị số 4
                        tức là bây h muốn đếm ngược từ 35 trở về chẳng hạn. thì ban đầu mình nạp giá trị 35 thập phân chứ không phải 35H như đoạn chương trình mình đã up lên rồi sau đó thực hiện trừ thập phân (P0-1) bình thường rồi dùng thuật toán hiệu chỉnh của bạn xuát dữ liệu ra con 7447 hôi nhỉ rồi mình sẽ viết thử một hàm luôn
                        Thanks
                        mình là machithanh nha

                        Comment


                        • #13
                          tức là bây h muốn đếm ngược từ 35 trở về chẳng hạn. thì ban đầu mình nạp giá trị 35 thập phân chứ không phải 35H
                          - Hoá ra vấn đề của bạn là ở đây. Như tôi đã nói, hệ 16, hệ 10, hệ 2, hệ BCD chỉ là các cách biểu diễn khác nhau của cùng một giá trị. Bây giờ bạn muốn đếm lùi từ 35 trở về thì trên LED 7 thanh giá trị hiển thị phải ở hệ 10 (các chữ số từ 0 -->9). Còn khi bạn nhập vào cho VDK xử lý thì bạn nhập kiểu gì cũng được miễn là đúng giá trị. Ví dụ 35 trong hệ 10 thì trong hệ 16 nó là 23H (chứ không phải là 35H). Tương tự cho các giá trị khác (bạn có thể dùng calculator của máy tính để kiểm tra sự chuyển đổi giá trị giữ các hệ với nhau)
                          Last edited by Toan.Lv; 05-05-2009, 15:07.
                          For a better world

                          Comment


                          • #14
                            Toan.Lv cho mình hỏi sau khi mình viết
                            hangchuc=byte/10;
                            sau đó lưu giá trị hangchuc vừa thu được vào 4 bit cao ( P0.4 - P0.7) để đưa ra LED 7 thanh thì cú faps lệnh thế nào nhỉ
                            ví dụ:
                            void main(void)
                            {P0=35d;
                            while (P0)
                            {
                            xuli(P0);

                            ......// sau khi xử lý P0 thì làm thế nào để 4 bit cao của P0 mang ja' trị 3, 4 bit thấp mang ja' tri 5---> ý mình hỏi là cú pháp lệnh ý
                            Delay();
                            P0=P0-1;

                            }
                            }
                            |

                            Comment


                            • #15
                              đây là chương trình của mình đếm ngược từ 35 về 0
                              #include <REGX51.H>
                              #include <AT89X51.H>
                              unsigned char hangchuc,hangdonvi;

                              void delay()
                              {
                              int i;
                              for(i=0;i<20;i++)
                              { //50000 x 20 = 1s
                              TH0=0x3c; //-50000 us
                              TL0=0xb0;
                              TR0=1;
                              while(!TF0); //cho timer0 tràn
                              TF0=TR0=0;
                              }
                              }

                              void xuli(void)
                              {
                              int m;
                              m=P0;
                              hangchuc=(P0/10);
                              hangdonvi=(P0%10);
                              P0=(hangchuc*16) + hangdonvi;
                              delay();
                              P0=m;
                              }

                              void main(void)
                              {
                              TMOD=0x01;
                              P0=35;

                              while (1)
                              {
                              xuli();
                              P0=P0-1;

                              }
                              }
                              |

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X