Thông báo

Collapse
No announcement yet.

Thắc mắc về quét led

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

  • Thắc mắc về quét led

    Chương trình sau em quét 4 led 7 đoạn hiển thị số, có nút nhấn để tăng giá trị của số, em dùng ngắt timer để quét led. Việc quét led thì được rồi nhưng khi nhấn nút thì số không tăng được, em không biết tại sao, nhờ các bác giúp đở.

    unsigned char z[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f,0x00};

    sbit up=P3^5;

    int so=1234;
    unsigned char ngan,tram,chuc,dvi;




    //delay ms
    void delay_ms(unsigned int ms)
    {
    while(ms--)
    {

    unsigned char temp=121;
    while(temp--);
    }
    }

    void int_timer0_handler() interrupt 1
    {
    TR0 = 0; //tam dung timer0
    TH0 = 0xFC; //nap lai gia tri
    TL0 = 0x18;
    TR0 = 1;
    P2=z[ngan];P0_0=0;delay_ms(1);P0=0xff;
    P2=z[tram];P0_1=0;delay_ms(1);P0=0xff;
    P2=z[chuc];P0_2=0;delay_ms(1);P0=0xff;
    P2=z[dvi];P0_3=0;delay_ms(1); P0=0xff;
    }

    main()
    {
    IE = 0x82; //cho phep ngat timer 0
    TMOD = 0x11; //mode 1 (16bits)
    IT0 = 1; //ngat ngoai canh cho timer0 (trong thanh ghi TCON)
    TF0 = 1; //bat dau ngat timer0
    while(1)
    {
    ngan=so1000;
    tram=(so/100)%10;
    chuc=(so%100)/10;
    dvi=(so%100)%10;

    if(!up)
    {
    TR0=0;
    delay_ms(5);while(!up);delay_ms(5);
    so++;
    TR0=1;
    }

    }

    }

  • #2
    nguyên nhân rất đơn giản đó là thời gian ngắt chiếm quá nhiều thời gian và việc ngắt xảy ra liên tục+quá nhanh khiến nó ko thể thực hiện được chuơng trình phục vụ đếm số
    có 2 cách khắc phục cho bài này
    1) bạn chuyển hàm quét led vào trong main, chứ ko để ở ngắt nữa để tránh việc ngắt liên tục khiến nó ko thể thực hiện được công việc trong main thì đã lại phải đi thực hiện ngắt mới
    2) nếu bạn vẫn muốn dùng ngắt để quét led thì hãy dùng 1 ngắt nữa đó là ngắt ngoài để đếm, và ưu tiên ngắt ngoài hơn ngắt timer, như vậy khi có phím được bấm, nó sẽ dừng ngắt timer và nhảy ngay đến ngắt ngoài để tăng biến đếm sau đó mới quay lại quét led
    Website chính thức đổi địa chỉ website thành
    Mời các bạn ghé thăm !!!

    Comment


    • #3
      Nhưng khi có tín hiệu nhấn nút mình đã cho tạm dừng timer rồi mà, sao vẫn không được hả bạn

      Comment


      • #4
        ko phải là khi có tín hiệu nhấn nút thì bạn cho dừng timer là được mà tại cái thời điểm đếm nút nó đang thực hiện cái công việc quét led lên nó ko phục vụ bạn việc nhấn nút
        để dế hiểu mình ví dụ như sau, của bạn có 10 công việc trong cái while(1)
        cv1
        cv2
        cv3
        .......
        cv10
        gia su cai nhan phim la cai cv10
        vậy cái thời điểm bạn ấn phím nó đang thực hiện cv1->9 thì chắc chắn việc bạn ấn phím nó chả có ý nghĩa j cả, nó đang làm công việc khác chứ có chờ bạn ấn phím đâu
        bạn cứ thử thay bằng ngắt ngoài xem và ưu tiên ngắt ngoài hơn ngắt timer là được, cái này giống kiểu đếm sản phẩm ý mà
        Website chính thức đổi địa chỉ website thành
        Mời các bạn ghé thăm !!!

        Comment


        • #5
          @phuong197: bạn thử xem lại phần cứng kết nối nút nhấn, khi nhấn, điện áp đo được đã thỏa mãn mức logic để vdk nhận chưa? Nhiều trường hợp lí do là như vậy đó? Bạn cũng có thể test lại ct xem ntn? Chúc bạn thành công!
          Đối với Tôi Đam mê là yếu tố không thể thiếu để quyết định sự Thành Công ...!
          Gmail: -Mobile: 0989.194.472

          Comment


          • #6
            Nguyên văn bởi phuong197 Xem bài viết
            Chương trình sau em quét 4 led 7 đoạn hiển thị số, có nút nhấn để tăng giá trị của số, em dùng ngắt timer để quét led. Việc quét led thì được rồi nhưng khi nhấn nút thì số không tăng được, em không biết tại sao, nhờ các bác giúp đở.

            unsigned char z[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f,0x00};

            sbit up=P3^5;

            int so=1234;
            unsigned char ngan,tram,chuc,dvi;




            //delay ms
            void delay_ms(unsigned int ms)
            {
            while(ms--)
            {

            unsigned char temp=121;
            while(temp--);
            }
            }

            void int_timer0_handler() interrupt 1
            {
            TR0 = 0; //tam dung timer0
            TH0 = 0xFC; //nap lai gia tri
            TL0 = 0x18;
            TR0 = 1;
            P2=z[ngan];P0_0=0;delay_ms(1);P0=0xff;
            P2=z[tram];P0_1=0;delay_ms(1);P0=0xff;
            P2=z[chuc];P0_2=0;delay_ms(1);P0=0xff;
            P2=z[dvi];P0_3=0;delay_ms(1); P0=0xff;
            }

            main()
            {
            IE = 0x82; //cho phep ngat timer 0
            TMOD = 0x11; //mode 1 (16bits)
            IT0 = 1; //ngat ngoai canh cho timer0 (trong thanh ghi TCON)
            TF0 = 1; //bat dau ngat timer0
            while(1)
            {
            ngan=so1000;
            tram=(so/100)%10;
            chuc=(so%100)/10;
            dvi=(so%100)%10;

            if(!up)
            {
            TR0=0;
            delay_ms(5);while(!up);delay_ms(5);
            so++;
            TR0=1;
            }

            }

            }
            Để chương trình trong sáng-dễ nhìn và tránh lỗi về sau thì bạn nên khai báo, xác định rõ các thông số và yêu cầu! Vd như:
            - Dùng thạch anh bao nhiêu?
            - Quét led bằng ngắt timer 0 thì chu kì quét là bao nhiêu? (THL0 = 0xFC18?)
            - Không dùng dư (vì thấy bạn dùng cả bit IT0=1 và M01=1 chả để làm gì!)
            - Và lưu ý set chân P35 trước khi đọc trạng thái vào!
            !e

            Comment


            • #7
              Nguyên văn bởi mast090 Xem bài viết
              ko phải là khi có tín hiệu nhấn nút thì bạn cho dừng timer là được mà tại cái thời điểm đếm nút nó đang thực hiện cái công việc quét led lên nó ko phục vụ bạn việc nhấn nút
              để dế hiểu mình ví dụ như sau, của bạn có 10 công việc trong cái while(1)
              cv1
              cv2
              cv3
              .......
              cv10
              gia su cai nhan phim la cai cv10
              vậy cái thời điểm bạn ấn phím nó đang thực hiện cv1->9 thì chắc chắn việc bạn ấn phím nó chả có ý nghĩa j cả, nó đang làm công việc khác chứ có chờ bạn ấn phím đâu
              bạn cứ thử thay bằng ngắt ngoài xem và ưu tiên ngắt ngoài hơn ngắt timer là được, cái này giống kiểu đếm sản phẩm ý mà
              Theo mình nghỉ thì sau khi thực hiện ngắt xong nó sẽ tiếp tục thực hiện cv10, và thời gian thực hiện từ cv1-cv9 cộng với ngắt chỉ khoảng vài ms là cùng. Nếu mình giữ nút trong vài ms thì phải đọc được chứ

              Comment


              • #8
                rất khó, ít nhất bạn phải giữ vài phút là ít chứ ko phải vài s nhé, kinh nghiệm thực tế rồi, thời gian ngắt xảy quá liên tục, khiến nó chưa kịp nhảy vào main được bao lâu thì lại ngắt, tầm khoảng 0,5ms nó ngắt 1 lần thì bạn giữ chán chê cũng còn miết
                hãy dùng thêm ngắt ngoài đi, rồi bạn sẽ ra vấn đề , lúc đó hãng đặt câu hỏi vì sao làm thế kia ko được, với 8051 nó có cái ưu tiên ngắt lên rất thuận tiện, đang làm j nó cũng có thể gác lại để thực hiện
                còn nếu ko muốn dùng bất cứ ngắt nào nữa thì quay về cách 1 mình đã nói ở trên, mình chỉ nói thế thôi, hãy thay đổi cách làm đi, đã nói rất chi tiết rồi
                mình sẽ ko góp ý thêm gì nữa
                Last edited by mast090; 15-06-2011, 15:34.
                Website chính thức đổi địa chỉ website thành
                Mời các bạn ghé thăm !!!

                Comment


                • #9
                  Nguyên văn bởi mast090 Xem bài viết
                  1) bạn chuyển hàm quét led vào trong main, chứ ko để ở ngắt nữa để tránh việc ngắt liên tục khiến nó ko thể thực hiện được công việc trong main thì đã lại phải đi thực hiện ngắt mới
                  Bạn này dùng 1 biến tạm, gọi nó như 1 cái cờ vậy, khi có ngắt timer xảy ra, cờ set=1

                  If(flag==1) {quetled();}
                  If(flag==0) {}; // ko làm gì cả

                  nếu có ngắt xảy ra, thì vào hàm main mình sẽ quét led, ko có thì ko làm, quét led xong rồi thì tắt cờ đi,

                  Mình thấy trong ngắt timer, chưa thực hiện xong công việc bạn này đã bật timer trở lại rồi, đáng lẽ cái dòng TR0 = 1; phải đặt cuối
                  - Mạch nạp vdk 8051, AVR, PIC, EEPROM
                  - Linh kiện điện tử cho sinh viên


                  Comment


                  • #10
                    Nguyên văn bởi phuong197 Xem bài viết
                    Chương trình sau em quét 4 led 7 đoạn hiển thị số, có nút nhấn để tăng giá trị của số, em dùng ngắt timer để quét led. Việc quét led thì được rồi nhưng khi nhấn nút thì số không tăng được, em không biết tại sao, nhờ các bác giúp đở.

                    unsigned char z[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f,0x00};

                    sbit up=P3^5;

                    int so=1234;
                    unsigned char ngan,tram,chuc,dvi;




                    //delay ms
                    void delay_ms(unsigned int ms)
                    {
                    while(ms--)
                    {

                    unsigned char temp=121;
                    while(temp--);
                    }
                    }

                    void int_timer0_handler() interrupt 1
                    {
                    TR0 = 0; //tam dung timer0
                    TH0 = 0xFC; //nap lai gia tri
                    TL0 = 0x18;
                    TR0 = 1;
                    P2=z[ngan];P0_0=0;delay_ms(1);P0=0xff;
                    P2=z[tram];P0_1=0;delay_ms(1);P0=0xff;
                    P2=z[chuc];P0_2=0;delay_ms(1);P0=0xff;
                    P2=z[dvi];P0_3=0;delay_ms(1); P0=0xff;
                    }

                    main()
                    {
                    IE = 0x82; //cho phep ngat timer 0
                    TMOD = 0x11; //mode 1 (16bits)
                    IT0 = 1; //ngat ngoai canh cho timer0 (trong thanh ghi TCON)
                    TF0 = 1; //bat dau ngat timer0
                    while(1)
                    {
                    ngan=so1000;
                    tram=(so/100)%10;
                    chuc=(so%100)/10;
                    dvi=(so%100)%10;

                    if(!up)
                    {
                    TR0=0;
                    delay_ms(5);while(!up);delay_ms(5);
                    so++;
                    TR0=1;
                    }

                    }

                    }
                    Mình thấy code ổn mà. Lỗi này bạn kiểm tra lại phần nút nhấn xem có lỗi nào ko, nhất thiết phải có điện trở treo cho chân P3.5. Không ngoại trừ trường hợp chân P3.5 bị hư, bạn thử chuyển nút nhấn sang chân khác xem

                    Comment


                    • #11
                      Mình chưa xem kỹ code của bạn. Nhưng theo mình, khi bạn muốn đọc phím thì nên dùng thêm 1 timer(nếu vẫn còn dư timer) để quét, khi đó bạn có thể quét rất nhiều phím khác nhau mà ko sợ nhấn phím đúng lúc VDK đang làm việc khác.
                      Có nghĩa là bạn dùng 1 timer để tạo ra 1 khoảng thời gian t nào đó(thường rất nhỏ) để kiểm tra phím có được nhấn hay ko?
                      Bạn tham khảo.
                      http://www.mediafire.com/?pziekzs4tihg93s
                      Mua bán thiết bị điện công nghiệp tại Hà Nội, toàn quốc.
                      http://diencongnghiep360.com/
                      http://tudienhathe.vn/

                      Comment


                      • #12
                        Nguyên văn bởi phuong197 Xem bài viết
                        Chương trình sau em quét 4 led 7 đoạn hiển thị số, có nút nhấn để tăng giá trị của số, em dùng ngắt timer để quét led. Việc quét led thì được rồi nhưng khi nhấn nút thì số không tăng được, em không biết tại sao, nhờ các bác giúp đở.

                        unsigned char z[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f,0x00};

                        sbit up=P3^5;

                        int so=1234;
                        unsigned char ngan,tram,chuc,dvi;




                        //delay ms
                        void delay_ms(unsigned int ms)
                        {
                        while(ms--)
                        {

                        unsigned char temp=121;
                        while(temp--);
                        }
                        }

                        void int_timer0_handler() interrupt 1
                        {
                        TR0 = 0; //tam dung timer0
                        TH0 = 0xFC; //nap lai gia tri
                        TL0 = 0x18;
                        TR0 = 1;
                        P2=z[ngan];P0_0=0;delay_ms(1);P0=0xff;
                        P2=z[tram];P0_1=0;delay_ms(1);P0=0xff;
                        P2=z[chuc];P0_2=0;delay_ms(1);P0=0xff;
                        P2=z[dvi];P0_3=0;delay_ms(1); P0=0xff;
                        }

                        main()
                        {
                        IE = 0x82; //cho phep ngat timer 0
                        TMOD = 0x11; //mode 1 (16bits)
                        IT0 = 1; //ngat ngoai canh cho timer0 (trong thanh ghi TCON)
                        TF0 = 1; //bat dau ngat timer0
                        while(1)
                        {
                        ngan=so1000;
                        tram=(so/100)%10;
                        chuc=(so%100)/10;
                        dvi=(so%100)%10;

                        if(!up)
                        {
                        TR0=0;
                        delay_ms(5);while(!up);delay_ms(5);
                        so++;
                        TR0=1;
                        }

                        }

                        }
                        lí do thời gian hiển thị >hơn thời gian ngắt time ,cho nên xảy ra ngắt liên tục .
                        sửa lại:
                        Code:
                        void int_timer0_handler() interrupt 1
                        {
                          TR0 = 0;                                           //tam dung timer0
                          TH0 = 0xFC;       //nap lai gia tri
                          TL0 = 0x18;
                                    P2=z[ngan];P0_0=0;delay_ms(1);P0=0xff;
                           P2=z[tram];P0_1=0;delay_ms(1);P0=0xff;
                           P2=z[chuc];P0_2=0;delay_ms(1);P0=0xff;
                           P2=z[dvi];P0_3=0;delay_ms(1); P0=0xff;       
                        TR0 = 1; đưa dòng này xuống đây
                        }
                        code trên còn nhược điểm khi nhấn nút mà giữ thì màn hình tối thui.
                        để khắc phuc phục điểm trên viết lại code như sau:
                        Code:
                           #include <at89x51.h>
                        char ma[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
                        sbit up=P3^5;
                        int so=1234;
                        unsigned char ngan,tram,chuc,dvi;
                        
                        
                        
                        
                        //delay ms
                        void delay_ms(unsigned int ms)
                        {
                        while(ms--)
                        {
                        
                        unsigned char temp=121;
                        while(temp--);
                        }
                        }
                        void hien_thi()
                        {
                        
                        P2=ma[ngan];P0_0=0;delay_ms(1);P0=0xff;
                        P2=ma[tram];P0_1=0;delay_ms(1);P0=0xff;
                        P2=ma[chuc];P0_2=0;delay_ms(1);P0=0xff;
                        P2=ma[dvi];P0_3=0;delay_ms(1); P0=0xff;
                        }
                        void int_timer0_handler() interrupt 1
                        {
                        TR0 = 0; //tam dung timer0
                        TH0 = 0xFC; //nap lai gia tri
                        TL0 = 0x18;
                        P2=ma[ngan];P0_0=0;delay_ms(1);P0=0xff;
                        P2=ma[tram];P0_1=0;delay_ms(1);P0=0xff;
                        P2=ma[chuc];P0_2=0;delay_ms(1);P0=0xff;
                        P2=ma[dvi];P0_3=0;delay_ms(1); P0=0xff;
                        TR0 = 1;
                        }
                        
                        main()
                        {
                        IE = 0x82; //cho phep ngat timer 0
                        TMOD = 0x11; //mode 1 (16bits)
                        IT0 = 1; //ngat ngoai canh cho timer0 (trong thanh ghi TCON)
                        ngan=so/1000;
                        tram=(so/100)%10;
                        chuc=(so%100)/10;
                        dvi=(so%100)%10;
                        TF0 = 1; //bat dau ngat timer0
                        while(1)
                        { 
                         
                        if(!up)
                        {
                        TR0=0;
                        hien_thi();
                        so++;
                        ngan=so/1000;
                        tram=(so/100)%10;
                        chuc=(so%100)/10;
                        dvi=(so%100)%10;
                        while(!up)hien_thi();
                        TR0=1;
                        }
                        
                        }
                        
                        }
                        Attached Files
                        Last edited by tdm; 08-07-2011, 12:05. Lý do: thêm hình
                        |

                        Comment

                        Về tác giả

                        Collapse

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

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

                        Collapse

                        Đang tải...
                        X