Thông báo

Collapse
No announcement yet.

Các bạn giúp mình giải đáp một số vấn đề

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

  • Các bạn giúp mình giải đáp một số vấn đề

    PHP Code:
    ;CAC LENH GAN
            DATA_LED        EQU     P0
    ;---------------------------------
    ORG     0000H
    LJMP    START
    ;---------------------------------
    ORG     03H                   ;external interrupt 0
            
    ;GOI CTC PHUC VU NGAT
    RETI
            
    ORG     0BH                   
    ;timer 0 interrupt
            LJMP    NGAT_T0
            
    ORG     13H                   
    ;external interrupt 1
            
    ;GOI CTC PHUC VU NGAT
    RETI

    ORG     1BH                   
    ;timer 1 interrupt
    RETI  

    ORG     23H                   
    ;serial port interrupt
            
    ;GOI CTC PHUC VU NGAT
    RETI
    ;=====================================
    ORG     30H
    ;=====================================
    KHOI_TAO:                     ;set up control registers
         MOV   TCON
    ,#00H
         
    MOV   TMOD,#00000001B      ; che do 1 ngat timer 0
         
    MOV   PSW,#00H             
         
    MOV   IE,#10000010B      ;CHO PHEP NGAT TIMER0
    RET
    ;-------------------------------------
    ;
    HAM MAIN
    ;-------------------------------------
    START:
            
    ACALL   KHOI_TAO        ;KHOI TAO CAC THANH GHI
            MOV     TH0
    ,#03CH
            
    MOV     TL0,#0B0H
            
    SETB    TR0
            SETB    TF0
            MOV     R0
    ,#0
            
    MOV     30H,#0
            
    LJMP    
    RET
    ;-------------------------------------
    NGAT_T0:
            
    CLR     TR0
            MOV     TH0
    ,#03CH
            
    MOV     TL0,#0B0H       ; dat lai thanh ghi timer
            
    SETB    TR0             bat TR0 cho timer hoat dong
            ACALL   HT_R0           
    goi ham hien thi 
            MOV     R1
    ,30H
            CJNE    R1
    ,#20,TANG_30H ;say 20 lan thi tang gia tri cua o nho 30H len 1 
            
    MOV     30H,#0          ;neu toi 20 thi ve 0 tro lai
            
    ACALL   DC_R0           sau 20 lan goi timer la dc 1 giaytien hanh dieu chinh R0 len 1
            LJMP    
    EXIT
     
    TANG_30H:
            
    INC     30H       
     
    EXIT:
    RETI
    ;-------------------------------------
    HT_R0:
            
    MOV     A,R0
            ACALL   DOI_MA_LED
            MOV     DATA_LED
    ,A
    RET
    ;-------------------------------------
    DC_R0:
            
    JB      00H,DEM_XUONG
            
    ;-----------DEM LEN
            CJNE    R0
    ,#9,TANG_R0
            
    SETB    00H     ;DIEU KHIEN DEM XUONG
            DEC     R0
            LJMP    EXIT_DC_R0
     TANG_R0
    :
            
    INC     R0
            LJMP    EXIT_DC_R0
            
    ;---------------DEM XUONG
     DEM_XUONG
    :
            
    CJNE    R0,#0,GIAM_R0
            
    CLR     00H      ;DIEU KHIEN DEM LEN
            INC     R0
            LJMP    EXIT_DC_R0
     GIAM_R0
    :
            
    DEC     R0       
     EXIT_DC_R0
    :
    RET
    ;-------------------------------------
    DOI_MA_LED:
            
    INC     A
            MOVC    A
    ,@A+PC
    RET
    DB 11000000B
    ,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
    DB 00010000B
    ;-------------------------------------
    END 
    với lại nếu mình nói sai vấn đề nào các bạn sửa lại giúp mình nhá vì mình không phải dân điện tử mà khoa mình lại học cái này nên mình không có hiểu nhìu cảm ơn rất nhìu
    1.
    Code:
    Các ORG+0000H ,ORG+03H ... là cái gì thế và mình lấy các 0000H,03H dựa vào cơ sở nào vậy
    2.
    Code:
    Sao lúc mình thấy RET lúc thì lại RETI vậy 2 cái đó khác nhau thế nào
    3.
    Code:
    ORG     0000H
    LJMP    START
    Có phải khi chương trình thực hiện thì ngắt này thực hiện đầu tiên không , vì mình thấy các ngắt khi mà nó đúng thời gian thì mới xảy ra ngắt nhưng tại sao cái này lại thực hiện đầu tiên
    4.
    Trong cái hàm START mình thấy là TF0 ban đầu người ta thường CLR nó để đưa nó về 0 và dùng JNB để kiếm tra TF0 đã bật chưa sao trong này nó SETB lun
    - khi LJMP nhảy tại chỗ cho đến khi xảy ra ngắt thì nó sẽ gọi NGAT_TO và khi thực hiện xong thì nó sẽ trả về đâu để tiếp tục đợi ngắt lần tiếp theo
    5.
    Cái đoạn
    Code:
     JB      00H,DEM_XUONG
            ;-----------DEM LEN
            CJNE    R0,#9,TANG_R0
            SETB    00H     ;DIEU KHIEN DEM XUONG
            DEC     R0
            LJMP    EXIT_DC_R0
    OOH mình không thấy nó khởi tạo ở đâu cả vậy khi đưa vào thì nó có giá trị là bao nhiu
    6.
    Đoạn này
    Code:
    DOI_MA_LED:
            INC     A
            MOVC    A,@A+PC
    RET
    DB 11000000B,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
    DB 00010000B
    Mình hỉu đoạn này là đổi ra tín hiệu của mã LED , nhưng tại sao phải tăng A vậy và lệnh MOVC A,@A+PC có nghĩa là gì

  • #2
    1.
    Code:
    Các ORG+0000H ,ORG+03H ... là cái gì thế và mình lấy các 0000H,03H dựa vào cơ sở nào vậy
    cái này có nghĩa là chỉ cho chương trình biết địa chỉ bắt đầu một chương trình con- có bao gồm hàm main nào đó
    2.
    Code:
    Sao lúc mình thấy RET lúc thì lại RETI vậy 2 cái đó khác nhau thế nào
    nói chong trong bài này của bạn chỉ sử dụng một ngắt nên hai cái đó không quan trọng lắm,
    về mặt hiểu thì mình hiểu thế này: ret là kết thúc chương trình con và trả bộ đếm chương trình PC về giá trị ngay sau lệnh gọi nó,
    còn reti thì dùng khi ta thực hiện trên 1 ngắt, và có sử dụng cái ưu tiên ngắt, tức là sau khi kết thúc ngắt 1 thì nếu ngắt 2 còn yêu cầu thì chuyển đến ngắt 2.
    3.
    Code:
    ORG     0000H
    LJMP    START
    Có phải khi chương trình thực hiện thì ngắt này thực hiện đầu tiên không , vì mình thấy các ngắt khi mà nó đúng thời gian thì mới xảy ra ngắt nhưng tại sao cái này lại thực hiện đầu tiên
    start hông phải là chương trình con, nó là chương trình để khởi tạo giá trị cho toàn bộ chương trình của bạn
    4.
    Trong cái hàm START mình thấy là TF0 ban đầu người ta thường CLR nó để đưa nó về 0 và dùng JNB để kiếm tra TF0 đã bật chưa sao trong này nó SETB lun
    - khi LJMP nhảy tại chỗ cho đến khi xảy ra ngắt thì nó sẽ gọi NGAT_TO và khi thực hiện xong thì nó sẽ trả về đâu để tiếp tục đợi ngắt lần tiếp theo
    bản chất cũng chẳng có gì cả, setb tf0 chẳng qua là để chương trình "chuyển luôn" hướng luôn đến chương trình ngắt thôi, còn clr kia là để "đợi" khi có ngắt
    5.
    Cái đoạn
    Code:
     JB      00H,DEM_XUONG
            ;-----------DEM LEN
            CJNE    R0,#9,TANG_R0
            SETB    00H     ;DIEU KHIEN DEM XUONG
            DEC     R0
            LJMP    EXIT_DC_R0
    OOH mình không thấy nó khởi tạo ở đâu cả vậy khi đưa vào thì nó có giá trị là bao nhiu
    đoạn này mình cũng không lắmchoox kiểm tra thanh ghi 00h ?
    6.
    Đoạn này
    Code:
    DOI_MA_LED:
            INC     A
            MOVC    A,@A+PC
    RET
    DB 11000000B,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
    DB 00010000B
    Mình hỉu đoạn này là đổi ra tín hiệu của mã LED , nhưng tại sao phải tăng A vậy và lệnh MOVC A,@A+PC có nghĩa là gì
    tăng thì phải biết bài toán của bạn yêu cầu là gì đã,
    còn mình không hiểu là xao lại dùng PC, vì PC là thanh ghi bộ đếm chương trình, nên nó thay đổi, khó đoán được giá trị (đối với mình),

    Comment


    • #3
      đoạn này mình cũng không lắmchoox kiểm tra thanh ghi 00h ?
      mình không biết tại sao 00H nó ở đâu ra mặc dù ban đầu chưa khởi tạo giá trị gì cho nó

      Comment


      • #4
        Nguyên văn bởi jimhawkins Xem bài viết
        mình không biết tại sao 00H nó ở đâu ra mặc dù ban đầu chưa khởi tạo giá trị gì cho nó
        Theo như code của bạn thì 00H là bit 00h chứ không phải là thanh ghi. Nó là bít đầu tiên của thanh ghi 20h (bít LSB). Và nó chỉ nhận 2 giá trị "0h" hoặc "1h"
        Last edited by Ck33spkt; 12-08-2012, 00:09.

        Comment


        • #5
          vậy cái bit này mặc định ban đầu là 0 lun hả bạn
          Bạn giúp mình trả lời câu hỏi 6 được không

          Comment


          • #6
            Nguyên văn bởi jimhawkins Xem bài viết
            vậy cái bit này mặc định ban đầu là 0 lun hả bạn
            Khi VĐK được reset thì bít sẽ có giá trị 00H
            Nguyên văn bởi jimhawkins Xem bài viết
            Bạn giúp mình trả lời câu hỏi 6 được không
            Code:
            DOI_MA_LED:         
            INC     A         
            MOVC    A,@A+PC 
            RET 
            DB 11000000B,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
            DB 00010000B
            Giả sử bạn đầu PC = 5, A = 0. Lệnh MOVC A, @A+PC sẽ lấy giả trị tại ô nhớ có địa chỉ A + PC = 0 + 5 = 5 để lưu vào thanh ghi A.
            Nếu tăng A lên 1 đơn vị (lúc này A = 1) rồi lại sử dụng lệnh MOVC A, @A+PC thì nó sẽ lấy giá trị tại ô nhớ có địa chỉ A + PC = 1 + 5 = 6 để lưu vào thanh ghi A.
            Vì bạn hiển thị lần lượt các số từ 0 tới 9, nên sau khi lấy được mã của số 0 cần phải tăng A để lấy mã của số 1 (vì mã của số 1 bạn đã lưu nó vào ô nhớ có địa chỉ ngay sau số 0). Cứ thế tiếp tục cho đến số 9
            .

            Comment


            • #7
              Trước tiên bạn phải phân biệt được mã điều khiển và mã lệnh, mã lệnh thì trong 8051 có 255 mã lệnh, cái này bạn tìm hiểu nhé, còn mã điều khiển để trình dịch hợp ngữ hiểu và dịch đúng theo ta muốn, mã điều khiển ORG ở đây báo cho trình dịch biết là bắt đầu ở vị trí 0000h trong rom nội nhé, còn mã ORG 0003h là vector ngắt của ngắt ngoài 1, nếu bạn muốn tìm hiểu sâu về 8051 thì cứ đọc sách là có hết, còn chỉ học để qua môn thì không cần để ý làm gì.
              Trả lời câu 6: Lúc này PC đang trỏ đúng vị trí của lệnh và sau lệnh MOVC A,@A+PC thanh ghi A sẽ có vị trí của PC và giá trị của thanh chứa A cộng lại. Mình nghĩ ở đây sở dĩ người lập trình sử dụng PC thay vì DPRT vì để tiết kiệm bộ nhớ, vì ngay sau lệnh MOVC A,@A+PC là các vị trí của chứa giá trị mã led 7 đoạn nên dùng PC là hợp lý, còn nếu vị trí của các mã led 7 đoạn ở những chỗ khác cách xa lệnh thì phải tạo bảng cho led và mov vào DPTR sau đó MOVC A,@A+DPTR thì sẽ mất thời gian và bộ nhớ hơn. Lập trình như thế này là chuẩn đấy, mình sẽ học tập hihi

              Comment


              • #8
                PC trong trường hợp này nó bằng bao nhiêu vậy bạn, mình có thắc mắc ở chỗ là ban đầu A nó bằng 0 khi vào hàm DOI_MA_LED thì lại tăng A lên , vậy số 0 ban đầu nó đổi sang mã LED như thế nào vậy,còn cái phải tăng A lên để đối sang mã tiếp theo thì mình hỉu

                Comment


                • #9
                  Nguyên văn bởi jimhawkins Xem bài viết
                  PC trong trường hợp này nó bằng bao nhiêu vậy bạn, mình có thắc mắc ở chỗ là ban đầu A nó bằng 0 khi vào hàm DOI_MA_LED thì lại tăng A lên , vậy số 0 ban đầu nó đổi sang mã LED như thế nào vậy,còn cái phải tăng A lên để đối sang mã tiếp theo thì mình hỉu
                  Nếu ban đầu A = 0, khi vào hàm DOI_MA_LED thì A được tăng lên 1. Lúc này khi thực hiện xong lệnh MOVC A, @A+PC thì A sẽ có giá trị của ô nhớ 1 + PC.
                  => bạn phải tính toán sao cho giá trị trong ô nhớ 1 + PC chính là mã của số 1 vì ban đầu bạn đã hiển thị sẵn số 0 rồi.
                  PC cụ thể bằng bao nhiêu thì phải lần từ đầu chương trinh đến thời điểm bạn tính.

                  Comment


                  • #10
                    Nguyên văn bởi Ck33spkt Xem bài viết
                    Nếu ban đầu A = 0, khi vào hàm DOI_MA_LED thì A được tăng lên 1. Lúc này khi thực hiện xong lệnh MOVC A, @A+PC thì A sẽ có giá trị của ô nhớ 1 + PC.
                    => bạn phải tính toán sao cho giá trị trong ô nhớ 1 + PC chính là mã của số 1 vì ban đầu bạn đã hiển thị sẵn số 0 rồi.
                    PC cụ thể bằng bao nhiêu thì phải lần từ đầu chương trinh đến thời điểm bạn tính.
                    sai rồi chú, ta sẽ xét độc lập CTC DOI_MA_LED:
                    Code:
                    DOI_MA_LED:         
                    INC     A         ;ADDR 008f
                    MOVC    A,@A+PC    ;ADDR 0090
                    RET           ;ADDR 0091
                    DB 11000000B,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
                    DB 00010000B
                    thứ nhất tại tại sao có dòng INC A. Dòng này bắt buột phải có để hướng tới điểm bắt đầu của bảng mã bên dưới vì dòng MOVC A,@A+PC cách bảng mã 1 lệnh RET chiếm 1 byte bộ nhớ. PC ở dòng MOVC này sẽ có giá trị bất kì tùy thuộc độ dài chương trình phía trên nó.Xét hoạt động:
                    Ta có R0 là biến quản lý giá trị đếm, ban đầu R0 bằng 0 ta phải tra bảng giá trị C0 (mã 7 đoạn của số 0) là giá trị thứ 0 trong bảng tra. Khi bắt đầu vào CTC DOI_MA_LED thì A giá trị 0 lấy từ R0, tăng A lên 1 sau đó tra bảng, giả sử PC khi tới lệnh MOVC là 0090h ta có 90h+1=91h thì A sẽ tra giá trị thứ 0 của bảng là giá trị C0H. Nếu ko có tăng A trước khi tra bảng thì A sẽ tra ra giá trị 22H (tương ứng với mã lệnh của lệnh RET)

                    Comment


                    • #11
                      cảm ơn các bạn nhiệt tình trả lời mình cũng hỉu chút rồi cho mình hỏi một chỗ ở câu hỏi 4
                      khi LJMP nhảy tại chỗ cho đến khi xảy ra ngắt thì nó sẽ gọi NGAT_TO và khi thực hiện xong trong hàm NGAT_TO thì nó nhảy đến nhãn EXIT vậy thì nó sẽ trả về đâu để tiếp tục đợi ngắt lần tiếp theo như việc nhảy tại chỗ giống như LJMP $ hay chương trinh cứ đơ như vậy khi có ngắt thì nó lại gọi cái NGAT_TO
                      -Ah các bạn cho mình hỏi thêm cái định thời và cái ngắt nó giống và khác như thế nào
                      -Ở bên định thời thì nó CLR TF0 rồi đợi TF0 bật cờ thì thực hiện , bên này sao nó SETB cờ TF0 lun vậy lúc nào cờ này nó bật hết , bạn trên kia giải thích cho mình để nó chuyển hướng luôn mình cũng không hỉu là gì nữa
                      -Trong cái mã LED ah sao số 0 thì dot nó lại tắt còn mấy số kia thì không

                      Comment


                      • #12
                        Nguyên văn bởi jimhawkins Xem bài viết
                        cảm ơn các bạn nhiệt tình trả lời mình cũng hỉu chút rồi cho mình hỏi một chỗ ở câu hỏi 4

                        -Ah các bạn cho mình hỏi thêm cái định thời và cái ngắt nó giống và khác như thế nào
                        -Ở bên định thời thì nó CLR TF0 rồi đợi TF0 bật cờ thì thực hiện , bên này sao nó SETB cờ TF0 lun vậy lúc nào cờ này nó bật hết , bạn trên kia giải thích cho mình để nó chuyển hướng luôn mình cũng không hỉu là gì nữa
                        -Trong cái mã LED ah sao số 0 thì dot nó lại tắt còn mấy số kia thì không
                        đối với ngắt bạn hỏi.CT đang làm việc tại lệnh JMP $ , khi có ngắt quy trình sẽ là lưu địa chỉ của lệnh JMP $ và stack, nhảy vào trình phục vụ ngắt mà vector ngắt hướng đến, làm trình phục vụ ngắt cho tới khi gặp lệnh RETI, lệnh RETI sẽ thực thi việc lấy địa chỉ của lệnh JMP $ đã lưu trong stack nạp vào cho PC để VDK thực hiện tiếp lệnh JMP $
                        Định thời là làm 1 công việc vô nghĩ để giết thời gian trước khi làm 1 công việc khác, giống như bạn vào lớp học mà bạn ngủ tới khi ra về.
                        Ngắt bộ định thời là hẹn giờ để làm 1 công việc nào đó, giống như bạn vào lớp, cài đồng hồ để còn 10 phút tới giờ ra về sẽ báo, rồi bạn học tiếp
                        Tại sao đầu CT chính lại set cờ TF0 là vì để nhảy vào trình phục ngắt để hiển thị giá trị ra 7 đoạn, đối với ngắt timer ko cần CLR cờ TF0 là vì VDK tự động xóa khi nhảy vào ngắt. Thực ra cũng ko cần CLR TR0 và SETB TR0 trong trình phục vụ ngắt, chỉ cần nhảy vào, nạp lại rồi nhảy ra(thích thì làm vài công chuyện khác rồi nhảy ra ^^)
                        còn cái mã led 7 đoạn thì bạn xóa bit 1 ở cuối mã là đc.

                        Comment


                        • #13
                          Nguyên văn bởi chung1608 Xem bài viết
                          sai rồi chú, ta sẽ xét độc lập CTC DOI_MA_LED:
                          Code:
                          DOI_MA_LED:         
                          INC     A         ;ADDR 008f
                          MOVC    A,@A+PC    ;ADDR 0090
                          RET           ;ADDR 0091
                          DB 11000000B,01111001B,00100100B,00110000B,00011001B,00010010B,00000010B,01111000B,00000000B
                          DB 00010000B
                          thứ nhất tại tại sao có dòng INC A. Dòng này bắt buột phải có để hướng tới điểm bắt đầu của bảng mã bên dưới vì dòng MOVC A,@A+PC cách bảng mã 1 lệnh RET chiếm 1 byte bộ nhớ. PC ở dòng MOVC này sẽ có giá trị bất kì tùy thuộc độ dài chương trình phía trên nó.Xét hoạt động:
                          Ta có R0 là biến quản lý giá trị đếm, ban đầu R0 bằng 0 ta phải tra bảng giá trị C0 (mã 7 đoạn của số 0) là giá trị thứ 0 trong bảng tra. Khi bắt đầu vào CTC DOI_MA_LED thì A giá trị 0 lấy từ R0, tăng A lên 1 sau đó tra bảng, giả sử PC khi tới lệnh MOVC là 0090h ta có 90h+1=91h thì A sẽ tra giá trị thứ 0 của bảng là giá trị C0H. Nếu ko có tăng A trước khi tra bảng thì A sẽ tra ra giá trị 22H (tương ứng với mã lệnh của lệnh RET)
                          Cái kiểu tra bảng dùng bộ đếm PC này rất khó tính chính xác được giá trị PC để mà tra mã LED. Nếu em để cái bảng mã Led tại đầu chương trình em nghĩ chắc chắn là cái đoạn chương trình con DOI_MA_LED sẽ hoạt động sai.
                          Bác chung68 cho em xin ý kiến về cách suy luận trên là đúng hay sai?

                          Comment


                          • #14
                            Nguyên văn bởi Ck33spkt Xem bài viết
                            Cái kiểu tra bảng dùng bộ đếm PC này rất khó tính chính xác được giá trị PC để mà tra mã LED. Nếu em để cái bảng mã Led tại đầu chương trình em nghĩ chắc chắn là cái đoạn chương trình con DOI_MA_LED sẽ hoạt động sai.
                            Bác chung68 cho em xin ý kiến về cách suy luận trên là đúng hay sai?
                            đối với CTC DOI_MA_LED trên ta ko cần quan tâm PC là bao nhiêu mà chỉ cần quan tâm phía sau lệnh MOVC A,@A+PC có bao nhiêu lệnh rồi mới tới bảng mã. Nhưng CTC phía trên sau MOVC có 1 lệnh RET thôi thì trước khi tra bảng ta tăng A lên 1, ví dụ nếu có thêm lệnh NOP sau MOVC tăng A lên 2, v.v...
                            Cách viết trên thích hợp với các code nhiều bảng mã ngắn với mức độ CTC tra bảng đơn giản.

                            Comment


                            • #15
                              cho mình hỏi thêm là trong cái hàm NGAT_T0,cái này là 1s thì nó tăng giá trị đếm lên 1 đơn vị,3CBO tính số xung đếm và đổi ra decimal là 50000 vậy cần lập 20 để đủ 1s,theo mình nghĩ là khi mà cái thanh ghi để kiểm tra nó bằng 20 chưa thì phải để ngoài hàm NGAT_TO để kiểm tra nó chứ nhỉ,nếu mà đúng thì mới xảy ra ngắt lúc này mới nhảy vào NGAT_TO thực hiện,sao trong này nó để lun trong hàm NGAT_TO các bạn giúp mình giải đáp chút

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X