help led quay chạy loạn theo hình tròn

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • vietluan93
    Thành viên tích cực
    • Aug 2012
    • 111

    #1

    help led quay chạy loạn theo hình tròn

    ko biết em viết code sai ở đâu mà sao chữ nó chạy theo hình tròn z mấy bác
    sửa 2 ngày nay rồi mà ko đc
    phần cứng em nối vào p1dùng ngắt 0
    mong đc sự hướng dẫn nhiết tình của mấy bác
    #include <at89x52.h>
    unsigned char j,buoc=0;
    unsigned int k=0,i=0;
    code unsigned int mang1[]={ 0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0x1,0x0EF,0x0EF,0x0EF,0x1,0x0FF, //h
    0x7,0x0EB,0x0ED,0x0EB,0x7,0x0FF, //a
    0x83,0x7D,0x7D,0x7D,0x83,0x0FF, //0
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0x7,0x0EB,0x0ED,0x0EB,0x7,0x0FF, //a
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x7,0x0EB,0x0ED,0x0EB,0x7,0x0FF, //a
    0x1,0x0F7,0x0EF,0x0DF,0x1,0x0FF, //n
    0x1,0x0EF,0x0EF,0x0EF,0x1,0x0FF, //h
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x6D,0x6D,0x6D,0x6D,0x0FF, //e
    0x1,0x0FB,0x0F7,0x0FB,0x1,0x0FF, //m
    0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x0EF,0x0D7,0x0BB,0x7D,0x0FF, //k
    0x71,0x75,0x75,0x75,0x8D,0x0FF, //5
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0x83,0x7D,0x7D,0x7D,0x83,0x0FF, //0
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x6D,0x6D,0x7D,0x83,0x0FF, //dd
    0x1,0x0FF, //i
    0x1,0x6D,0x6D,0x6D,0x6D,0x0FF, //e
    0x1,0x0F7,0x0EF,0x0DF,0x1,0x0FF, //n
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x0FD,0x0FD,0x1,0x0FD,0x0FD,0x0FF, //t
    0x81,0x7F,0x7F,0x7F,0x81,0x0FF, //u
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0x1,0x0EF,0x0EF,0x0EF,0x1,0x0FF, //h
    0x81,0x7F,0x7F,0x7F,0x81,0x0FF, //u
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x7,0x0EB,0x0ED,0x0EB,0x7,0x0FF, //a
    0x1,0x0F7,0x0EF,0x0DF,0x1,0x0FF, //n
    0x1,0x0EF,0x0EF,0x0EF,0x1,0x0FF, //h
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x6D,0x6D,0x6D,0x6D,0x0FF, //e
    0x1,0x0FB,0x0F7,0x0FB,0x1,0x0FF, //m
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x0EF,0x0EF,0x0EF,0x1,0x0FF, //h
    0x83,0x7D,0x7D,0x7D,0x83,0x0FF, //0
    0x83,0x7D,0x7D,0x7D,0x7D,0x0FF, //c
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x1,0x75,0x75,0x75,0x75,0x8B,0x0FF, //b
    0x7,0x0EB,0x0ED,0x0EB,0x7,0x0FF, //a
    0x1,0x0FF, //i
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x0C1,0x0BF,0x7F,0x7F,0x0BF,0x0C1,0x0FF, //v
    0x81,0x7F,0x7F,0x7F,0x81,0x0FF, //u
    0x1,0x0FF, //i//i
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x0C1,0x0BF,0x7F,0x7F,0x0BF,0x0C1,0x0FF, //v
    0x1,0x6D,0x6D,0x6D,0x6D,0x0FF, //e
    0x0F7,0x0FB,0x0FD,0x0FB,0x0F7,0x0BF,0x0F7,0x0FB,0x 0FD,0x0FB,0x0F7, // ^.^ //399
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff

    };
    void ISR0 (void) interrupt 0 using 2
    {
    for(i=0;i<(120+k);i++)
    {
    j=20;
    while(j--)
    {
    P1=mang1[i];
    }
    }
    P1=0xff;
    buoc++; //cho chu hien thi lau 1chut
    if(buoc==3)k++,buoc=0;
    if(k==399)k=0;
    }
    //================================================== =====================================
    void main()
    {
    P2=0xff;
    P1=0xff;
    EA=1;
    EX0=1;
    P3_0=0;
    while(1)
    {}
    }
  • NinoNguyen_
    Thành viên tích cực
    • Feb 2011
    • 349

    #2
    bạn đưa sơ đồ mạch lên đi.

    Comment

    • vietluan93
      Thành viên tích cực
      • Aug 2012
      • 111

      #3
      em dùng ngắt ngoài 0 led nối vào p1 đó bác. ngắt thì cũng hoạt động rồi mà sao chữ nó chạy vòng vòng theo hình tròn. monh bác giúp đỡ

      Comment

      • NinoNguyen_
        Thành viên tích cực
        • Feb 2011
        • 349

        #4
        Chữ nó chạy là do thời gian thực hiện hàm ngắt của bạn nó lớn hơn chu kì T của 1 vòng quay. Vì khi đang thực hiện hàm ngắt thì các nguồn ngắt đều bị disable tuy nhiên cờ ngắt vẫn được xác lập tự động bởi phần cứng. Khi thực hiện xong chương trình ngắt thì các nguồn ngắt được enable trở lại, gặp cờ ngắt ngay lập tức lại quay trở lại thực hiện chương trình ngắt. Lúc này điểm tọa độ của led quay không phải là ở điểm gốc nữa mà đã đi qua điểm gốc 1 khoảng x độ. Sau 2 lần như vậy sẽ là 2x độ so với điểm gốc, chữ C sẽ bị nhảy 1 khoảng x độ sau mỗi vòng quay, kết quả là toàn bộ ô chữ của bạn bị xoay đi.
        Để khắc phục điều này có 2 cách: Giảm thời gian thực hiện hàm ngắt, hoặc cho động cơ quay chậm hơn.
        Last edited by NinoNguyen_; 04-06-2014, 11:28.

        Comment

        • NinoNguyen_
          Thành viên tích cực
          • Feb 2011
          • 349

          #5
          Làm led quay chuyên nghiệp hơn người ta sẽ sử dụng ngắt để đo chu kì T của vòng quay từ lúc khởi động động cơ cho tới khi động cơ đạt tốc độ ổn định (nghĩa là T thay đổi rất ít). Sau đó dùng giá trị T đo được để tự động điều chỉnh việc delay của led, cuối cùng mới cho hiển thị led. Sau 1 khoảng thời gian thì lại thực hiện đo lại T.
          Làm như vậy thì đông cơ quay nhanh hay quay chậm đều hiển thị tốt, trừ khi động cơ quay quá nhanh, vượt tốc độ đáp ứng của VDK hoặc quá chậm cho hiện tượng lưu ảnh trên võng mạc thì chịu thôi.

          Comment

          • vietluan93
            Thành viên tích cực
            • Aug 2012
            • 111

            #6
            em khắc phục đc rồi bác. giờ em muốn cho nó chạy ảnh thì phải làm sao z bác? vd như em tạo 1 ngôi sao bằng pm maxtrix rồi cho nó hiển thị nhiều ngôi sao đều hết vòng tròn chạy vòng tròn z phải làm như thế nào?
            mà mình có thể chia vòng quay của led thành bao nhiu cột ở đây em dùng quạt loại nhỏ? thanks

            Comment

            • vietluan93
              Thành viên tích cực
              • Aug 2012
              • 111

              #7
              em nghĩ là nếu đưa dữ liệu ngôi sao ra VD mình quét 120 cột thì tới 120 cột nó tự động đi vào mất hk thể cho chạy vòng tròn đc mong mấy bác giúp em.

              Comment

              • NinoNguyen_
                Thành viên tích cực
                • Feb 2011
                • 349

                #8
                Điều quan trọng nhất là bạn phải nắm được chu kì T của 1 vòng quay. Giả sử bạn cho led quay 25 vòng/giây nghĩa là T=0.04s. Bạn xác lập sao cho 1 vòng quét led mất 1 khoảng thời gian <=T, nếu bằng T thì tuyệt cú mèo.
                Bình thường bạn luôn xuất dữ liệu mang1[i] tại đúng thời điểm xảy ra ngắt thì thay vào đó bạn xuất mang1[i+z], z là biết tăng theo cấp số cộng sau mỗi lần ngắt. Thằng z này tăng nhanh hay tăng chậm thì chữ của bạn cũng sẽ xoay vòng nhanh hay chậm theo nó.
                Thằng z này hoàn toàn có thể giảm theo cấp số trừ, lúc đó chữ hiển thị sẽ xoay theo chiều ngược lại.

                Comment

                • vietluan93
                  Thành viên tích cực
                  • Aug 2012
                  • 111

                  #9
                  Nguyên văn bởi NinoNguyen_ Xem bài viết
                  Điều quan trọng nhất là bạn phải nắm được chu kì T của 1 vòng quay. Giả sử bạn cho led quay 25 vòng/giây nghĩa là T=0.04s. Bạn xác lập sao cho 1 vòng quét led mất 1 khoảng thời gian <=T, nếu bằng T thì tuyệt cú mèo.
                  Bình thường bạn luôn xuất dữ liệu mang1[i] tại đúng thời điểm xảy ra ngắt thì thay vào đó bạn xuất mang1[i+z], z là biết tăng theo cấp số cộng sau mỗi lần ngắt. Thằng z này tăng nhanh hay tăng chậm thì chữ của bạn cũng sẽ xoay vòng nhanh hay chậm theo nó.
                  Thằng z này hoàn toàn có thể giảm theo cấp số trừ, lúc đó chữ hiển thị sẽ xoay theo chiều ngược lại.
                  bác nói cao quá em hk có hiểu đc.. giờ em muốn biết mình phải cần quét như thế nào để vừa kín cái vòng tròn led quay để em vẽ ngôi sao lên đó thôi.. theo em nghĩ là nếu dữ liệu vừa hết thì mình lấy cái đó đưa ra lại nữa thì sẽ ko bị cắt cái ngôi sao theo kiểu lần lượt các cột đi vào

                  Comment

                  • NinoNguyen_
                    Thành viên tích cực
                    • Feb 2011
                    • 349

                    #10
                    Vì cả 1 vòng quay của led chỉ có mỗi 1 điểm xảy ra ngắt, tại điểm này bạn biết chính xác được vị trí của led. Các điểm còn lại bạn phải dựa vào tốc độ quay của led để xác định. Nắm được tốc độ quay của led, nắm được thời gian xử lý lệnh của VDK thì bạn giải quyết xong vấn đề, muốn hiển thị thế nào là tùy bạn.

                    Comment

                    • hd03
                      Thành viên mới
                      • Aug 2014
                      • 56

                      #11
                      Bác NinoNguyen nói đúng á, chuyên nghiệp thì người ta dùng 2 lần ngắt ETX0 để đánh dấu rồi dùng Timer0 để tính thời gian giữa 2 lần ngắt. Sau đó đem thời gian đếm được chia cho số cột (người dùng đặt) thì sẽ ra thời gian delay cho mỗi cột. Như vậy led sẽ tự cân chỉnh được tốc độ mà không bị sai dữ liệu. Em đọc tài liệu của mấy bác nước ngoài thấy họ làm vậy (cao siêu hơn là tính theo độ- góc quay). VD 1 đoạn code:
                      //*****************************CROSSING INTERRUPTION*****

                      void Crossing_Interrupt(void) interrupt 0
                      {
                      int offset;
                      TR0=0;
                      TR1=0;
                      offset=(TH1*256+TL1)/time; // Calculate the time from timer 0 stop position to crossing interruption position to adjust the value of time which will be put to the TH0 and TL0 of timer 0
                      if (offset>6)
                      {
                      time++;
                      }
                      if (offset<3)
                      {
                      time--;
                      }


                      if (keypressed==1)
                      { // increase the value of 'count' to count the crossing interuption, this value is used
                      count++; //to lower the speed of increasing value of min, sec, hour when the keys are pressed
                      count1++;
                      }


                      if(count>254)
                      {
                      count=0;
                      keypressed=0;
                      }



                      TL0_value=(0xFFFF-time)%256;
                      TH0_value=(0xFFFF-time)/256;
                      TH1=0x00; //Set the value for timer 1, timer1 will calculate how many clock after timer 0 stop.
                      TL1=0x00;
                      TH0=TH0_value; //Set the value for timer 0, timer 0 will overflow every degree
                      TL0=TL0_value;
                      position=0; //Reset the position value
                      pos=0;
                      TR0=1; //start timer0
                      }
                      //************************************************** *********


                      //*******************TIMER_0 INTERRUPTION**********************

                      void Timer0_Interrupt(void) interrupt 1
                      {
                      int pos_t;
                      TF0=0; //clear the flag of timer_0 overflow
                      TL0=TL0_value;
                      TH0=TH0_value;
                      if (position==296)
                      {
                      TR0=0; // Check the position to stop timer 0 and start to count the timer 1, this process aim to solve
                      TR1=1; // the problem of overlapping interruption between timer 0 and INT 0.
                      }

                      // output data here


                      position++; //Increase the Position of degree
                      }

                      //************************************************** ****

                      Mong sẽ giúp ích được cho bạn.
                      Thân!

                      Comment

                      Về tác giả

                      Collapse

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

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

                      Collapse

                      Đang tải...