Thông báo

Collapse
No announcement yet.

cách dùng nhiều ngắt cho 8051

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

  • cách dùng nhiều ngắt cho 8051

    mấy a chỉ cho e cách dùng nhiều ngắt trong lập trình vdk 8051 với. e đang lam bài tập có đề là như thế này:viết chương trình ngắt timer để tạo đồng thời 2 sóng vuông 1khz và 50khz tại p1.0 và p1.1 (tần số dao động của thạch anh 12Mhz)

  • #2
    Nguyên văn bởi imyour_nnc Xem bài viết
    mấy a chỉ cho e cách dùng nhiều ngắt trong lập trình vdk 8051 với. e đang lam bài tập có đề là như thế này:viết chương trình ngắt timer để tạo đồng thời 2 sóng vuông 1khz và 50khz tại p1.0 và p1.1 (tần số dao động của thạch anh 12Mhz)
    thì bạn chỉ cần dùng ngắt 2 timer thôi là đc rồi.
    Last edited by chung1608; 23-12-2011, 17:28.

    Comment


    • #3
      Èo cái này làm gì mà bạn phải dùng tới 2 ngắt vậy. Cái này dùng 1 ngắt Timer chế độ 16bits là được.

      Comment


      • #4
        Nguyên văn bởi OoMrBayoO Xem bài viết
        Èo cái này làm gì mà bạn phải dùng tới 2 ngắt vậy. Cái này dùng 1 ngắt Timer chế độ 16bits là được.
        chủ thớt cần ngắt nhiều thì cho ngắt 2 cái, thực tế ngắt 1 cái cũng đc nhưng timer ngắt chạy 16bits thì ko thể tạo 2 xung này đc. Chú nói tạo đc thì chú viết thử 1 đoạn với ngắt timer 16bits tạo 2 xung trên xem.

        Comment


        • #5
          Bạn dùng 1 Timer bất kì rồi nhân lên thành 10 con hay 100 con hay 255 con timer rồi dùng dần

          Ví dụ như sử dụng ngắt timer để tạo ra 32 con timer khác rồi sử dụng tạo 32 xung với 32 tần số khác nhau đưa ra 32 chân chíp ...

          Bạn thử làm với ý tưởng này nhé ... Chúc thành công.

          Comment


          • #6
            bạn ơi 1 timer làm sao có thể thực hiện 2 ngắt cùng 1 lần dc hả bạn,bạn thử đưa ra 1 vị dụ để thuyết phục mọi ng đi

            Comment


            • #7
              ý bạn đấy là thế này chứ đâu phải 1 timer thực hiện 2 ngắt 1 lúc

              Code:
              time0:
              inc dem
              mov a,dem
              cjne a,do_sang_red,clr_pwm_green
              clr pwm_red
              clr_pwm_green:
              cjne a,do_sang_green,clr_pwm_blu
              clr pwm_green
              clr_pwm_blu:
              cjne a,do_sang_blu,setb_pwm
              clr pwm_blu
              setb_pwm:
              cjne a,#255,exit
              mov p0,#0ffh
              exit:
              reti

              Comment


              • #8
                Nguyên văn bởi anh_hung_21 Xem bài viết
                bạn ơi 1 timer làm sao có thể thực hiện 2 ngắt cùng 1 lần dc hả bạn,bạn thử đưa ra 1 vị dụ để thuyết phục mọi ng đi
                không phải 2 ngắt 1 lần mà là nửa chu kỳ các xung đc tạo ra là bội số của thời gian timer chạy từ đó dùng bộ đếm để quản lý bên trong ngắt. Mỗi lần ngắt thì đi kiểm tra các bộ đếm, bộ đếm nào trống thì thay đổi trạng thái xung của bộ đếm đó.

                Comment


                • #9
                  Mình lấy ví dụ thế này nhé, để dễ hiểu mình trình bầy thuật toán là chính có dùng thêm code C các bạn tùy vào môi trường lập trình và ngôn ngữ sử dụng mà thay đổi cho thích hợp nhé ...

                  1. Ý tưởng: Ngày xưa mình học Vi điều khiển và PLC song song (PLC S7200 - siements) mình có nhận xét thế này:
                  Con PLCs7200 trong nó cũng chỉ là một con vi diều khiển họ 8051 vậy mà trong khi sử dụng môi trường lập trình của nó ta có thể chon độ phân giải timer và có rất nhiều timer để sử dụng ... vậy thì phần cứng nào đáp ứng được điều này. Mình đã tìm ra câu trả lời tất cả nằm ở phần mềm.

                  2. Không cam chịu: Vi điều khiển cũng có thể làm được chỉ có điều phải khá thận trọng trong việc xử lý ngắt timer tránh việc thời gian xử lý các câu lệnh trong ngắt lớn hơn thời gian ngắt của timer

                  3. Thử lập trình tạo ra 8 con timer để nháy 8 con led với 8 tân số khác nhau trong một dải tần số hạn chế nào đó
                  Bước 1: Cài đặt và tạo một ngắt timer khoảng 1ms tùy bạn
                  Bước 2: Khai báo biến để sử dụng
                  int timer_tutao(8)={}; //khai báo biến mảng cho dễ dùng ... tùi ý đặt tên
                  Bước 3: Viết thêm lệnh trong hàm ngắt của timer nhằm mục đích đếm tăng các biến vừa khai báo
                  Ngat_timer()
                  {
                  for (i=0,i<=7,i++)
                  {
                  timer_tutao[i] = timer_tutao[i] +1;
                  }
                  }
                  Như vậy vô hình chung ta đã tạo được 8 time line độ phân giải 1ms, chạy từ 0 đến 65535 ( int mà - tùi vào ứng dụng ta dùng kiểu biến cho hợp lí )

                  Bước 4: Sử dụng timer chúng ta vừa tạo ra trong chương trình chính như thế nào ?
                  void main()
                  {
                  // -------------- các lệnh khởi tạo ban đầu --------
                  // trước khi sử dụng timer_tutao nào đó ta reset giá trị cho timer đó

                  timer_tutao[0] = 0;
                  timer_tutao[4] = 0;
                  timer_tutao[7] = 0;

                  // ----------- hết các lệnh khởi tạo ban đầu -------

                  while(1) // vòng lặp chính của chương trình
                  {
                  //-----------------đoạn chương trình nhấp nháy led với f=1hz độ đầy 10% ------------------
                  if ((timer_tutao[0] >0) & (timer_tutao[0]<100)) {led1 = 0;}
                  if ((timer_tutao[0] >=100) & (timer_tutao[0]<1000)) {led1 = 1;}
                  if (timer_tutao[0] >= 1000) { timer_tutao[0]=0;}

                  //-----------------đoạn chương trình nhấp nháy led với f=1/T = 1 / 0.2 = 5hz độ đầy 50%
                  if ((timer_tutao[4] >0) & (timer_tutao[4]<100)) {led2 = 0;}
                  if ((timer_tutao[4] >=100) & (timer_tutao[4]<200)) {led2 = 1;}
                  if (timer_tutao[4] >= 200) { timer_tutao[4]=0;}

                  //-----------------đoạn chương trình nhấp nháy led với f=1hz độ đầy 50% ------------------
                  if ((timer_tutao[7] >0) & (timer_tutao[7]<500)) {led3 = 0;}
                  if ((timer_tutao[7] >=500) & (timer_tutao[7]<1000)) {led3 = 1;}
                  if (timer_tutao[7] >= 1000) { timer_tutao[7]=0;}
                  }
                  }

                  Bước 5: Triển khai và những ứng dụng mở rộng

                  Với cách viết như vậy ta có thể linh hoạt hơn trong việc quy hoạch chương trình chính, chương trính viết khéo sẽ không bị dừng tại đâu cả liên tục thực hiện qua các hàm và chương trình con.

                  Ta có thể phân bổ cho chương trình quét nút sau khoảng 100ms quét 1 lần , hiẻn thị LCD không nhất thiết phải bắng tằng tằng dữ liệu lên cho khoảng 40 ms cập nhật một lần (LCD không cần phải có tần số làm tươi lớn hơn 30 hình 1s làm gì cho phí hiệu năng của chíp), quét sensor dò đường 10ms một lần, quét cảm biến vật cản trước của robot 50ms, chống nhiễu rung tiếp điểm, trễ thời gian không chết chương tình ...vv ...

                  Đây cũng chính là bước đầu tiên để tập tành thực hiện viết một nhân hệ điều hành on chip vô cùng vô cùng cơ bản và ít tính năng.

                  Hi vọng với ý tưởng trên đây những bạn đang học lập trình Vi điều khiển sẽ có thêm một công cụ mới ý tưởng mới cho các đề tài lớn. Chúc vui.

                  Các bạn hãy thử cùng phân tích ưu điểm và nhược điểm của công cụ nhân bản timer này nhé ... !

                  Comment


                  • #10
                    Các anh ơi giúp em cái này với ạ
                    So sánh 2 phương pháp lập trình tạo trễ trong 8051 là
                    1. Dùng Timer.
                    2. Dùng vòng lặp.
                    Em cảm ơn các anh trước ạ.

                    Comment


                    • #11
                      HIx có ai không ạ giúp em với huhu

                      Comment


                      • #12
                        Nguyên văn bởi namctmc Xem bài viết
                        Các anh ơi giúp em cái này với ạ
                        So sánh 2 phương pháp lập trình tạo trễ trong 8051 là
                        1. Dùng Timer.
                        2. Dùng vòng lặp.
                        Em cảm ơn các anh trước ạ.
                        timer và vòng lặp bằng C đều có ưu nhược điểm, nếu xét về độ chính xác thì timer chuẩn hơn nhưng ko chuẩn hoàn toàn, thông thường mình xài trễ = C hơn vì các timer hầu hết mình toàn xài cho các ứng dụng khác chứ timer chỉ để làm cái delay thì phí phạm quá, chương trình ném hết vào ngắt, trong main để trống
                        Website chính thức đổi địa chỉ website thành
                        Mời các bạn ghé thăm !!!

                        Comment


                        • #13
                          Nguyên văn bởi robot_arm Xem bài viết
                          Mình lấy ví dụ thế này nhé, để dễ hiểu mình trình bầy thuật toán là chính có dùng thêm code C các bạn tùy vào môi trường lập trình và ngôn ngữ sử dụng mà thay đổi cho thích hợp nhé ...

                          1. Ý tưởng: Ngày xưa mình học Vi điều khiển và PLC song song (PLC S7200 - siements) mình có nhận xét thế này:
                          Con PLCs7200 trong nó cũng chỉ là một con vi diều khiển họ 8051 vậy mà trong khi sử dụng môi trường lập trình của nó ta có thể chon độ phân giải timer và có rất nhiều timer để sử dụng ... vậy thì phần cứng nào đáp ứng được điều này. Mình đã tìm ra câu trả lời tất cả nằm ở phần mềm.

                          2. Không cam chịu: Vi điều khiển cũng có thể làm được chỉ có điều phải khá thận trọng trong việc xử lý ngắt timer tránh việc thời gian xử lý các câu lệnh trong ngắt lớn hơn thời gian ngắt của timer

                          3. Thử lập trình tạo ra 8 con timer để nháy 8 con led với 8 tân số khác nhau trong một dải tần số hạn chế nào đó
                          Bước 1: Cài đặt và tạo một ngắt timer khoảng 1ms tùy bạn
                          Bước 2: Khai báo biến để sử dụng
                          int timer_tutao(8)={}; //khai báo biến mảng cho dễ dùng ... tùi ý đặt tên
                          Bước 3: Viết thêm lệnh trong hàm ngắt của timer nhằm mục đích đếm tăng các biến vừa khai báo
                          Ngat_timer()
                          {
                          for (i=0,i<=7,i++)
                          {
                          timer_tutao[i] = timer_tutao[i] +1;
                          }
                          }
                          Như vậy vô hình chung ta đã tạo được 8 time line độ phân giải 1ms, chạy từ 0 đến 65535 ( int mà - tùi vào ứng dụng ta dùng kiểu biến cho hợp lí )

                          Bước 4: Sử dụng timer chúng ta vừa tạo ra trong chương trình chính như thế nào ?
                          void main()
                          {
                          // -------------- các lệnh khởi tạo ban đầu --------
                          // trước khi sử dụng timer_tutao nào đó ta reset giá trị cho timer đó

                          timer_tutao[0] = 0;
                          timer_tutao[4] = 0;
                          timer_tutao[7] = 0;

                          // ----------- hết các lệnh khởi tạo ban đầu -------

                          while(1) // vòng lặp chính của chương trình
                          {
                          //-----------------đoạn chương trình nhấp nháy led với f=1hz độ đầy 10% ------------------
                          if ((timer_tutao[0] >0) & (timer_tutao[0]<100)) {led1 = 0;}
                          if ((timer_tutao[0] >=100) & (timer_tutao[0]<1000)) {led1 = 1;}
                          if (timer_tutao[0] >= 1000) { timer_tutao[0]=0;}

                          //-----------------đoạn chương trình nhấp nháy led với f=1/T = 1 / 0.2 = 5hz độ đầy 50%
                          if ((timer_tutao[4] >0) & (timer_tutao[4]<100)) {led2 = 0;}
                          if ((timer_tutao[4] >=100) & (timer_tutao[4]<200)) {led2 = 1;}
                          if (timer_tutao[4] >= 200) { timer_tutao[4]=0;}

                          //-----------------đoạn chương trình nhấp nháy led với f=1hz độ đầy 50% ------------------
                          if ((timer_tutao[7] >0) & (timer_tutao[7]<500)) {led3 = 0;}
                          if ((timer_tutao[7] >=500) & (timer_tutao[7]<1000)) {led3 = 1;}
                          if (timer_tutao[7] >= 1000) { timer_tutao[7]=0;}
                          }
                          }

                          Bước 5: Triển khai và những ứng dụng mở rộng

                          Với cách viết như vậy ta có thể linh hoạt hơn trong việc quy hoạch chương trình chính, chương trính viết khéo sẽ không bị dừng tại đâu cả liên tục thực hiện qua các hàm và chương trình con.

                          Ta có thể phân bổ cho chương trình quét nút sau khoảng 100ms quét 1 lần , hiẻn thị LCD không nhất thiết phải bắng tằng tằng dữ liệu lên cho khoảng 40 ms cập nhật một lần (LCD không cần phải có tần số làm tươi lớn hơn 30 hình 1s làm gì cho phí hiệu năng của chíp), quét sensor dò đường 10ms một lần, quét cảm biến vật cản trước của robot 50ms, chống nhiễu rung tiếp điểm, trễ thời gian không chết chương tình ...vv ...

                          Đây cũng chính là bước đầu tiên để tập tành thực hiện viết một nhân hệ điều hành on chip vô cùng vô cùng cơ bản và ít tính năng.

                          Hi vọng với ý tưởng trên đây những bạn đang học lập trình Vi điều khiển sẽ có thêm một công cụ mới ý tưởng mới cho các đề tài lớn. Chúc vui.

                          Các bạn hãy thử cùng phân tích ưu điểm và nhược điểm của công cụ nhân bản timer này nhé ... !
                          cái này có bị hay quá không vậy :v
                          không hiểu sao bây giờ em mới đọc được bài viết này của a, đúng là chưa có duyên.
                          a còn thủ thuật gì hay chia sẻ nốt cho ae đi a ơi, quá hay, quá hữu ích!

                          Comment


                          • #14
                            Đề bài yêu cầu: HIển thị lần lượt 4 số trên 4 led 7 đoạn, dùng cổng P1.[3:0]. Sử dụng ngắt P3.3 cho phép ngắt ngoài.
                            Mong các bạn giúp đỡ thêm.
                            Code này chỉ là 2 led nhưng lại không đếm lần lượt.
                            #include <sfr51.inc>
                            ORG 00H
                            LJMP MAIN
                            ORG 0013H ; dia chi vector ngat ngoai1
                            LJMP INT1_EX
                            MAIN:
                            SETB EA ;cho phep ngat
                            SETB EX1 ;ngat ngoai1
                            SETB IT1 ;ngat canh ngoai1
                            MOV DPTR,#CODELED
                            MOV R0,#01H
                            MOV R1,#00H
                            DISP:
                            MOV A,R0
                            MOVC A,@A+DPTR
                            MOV P0,A
                            MOV A,R1
                            MOVC A,@A+DPTR
                            MOV P1,A
                            CJNE R0,#9,NEXT
                            CJNE R1,#10,DISP
                            SJMP MAIN
                            NEXT:
                            CJNE R0,#10,DISP
                            MOV R0,#00H
                            SJMP DISP
                            CODELED:
                            DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
                            RET
                            INT1_EX:
                            INC R0
                            CJNE R0,#10,JUMPER
                            MOV R0,#0
                            INC R1
                            CJNE R1,#10,JUMPER
                            MOV R1,#0
                            JUMPER:
                            RETI
                            END

                            Comment


                            • #15
                              Nguyên văn bởi 1zx2zx Xem bài viết
                              Đề bài yêu cầu: HIển thị lần lượt 4 số trên 4 led 7 đoạn, dùng cổng P1.[3:0]. Sử dụng ngắt P3.3 cho phép ngắt ngoài.
                              Mong các bạn giúp đỡ thêm.
                              Code này chỉ là 2 led nhưng lại không đếm lần lượt.
                              #include <sfr51.inc>
                              ORG 00H
                              LJMP MAIN
                              ORG 0013H ; dia chi vector ngat ngoai1
                              LJMP INT1_EX
                              MAIN:
                              SETB EA ;cho phep ngat
                              SETB EX1 ;ngat ngoai1
                              SETB IT1 ;ngat canh ngoai1
                              MOV DPTR,#CODELED
                              MOV R0,#01H
                              MOV R1,#00H
                              DISP:
                              MOV A,R0
                              MOVC A,@A+DPTR
                              MOV P0,A
                              MOV A,R1
                              MOVC A,@A+DPTR
                              MOV P1,A
                              CJNE R0,#9,NEXT
                              CJNE R1,#10,DISP
                              SJMP MAIN
                              NEXT:
                              CJNE R0,#10,DISP
                              MOV R0,#00H
                              SJMP DISP
                              CODELED:
                              DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
                              RET
                              INT1_EX:
                              INC R0
                              CJNE R0,#10,JUMPER
                              MOV R0,#0
                              INC R1
                              CJNE R1,#10,JUMPER
                              MOV R1,#0
                              JUMPER:
                              RETI
                              END
                              liên hệ email mình: liuchengzhong@gmail.com

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X