Thông báo

Collapse
No announcement yet.

chuong trinh bị sai ???

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

  • chuong trinh bị sai ???

    mình có thực hiện một mạch điều khiển động cơ bước dạng 1.8 đọ áp 12v 6 đầu dây. thông qua biến trở bằng adc. nhung có một số vấn đề xảy ra là khi mình text để port1 không ảnh hưởng đên adc0804 thì mov p1,#0 và mỗi lần reset thì và thay đổi giá trị biến trở thì thấy 8 led ở đầu ra của adc0804 thay đổi . có nghĩa là con này hoạt động nhung khi nạp chưong trình mình viết vô thì thấy động cơ không chạy và mấy led đó cũng không thầy sáng port1 do lun ở 5v. còn 3 led 7 doạn báo tốc độ thì chỉ nhấp nháy mờ thồi. mình nghĩ có lẽ do chương trình mình viết có lỗi gì chăng ?? ở đây mình đã viết và chú thích khá rõ từng dòng lệnh và í đồ thiết kế bác nào hiểu sâu về lập trình assemly thì có thể chỉ ra lỗi của chương trình mình viết ??????:


    ;----- Chuong trinh dieu khien & hien thi toc do encoder-------------

    Org 0000h
    Ljmp Main
    Org 0003h ; ngat dem xung encoder
    Inc R0 ; bien dem xung
    Mov A, R0
    Cjne A,#100,finish ; neu du 100 xung/vong
    INC 60H ; thi luu so vong vao R1
    Mov R0, #0 ; va xoa bien dem xung R0cho lan dem sau
    finish:
    nop
    RETI
    Org 0013H ; ngat tu ADC bao da chuyen xong tu (voltage to digital)
    Clr P3.5 ; cho phep vi dieu khien doc tu ADC (chan p3.5 dieu khien chan "READ" cua 0804
    Mov A,p1

    Setb P3.5 ; set cho lan doc tu adc sau.
    Clr P3.6 ;
    Setb P3.6 ; tao xung tu 0-->1 de cho phep "WR" from analogue to digital (dieu khien chan Write of 0804)
    RETI

    Org 001BH ; ngat bao thoi diem hien toc do ra 7segment
    ljmp Hien_thi ; ngat time 1 bao led---

    Main:

    Mov R0, #0
    Mov R1, #0
    Mov TMOD,#11H ; khai bao su dung timer 1 va 0
    Mov IE,#10001101B ; khai bao cho phep su dung 3 ngat ( INT0,INT1,TIMER1)
    Setb IT0
    Setb IT1
    Clr P3.6
    Setb P3.6 ;--------------- Khai bao cho phep convert voltage to digital lan dau tien

    Mov TH1,#HIGH(-50000) ; nap gia tri dau cho ngat timer 1
    Mov TL1,#LOW(-50000) ;***********
    SetB TR1 ;-------------------------cho phep timer 1 hoat dong
    ;****************************************
    ;/////; **---cho motor hoat dong---**//
    Kiem_tra:
    Mov A,P1 ; kiem tra bien tro qua trung gian ic ADC va P1
    Cjne A,#0FFH,Begin ; bien tro khong o min thi cho motor hoat dong
    Mov P2,#0 ;-------------neu de o min thi stop moto and wait
    ; a new value; dùng port 2 de kich opto ..-->motor
    Sjmp Kiem_tra
    Begin:
    Mov R5,#4 ; 4 xung de kich du mot chu trinh kich 4 cuon day .....vv...
    Mov R6,#0 ; thay doi thu tu cac cuon day kich...
    Mov DPTR,#buoc_quay
    Chay_tiep:
    Mov A,R6
    Movc A,@A+DPTR
    Mov P2, A
    Inc R6
    Call Delay_chay
    Djnz R5,Chay_tiep ; neu kich chua du chu trinh thi Jmp chay_tiep
    Sjmp Kiem_tra ; khi kich du chu trình 4 cuon dây thì Jmp to Kiem_tra

    Delay_chay:

    ;***** neu nap #63H vào Th0 và tl0 thì motor quay min..
    ;***** neu nap #0F0H vào th0 và tl0 thì motor quay max
    ;***** do do sau khi check motor not " min" thì
    ;****** kiem tra xem #63h<= P1<= #0F0h ???

    Mov A,P1
    Clr C ; xoa co nho ve "Zero"
    Mov R3, #63h ; dua value min "#63h " vao R3de so sanh voi gia tri tu Port 1
    Subb A,R3
    Jc Next ;if #63H thi nhay den label Next
    Mov R0,#0F0H ; tiep tu so sanh voi chuan "max" #0F0H"
    Mov A,P1
    Subb A,R3
    Jc Inner ; P1< #0F0h thi nhay den label "Inner"
    Mov A,#0F0H ; P1>= max thì chon max chuan lam gia tri cho ham delay
    Sjmp Delay1
    Next:
    Mov A,#63H ; neu P1 <#63h thi chon TH0= #63H lam gia tri delay
    Sjmp Delay1
    Inner:
    Mov A,P1 ; neu #63h <= P1 <= #0F0h thi lay P1 lam gia tri ham delay

    ; ********* ham delay cho motor***********
    Delay1:
    Mov TH0,A
    Mov TL0,A
    Setb TR0
    Jnb TF0,$
    Clr TF0
    Clr TR0
    RET
    buoc_quay: DB 01h,02h,04h,08h

    ;************************ phan hien thi ra led *******************************
    Hien_thi:
    Clr TR1 ; stop timer 1
    Clr TF1 ; xoa co tran timer 1
    Mov TH1,#HIGH(-50000) ;---nap lai gia tri cho timer 1
    Mov TL1,#LOW(-50000) ;----nap lai gia tri cho timer 1
    SETB TR1 ;---------------------tiep tuc cho timer 1 hoat dong
    Inc R7 ; bien R7 de kiem soat lap 20 lan cho du 1s
    Mov A,R7 ; kiem tra xem da du 1s chua ??

    Cjne A,#20,Nothing ; thoat khoi ngat neu chua du 1s
    Mov R7,#0 ; neu du 1s thi R7 cho lan sau
    Mov DPTR,#ma_led ; thuc hien viec giai ma xuat led
    Mov B,#60
    Mov A, 60H ; dua so vong quay sau 1s vao A
    Mov 60H, #0 ; dua bien dem vong ve "zero" cho lan dem sau/
    Mul AB ; so vong /phut
    Xch A,B
    Swap A
    Orl A,B
    Mov B,#10
    Div AB
    Xch A,B
    Movc A,@A+DPTR
    Mov P0, A ; ; hien thi hang don vi
    Clr P3.4 ; p3.4 noi voi cua baze cua transistor kich hang don vi
    Acall Small_d ; goi tre de quan sat led
    Setb P3.4 ; tat led don vi
    Xch A,B
    Mov B,#10
    Div AB
    Movc A,@A+DPTR
    Mov P0,A ;**************
    Clr P3.0 ;----On led hàng tram
    Acall Small_d
    Setb P3.0 ;----Off led hang tram
    Mov A,B
    Movc A,@A+DPTR
    Mov P0,A ;------hien thi hang chuc
    Clr P3.1 ;------on led hang chuc
    Acall Small_d
    Setb P3.1 ; off led hàng chuc
    Sjmp Nothing ; hien thi xong thi nhay den "nothing de thoat khoi ngat timer 1
    Small_d:
    Mov R4, #255
    Djnz R4, $
    Ret

    ma_led: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
    Nothing:
    nop
    RETI
    End

  • #2
    tui chưa xem kỹ ct bạn viết. Nhưng có thể nói với bạn vài điều thế này.
    1/Trong CT khi sử dụng ngắt, bạn cần chú ý là trong CT ngắt của bạn có lệnh làm thay đổi thanh ghi A và cờ C, mà trong CT chính lại thường sử dụng thanh ghi A và cờ C, bạn đã biết là ngắt có thể xảy ra bất kỳ lúc nào và CT chính phải tạm dừng để nhường cho ngắt, khi ngắt thực hiện xong và quay lại Ct chính thì thanh ghi A và cờ C đã thay đổi dẩn tới là Ct chính sẽ không đúng. cho nên khi ngăt xảy ra bạn nên push ACC, bên cạnh đó bạn tạm lưu cờ C vào port nào đó mà còn trống (vd: mov p3.7,c) và khi xong ngắt thì pop ACC và mov c,p3.7 rồi mới Reti.
    2/dùng ngắt T1 để quét led, nhưng phải 1 s mới quét 1 lần nên led không sáng theo ý muốn là đúng rồi
    Trong giới hạn bài viết tui không thể nói chi tiết, cụ thể. Bạn nghiên cứu thêm vậy.
    Last edited by phienbinh; 14-06-2008, 14:43.
    Trên đường thành công, không có dấu chân của kẻ lười biếng.

    Comment


    • #3
      Nguyên văn bởi phienbinh Xem bài viết
      tui chưa xem kỹ ct bạn viết. Nhưng có thể nói với bạn vài điều thế này.
      1/Trong CT khi sử dụng ngắt, bạn cần chú ý là trong CT ngắt của bạn có lệnh làm thay đổi thanh ghi A và cờ C, mà trong CT chính lại thường sử dụng thanh ghi A và cờ C, bạn đã biết là ngắt có thể xảy ra bất kỳ lúc nào và CT chính phải tạm dừng để nhường cho ngắt, khi ngắt thực hiện xong và quay lại Ct chính thì thanh ghi A và cờ C đã thay đổi dẩn tới là Ct chính sẽ không đúng. cho nên khi ngăt xảy ra bạn nên push ACC, bên cạnh đó bạn tạm lưu cờ C vào port nào đó mà còn trống (vd: mov p3.7,c) và khi xong ngắt thì pop ACC và mov c,p3.7 rồi mới Reti.
      2/dùng ngắt T1 để quét led, nhưng phải 1 s mới quét 1 lần nên led không sáng theo ý muốn là đúng rồi
      Trong giới hạn bài viết tui không thể nói chi tiết, cụ thể. Bạn nghiên cứu thêm vậy.
      cũng có thể lỗi là ở đó... thực ra chương trình này mình đã viết và có hỏi thầy xem wa thử nhưng cũng không phát hiện ra lỗi ... có lẽ do coi không kĩ... nên mình mới hỏi ý kiến mấy bạn rành về assemly.. u mà cái thằng push .. pop của bạn phải theo thứ tự vào trước ra sau mới đúng chứ........

      Comment


      • #4
        hi vọng là có thể nhận được sự góp ý của các bạn..

        Comment


        • #5
          bạn có thể cho mình hỏi thêm ... về quét led :
          1/ cách định nghĩa về tần số quét...thực chất giải sử trong mạch cần hiển thị có "X" led thì tần số này được hiểu là khoảng thời gian bạn sẽ lặp lại việc cho sáng từ led 1--> led thứ "X"của bạn ???
          2/ trong kĩ thuật quét giả sự bạn đưa baze của transistor về mức thấp hoặc mức cao để cho led sáng điều này phụ thuộc vào loại đó là pnp or npn... và sau đó sẽ gọi một hàm delay trước khi cho nó off để sang led 2 vvvv.........
          3/ giả sử trong bài này mình muốn led của mình sau 1s mới được cập nhật giá trị mới từ encoder mà nó đếm được ......... trong khoảng 1s này thì chương trình phải xử lý nhiều việc khác ..... vậy phải thỏa mãn sao để nó không bị nhấp nháy ?????/

          Comment


          • #6
            Lưu cờ nhớ thì push toàn bộ thanh ghi có chứa cờ nhớ (không nhớ tên).
            Theo tôi khi quét led thì tạo 1 chương trình ngắt theo thời gian. Tới thời điểm thì tắt đèn này mở đèn khác. Xong quay về chương trình chính, khi có ngắt tới thì tiếp tục.

            Comment


            • #7
              Org 0000h
              Ljmp Main
              Org 0003h ; ngat dem xung encoder
              Inc R0 ; bien dem xung
              Mov A, R0
              Cjne A,#100,finish ; neu du 100 xung/vong
              INC 60H ; thi luu so vong vao R1
              Mov R0, #0 ; va xoa bien dem xung R0cho lan dem sau
              finish:
              nop
              RETI
              Org 0013H ; ngat tu ADC bao da chuyen xong tu (voltage to digital)
              Clr P3.5 ; cho phep vi dieu khien doc tu ADC (chan p3.5 dieu khien chan "READ" cua 0804
              Mov A,p1

              Setb P3.5 ; set cho lan doc tu adc sau.
              Clr P3.6 ;
              Setb P3.6 ; tao xung tu 0-->1 de cho phep "WR" from analogue to digital (dieu khien chan Write of 0804)
              RETI

              Org 001BH ; ngat bao thoi diem hien toc do ra 7segment
              ljmp Hien_thi ; ngat time 1 bao led---


              Bạn không nên viết code ngắt như trên, vì bảng vector ngắt chỉ để dành 8 ô nhớ cho mỗi chương trình ngắt, bạn viết chương trình ngắt như vậy sẽ vượt quá 8 ô nhớ chương trình. Cụ thể ở đây chương trình ngắt ngoài EX1 đã tràn qua địa chỉ 001BH của ngắt timer1 và sẽ gây rối loạn chương trình khi ngắt EX1 xãy ra.
              Bạn nên viết code như sau:
              org 0000h
              sjmp main
              org 0003h
              ljmp ngat_EX0
              org 000Bh
              ljmp ngat_timer0
              org 0013h
              ljmp ngat_EX1
              org 001bh
              ljmp ngat_timer1

              org 0030h
              main:
              ...
              ;-----------
              các chương trình ngắt ở đây
              ngat_EX0:
              reti
              ngat_timer0:
              reti
              ......

              Comment


              • #8
                Nguyên văn bởi pvkhai Xem bài viết
                Org 0000h
                Ljmp Main
                Org 0003h ; ngat dem xung encoder
                Inc R0 ; bien dem xung
                Mov A, R0
                Cjne A,#100,finish ; neu du 100 xung/vong
                INC 60H ; thi luu so vong vao R1
                Mov R0, #0 ; va xoa bien dem xung R0cho lan dem sau
                finish:
                nop
                RETI
                Org 0013H ; ngat tu ADC bao da chuyen xong tu (voltage to digital)
                Clr P3.5 ; cho phep vi dieu khien doc tu ADC (chan p3.5 dieu khien chan "READ" cua 0804
                Mov A,p1

                Setb P3.5 ; set cho lan doc tu adc sau.
                Clr P3.6 ;
                Setb P3.6 ; tao xung tu 0-->1 de cho phep "WR" from analogue to digital (dieu khien chan Write of 0804)
                RETI

                Org 001BH ; ngat bao thoi diem hien toc do ra 7segment
                ljmp Hien_thi ; ngat time 1 bao led---


                Bạn không nên viết code ngắt như trên, vì bảng vector ngắt chỉ để dành 8 ô nhớ cho mỗi chương trình ngắt, bạn viết chương trình ngắt như vậy sẽ vượt quá 8 ô nhớ chương trình. Cụ thể ở đây chương trình ngắt ngoài EX1 đã tràn qua địa chỉ 001BH của ngắt timer1 và sẽ gây rối loạn chương trình khi ngắt EX1 xãy ra.
                Bạn nên viết code như sau:
                org 0000h
                sjmp main
                org 0003h
                ljmp ngat_EX0
                org 000Bh
                ljmp ngat_timer0
                org 0013h
                ljmp ngat_EX1
                org 001bh
                ljmp ngat_timer1

                org 0030h
                main:
                ...
                ;-----------
                các chương trình ngắt ở đây
                ngat_EX0:
                reti
                ngat_timer0:
                reti
                ......
                hình như bạn nhầm chứ mình tính toán chỗ đó cũng không vượt quá 8 byte của một ngắt được phép đâu bạn ạh !!
                chương trình nào dài thì mình đã cho nó ljmp rùi...
                cái mình thắc mắc chính là trong chương trình cụ thể này làm sao để giải quyết vấn đề quét led như yêu cầu trên ....mình có hỏi...

                Comment


                • #9
                  Nguyên văn bởi duc thang Xem bài viết
                  Lưu cờ nhớ thì push toàn bộ thanh ghi có chứa cờ nhớ (không nhớ tên).
                  Theo tôi khi quét led thì tạo 1 chương trình ngắt theo thời gian. Tới thời điểm thì tắt đèn này mở đèn khác. Xong quay về chương trình chính, khi có ngắt tới thì tiếp tục.
                  bạn đức thắng nói đúng rùi có lẽ bạn phiên binh có nhầm đôi chút chớ push và pop cờ nhớ phải push và pop cả địa chỉ của thanh ghi spw (#0d0h) thì mới đc ! còn vụ quét thì bạn thấy chương trình mình cũng đã có xử lý quét như nó không ổn... thực tế mình nạp chương trình này vào at89 thì nó nhấp nháy theo chu kì một giây và đèn thì sáng rất mờ ...chứ không như mình mong muốn là cứ 1s thì 7segment sẽ cập nhận giá trị mới ..... trong khoảng 1s thì nó hiện giá trị cũ.....mình có xem một số chương trình mẫu thì đa số họ chỉ làm mỗi một việc là quét mỗi led chứ vxl không làm ghì nữa... nên tình trạng nhấp nháy này xử lý rất dễ...
                  Last edited by mongdu; 15-06-2008, 20:10.

                  Comment


                  • #10
                    Các bạn hãy đọc kỹ lời giải thích của tui rồi xem tui có nhầm không.
                    Tui đã làm gần 10 năm rồi, thiết kế bo mạch và viết Ct cho Vi xử lý bao nhiêu tui cũng không nhớ. Ct của bạn rất đơn giản, nếu các bạn cho tui nhầm thì chắc tui... bỏ nghề thôi.
                    Trên đường thành công, không có dấu chân của kẻ lười biếng.

                    Comment


                    • #11
                      Nguyên văn bởi mongdu Xem bài viết
                      bạn đức thắng nói đúng rùi có lẽ bạn phiên binh có nhầm đôi chút chớ push và pop cờ nhớ phải push và pop cả địa chỉ của thanh ghi spw (#0d0h) thì mới đc ! còn vụ quét thì bạn thấy chương trình mình cũng đã có xử lý quét như nó không ổn... thực tế mình nạp chương trình này vào at89 thì nó nhấp nháy theo chu kì một giây và đèn thì sáng rất mờ ...chứ không như mình mong muốn là cứ 1s thì 7segment sẽ cập nhận giá trị mới ..... trong khoảng 1s thì nó hiện giá trị cũ.....mình có xem một số chương trình mẫu thì đa số họ chỉ làm mỗi một việc là quét mỗi led chứ vxl không làm ghì nữa... nên tình trạng nhấp nháy này xử lý rất dễ...
                      AVR đã quay trở lại: ATMEGA32: 66k, ATMEGA8A: 30k, ATMEGA48: 30k.
                      Xem thêm tại Online Store ---> Click here
                      Mob: 0982.083.106

                      Comment


                      • #12
                        Nguyên văn bởi mongdu Xem bài viết
                        hình như bạn nhầm chứ mình tính toán chỗ đó cũng không vượt quá 8 byte của một ngắt được phép đâu bạn ạh !!
                        chương trình nào dài thì mình đã cho nó ljmp rùi...
                        cái mình thắc mắc chính là trong chương trình cụ thể này làm sao để giải quyết vấn đề quét led như yêu cầu trên ....mình có hỏi...
                        Bạn nên xem đoạn code trên file list như sau :

                        0013 17 Org 0013H ; ngat tu ADC bao da chuyen xong tu (voltage to digital)
                        0013 C2B5 18 Clr P3.5 ; cho phep vi dieu khien doc tu ADC (chan p3.5 dieu khien chan "READ" cua 0804
                        0015 E590 19 Mov A,p1
                        20
                        0017 D2B5 21 Setb P3.5 ; set cho lan doc tu adc sau.
                        0019 C2B6 22 Clr P3.6 ;
                        001B D2B6 23 Setb P3.6 ; tao xung tu 0-->1 de cho phep "WR" from analogue to digital (dieu khien chan Wr
                        ite of 0804)
                        001D 32 24 RETI ; CHÚ Ý LỆNH NÀY ĐÃ TRÀN QUA ĐỊA CHỈ 001BH CỦA NGẮT TIMER1
                        25
                        001B 26 Org 001BH ; ngat bao thoi diem hien toc do ra 7segment
                        001B 020080 27 ljmp Hien_thi ; ngat time 1 bao led---

                        Bạn chú ý lệnh Setb P3.5 và lệnh Reti ở đoạn code trên đã tràn qua địa chỉ 001BH của ngắt Timer1
                        Bạn nên để ý rằng đa số lệnh Assembly chiếm 2 byte!
                        Chúc vui!

                        Comment


                        • #13
                          Nguyên văn bởi phienbinh Xem bài viết
                          Các bạn hãy đọc kỹ lời giải thích của tui rồi xem tui có nhầm không.
                          Tui đã làm gần 10 năm rồi, thiết kế bo mạch và viết Ct cho Vi xử lý bao nhiêu tui cũng không nhớ. Ct của bạn rất đơn giản, nếu các bạn cho tui nhầm thì chắc tui... bỏ nghề thôi.
                          ừ thì có thể là nhầm mà sao bác lại nổi nóng thế nhỉ ????? diễn đàn để we thảo luận cơ mà
                          mình đã thử sửa lại ở mỗi chương trình ngắt đều có cất cf và acc và hiệu chỉnh thêm phần ngắt từ encoder thì cũng tạm ổn .... kể cả 8 led ở ngõ ra của adc0804 cũng thay đổi mỗi khi mình điều chỉnh biến trở........
                          nhưng không hiểu sao nó động cơ cứ đứng đứng đực ra........ thế là bực wa bỏ lun cái phần text biến trỏ để ở min thì stop motor thì nó chạy nhưng khi thay đổi giá trị biến trở thấy tốc độ dừng như chẳng thay đổi trong khi chương trình của mình lun cập nhật từ adc ......

                          Comment


                          • #14
                            Quét Led

                            Nguyên văn bởi mongdu Xem bài viết
                            bạn có thể cho mình hỏi thêm ... về quét led :
                            1/ cách định nghĩa về tần số quét...thực chất giải sử trong mạch cần hiển thị có "X" led thì tần số này được hiểu là khoảng thời gian bạn sẽ lặp lại việc cho sáng từ led 1--> led thứ "X"của bạn ???
                            2/ trong kĩ thuật quét giả sự bạn đưa baze của transistor về mức thấp hoặc mức cao để cho led sáng điều này phụ thuộc vào loại đó là pnp or npn... và sau đó sẽ gọi một hàm delay trước khi cho nó off để sang led 2 vvvv.........
                            3/ giả sử trong bài này mình muốn led của mình sau 1s mới được cập nhật giá trị mới từ encoder mà nó đếm được ......... trong khoảng 1s này thì chương trình phải xử lý nhiều việc khác ..... vậy phải thỏa mãn sao để nó không bị nhấp nháy ?????/
                            Những phần lặp đi lặp lại trong khoảng thời gian cố định (tuần hoàn) như chương trình quét led chẳng hạn, bạn viết chương trình trong 1 ngắt timer ( T0 chẳng hạn), đến hẹn lại lên > xong về main program (làm chuyện khác).
                            Chương trình quét tự động hiển thị (về thời gian), thông số hiển thị thì viết bên main program. Thân

                            Comment


                            • #15
                              cảm ơn các bạn đã góp ý thứ 7 tuần trước mình đã bảo vệ xong đồ án 1 này rùi.... mạch chạy tương đối ổn......hi !

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X