Thông báo

Collapse
No announcement yet.

Lại một lỗi ( chưa hẳn là lỗi) của PIC16F877A

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

  • Lại một lỗi ( chưa hẳn là lỗi) của PIC16F877A

    Một bài toán sử dụng PORT B của PIC16F877A như sau.PIC16F877A cấp tải 5mA qua RB0Viết bằng CCS
    có sử dụng
    #use fast_io(B)
    và không sử dụng
    //#use fast_io(B)
    Vẫn kết quả như nhau

    cấu hình RB0 = output.
    Một đoạn ví dụ:

    set_tris_b(0x80);
    main
    {
    // các lệnh khác tại đây
    // Bây giờ cho B0 =1
    output_bit(PIN_B0,1); // Ket quả.
    // Nếu không tải ( kênh chân RB0 ra) đo được gần 5V như vậy điều khiển OK.
    // Nhưng nếu có tải trước thì RB0 gần 0V.
    // Quá tải thì không phải vì.
    // Nếu kênh chân RB0 ra và thực hiện
    output_bit(PIN_B0,1);// Sau đó nối tải vào thì RB0 = gần 5V như vậy vẫn OK. Chỉ khi có tải trước thì k được.
    // Thử lại với cách sau
    // Dùng 2 lệnh
    output_bit(PIN_B0,0);
    output_bit(PIN_B0,1);
    // Thì lại OK.
    // Khi RB0 = H
    // Lệnh
    output_bit(PIN_B0,0);// Thực hiện OK.
    }

    Vậy tại sao?
    Lỗi CCS hay lỗi PIC?
    CCS chắc khó xảy ra.
    Các nhà thiết kế và các cao thủ cởi quần áo ra nhảy xuống giải giúp.
    Cám ơn trước nhé
    Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

    Biến tần
    Máy giặt
    Lò vi sóng
    Bếp từ.
    Tủ lạnh.
    Điều hòa


  • #2
    Anh làm thế này thử xem, viết thẳng vào thanh ghi:

    PORTB=0;
    TRISB=cấu hình;
    PORTB=xxxx;

    Có thể đây là lỗi Read-Modify-Write.
    Khi thực hiện lệnh output_bit(PIN_B0,1); nhằm tránh thay đổi nội dung các chân khác. CCS sẽ đọc nội dung hiện thời của thanh ghi PORT, so đó dùng AND hoặc OR để thay đổi chân B0 rồi đưa trở lại thanh ghi PORT, lỗi là ở chỗ này.
    Khi anh đưa ra 1 do có tải nên chân này không tăng nhanh lên mức 5V được, khi đọc lại vô tình đọc sai chân đó là 0 chứ không phải 1. Kết quả xuất lại vào chân đó sẽ là 0 chứ không phải 1.
    Last edited by phamthaihoa; 20-02-2008, 22:38.

    Comment


    • #3
      Nhưng chỉ RB0 bị lỗi, thay sang RB1 thì chương trình chạy không sao cả.
      Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

      Biến tần
      Máy giặt
      Lò vi sóng
      Bếp từ.
      Tủ lạnh.
      Điều hòa

      Comment


      • #4
        Nếu là PIC18, dsPIC em luôn dùng thanh ghi LAT khi muốn ghi ra để tránh lỗi Read_Modify_Write. Em cũng gặp một lỗi hoàn toàn tương tự của anh, dùng 3 chân của PIC để điều khiển một con chọn kênh 8-1. Có một chân trong 3 chân đó luôn là 0 khi điều khiển bằng thanh ghi PORT, không hề có lỗi về phần cứng. Chỉ có thực hiện lệnh bằng thanh ghi LAT thì mới không có lỗi.

        Comment


        • #5
          debug
          947: output_bit(PIN_B0,1);
          0A30 1283 BCF 0x3, 0x5
          0A31 1406 BSF 0x6, 0
          0A32 1683 BSF 0x3, 0x5
          0A33 1006 BCF 0x6, 0
          đâu có thấy nó đọc về.
          Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

          Biến tần
          Máy giặt
          Lò vi sóng
          Bếp từ.
          Tủ lạnh.
          Điều hòa

          Comment


          • #6
            còn khi
            #use fast_io(B)
            thì

            947: output_bit(PIN_B0,1);
            09DF 1406 BSF 0x6, 0


            trước đó đã có
            704: set_tris_b(0x80); //
            082B 3080 MOVLW 0x80
            082C 0086 MOVWF 0x6
            Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

            Biến tần
            Máy giặt
            Lò vi sóng
            Bếp từ.
            Tủ lạnh.
            Điều hòa

            Comment


            • #7
              Quả chuối ở đây là chỉ có mỗi RB0 bị, chân khác không bị, các cao thủ có cao kiến hay bị trường hợp nào tương tự không nhỉ ?

              Comment


              • #8
                Nguyên văn bởi MinhHa Xem bài viết
                debug
                947: output_bit(PIN_B0,1);
                0A30 1283 BCF 0x3, 0x5
                0A31 1406 BSF 0x6, 0
                0A32 1683 BSF 0x3, 0x5
                0A33 1006 BCF 0x6, 0
                đâu có thấy nó đọc về.
                Bản thân các lệnh BCF và BSF là các lệnh có hoạt động read-modify-write. Trước khi thay đổi bit của thanh ghi, các lệnh này sẽ đọc giá trị cũ trong thanh ghi, thay đổi bit cần thiết, rồi ghi lại. Nói chung, các lệnh có thay đổi nội dung của thanh ghi I/O là những lệnh có hoạt động read-modify-write. Vì lý do này, với PIC16, tôi thường dùng một thanh ghi đệm để chứa giá trị của thanh ghi I/O (các thanh ghi PORTx), thay đổi giá trị của thanh ghi đệm khi cần và xuất ra thanh ghi PORTx.

                Cũng vì hoạt động read-modify-write, kể từ PIC18 cho đến các PIC24, dsPIC, Microchip đều có 2 thanh ghi PORTx và LATx cho mỗi I/O port. Và chúng ta chỉ cần ghi vào LATx, đọc từ PORTx.

                Về chân RB0 có phản ứng khác với chân RB1, không rõ bác đã thử với con PIC khác hay chưa? Tôi tạm cho rằng tải 5 mA của bác chỉ là LED + điện trở.

                Thân,
                Biển học mênh mông, sức người có hạn

                Comment


                • #9
                  uh. chỉ LED thôi. gần 5mA vì LED + 680 ôm.
                  Thử 10 con 877A mới tinh ( mới nhập từ thailand) đều chung 1 kết quả.
                  nhưng
                  nếu dùng lệnh kép thì k bị thế mới chuối chứ.
                  lệnh
                  output_bit(PIN_B0,0);thực hiện ngon lành.
                  nhưng
                  output_bit(PIN_B0,1) ; lại lỗi

                  nhưng để 2 lênh liền nhau
                  output_bit(PIN_B0,0);
                  output_bit(PIN_B0,1);

                  thì ra 1 OK.
                  Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                  Biến tần
                  Máy giặt
                  Lò vi sóng
                  Bếp từ.
                  Tủ lạnh.
                  Điều hòa

                  Comment


                  • #10
                    a đã thử lệnh output_high(PIN_B0) chưa?
                    hoặc anh thử lệnh xuất ra PORTB
                    Dưới đây là chương trình em viết dùng PORTB nháy 8 led, chạy ổn. Em không sử dụng các hàm có sẵn của CCS mà viết một thu viện khai báo thanh ghi để có thể dùng thẳng theo kiểu TRISB = 0x00
                    Code:
                    //////////// main.c ///////////
                    #include <16f877a.h>
                    #include <def_877a.h>
                    #device *=16 ADC=8
                    #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
                    NOLVP, NOCPD, NOWRT
                    #use delay(clock=20000000)
                    void main()
                    {
                    // Thiet lap che do cho PORTB
                    TRISB = 0x00; // Tat ca PORTB deu la cong xuat du lieu
                    PORTB = 0xFF; // Tat het cac LED
                    While(1)
                    {
                    PORTB = 0; // Cho các LED sáng
                    delay_ms(250); // Tạo thời gian trễ 250ms
                    PORTB = 0xFF;
                    delay_ms(250);
                    }
                    }
                    /// end main ////////////
                    
                    //////////// def_877a.h /////////////
                    // register definitions
                    
                    #define W 0
                    #define F 1
                    
                    // register files
                    #byte INDF          =0x00
                    #byte TMR0          =0x01
                    #byte PCL           =0x02
                    #byte STATUS        =0x03
                    #byte FSR           =0x04
                    #byte PORTA         =0x05
                    #byte PORTB         =0x06
                    #byte PORTC         =0x07
                    #byte PORTD         =0x08
                    #byte PORTE         =0x09
                    
                    #byte EEDATA        =0x10C
                    #byte EEADR         =0x10D
                    #byte EEDATH        =0x10E
                    #byte EEADRH         =0x10F
                    #byte ADCON0 	 =0x1F
                    #byte ADCON1 	 =0x9F
                    #byte ADRESH 	 =0x9F
                    #byte ADSESL 	 =0x9F
                    
                    #byte PCLATH        =0x0a
                    #byte INTCON        =0x0b
                    #byte PIR1 	=0x0c
                    #byte PIR2 	=0x0d
                    #byte PIE1 	=0x8c
                    #byte PIE2 	=0x8d
                    
                    #byte OPTION_REG    =0x81
                    #byte TRISA         =0x85
                    #byte TRISB         =0x86
                    #byte TRISC         =0x87
                    #byte TRISD         =0x88
                    #byte TRISE         =0x89
                    
                    #byte EECON1        =0x18C
                    #byte EECON2        =0x18D
                    
                    //DINH NGHIA BIT
                    #bit RA5	=0x05.5
                    #bit RA4	=0x05.4
                    #bit RA3	=0x05.3
                    #bit RA2	=0x05.2
                    #bit RA1	=0x05.1
                    #bit RA0	=0x05.0
                    
                    #bit RB7	=0x06.7
                    #bit RB6	=0x06.6
                    #bit RB5	=0x06.5
                    #bit RB4	=0x06.4
                    #bit RB3	=0x06.3
                    #bit RB2	=0x06.2
                    #bit RB1	=0x06.1
                    #bit RB0	=0x06.0
                    
                    #bit RC7	=0x07.7
                    #bit RC6	=0x07.6
                    #bit RC5	=0x07.5
                    #bit RC4	=0x07.4
                    #bit RC3	=0x07.3
                    #bit RC2	=0x07.2
                    #bit RC1	=0x07.1
                    #bit RC0	=0x07.0
                    
                    #bit RD7	=0x08.7
                    #bit RD6	=0x08.6
                    #bit RD5	=0x08.5
                    #bit RD4	=0x08.4
                    #bit RD3	=0x08.3
                    #bit RD2	=0x08.2
                    #bit RD1	=0x08.1
                    #bit RD0	=0x08.0
                    
                    #bit RE2	=0x09.2
                    #bit RE1	=0x09.1
                    #bit RE0	=0x09.0
                    
                    
                    #bit TRISA5	=0x85.5
                    #bit TRISA4	=0x85.4
                    #bit TRISA3	=0x85.3
                    #bit TRISA2	=0x85.2
                    #bit TRISA1	=0x85.1
                    #bit TRISA0	=0x85.0
                    
                    #bit TRISB7	=0x86.7
                    #bit TRISB6	=0x86.6
                    #bit TRISB5	=0x86.5
                    #bit TRISB4	=0x86.4
                    #bit TRISB3	=0x86.3
                    #bit TRISB2	=0x86.2
                    #bit TRISB1	=0x86.1
                    #bit TRISB0	=0x86.0
                    
                    #bit TRISC7	=0x87.7
                    #bit TRISC6	=0x87.6
                    #bit TRISC5	=0x87.5
                    #bit TRISC4	=0x87.4
                    #bit TRISC3	=0x87.3
                    #bit TRISC2	=0x87.2
                    #bit TRISC1	=0x87.1
                    #bit TRISC0	=0x87.0
                    
                    #bit TRISD7	=0x88.7
                    #bit TRISD6	=0x88.6
                    #bit TRISD5	=0x88.5
                    #bit TRISD4	=0x88.4
                    #bit TRISD3	=0x88.3
                    #bit TRISD2	=0x88.2
                    #bit TRISD1	=0x88.1
                    #bit TRISD0	=0x88.0
                    
                    #bit TRISE2	=0x89.2
                    #bit TRISE1	=0x89.1
                    #bit TRISE0	=0x89.0
                    
                    // INTCON Bits for C
                    #bit gie 	= 0x0b.7
                    #bit peie = 0x0b.6
                    #bit tmr0ie = 0x0b.5
                    #bit int0ie = 0x0b.4
                    #bit rbie	= 0x0b.3
                    #bit tmr0if    = 0x0b.2
                    #bit int0if    = 0x0b.1
                    #bit rbif    = 0x0b.0
                    
                    // PIR1 for C
                    #bit pspif  = 0x0c.7
                    #bit adif    = 0x0c.6
                    #bit rcif    = 0x0c.5
                    #bit txif    = 0x0c.4
                    #bit sspif    = 0x0c.3
                    #bit ccp1if    = 0x0c.2
                    #bit tmr2if    = 0x0c.1
                    #bit tmr1if    = 0x0c.0
                    
                    //PIR2 for C
                    #bit cmif    = 0x0d.6
                    #bit eeif    = 0x0d.4
                    #bit bclif  = 0x0d.3
                    #bit ccp2if    = 0x0d.0
                    
                    // PIE1 for C
                    #bit adie    = 0x8c.6
                    #bit rcie    = 0x8c.5
                    #bit txie    = 0x8c.4
                    #bit sspie    = 0x8c.3
                    #bit ccp1ie    = 0x8c.2
                    #bit tmr2ie    = 0x8c.1
                    #bit tmr1ie    = 0x8c.0
                    
                    //PIE2 for C
                    #bit osfie    = 0x8d.7
                    #bit cmie    = 0x8d.6
                    #bit eeie	= 0x8d.4
                    
                    // OPTION Bits
                    #bit not_rbpu	= 0x81.7
                    #bit intedg     = 0x81.6
                    #bit t0cs       = 0x81.5
                    #bit t0se       = 0x81.4
                    #bit psa        = 0x81.3
                    #bit ps2        = 0x81.2
                    #bit ps1        = 0x81.1
                    #bit ps0        = 0x81.0
                    
                    // EECON1 Bits
                    #bit eepgd	= 0x18c.7
                    #bit free   	= 0x18C.4
                    #bit wrerr  	= 0x18C.3
                    #bit wren    	= 0x18C.2
                    #bit wr      	= 0x18C.1
                    #bit rd      	= 0x18C.0
                    //ADCON0
                    #bit CHS0 	=0x1F.3
                    #bit CHS1 	=0x1F.4
                    #bit CHS2 	=0x1F.5
                    Ethernet-RS232, PIC Webserver, RFID Reader
                    CallerID, Cảnh báo BTS, ...
                    0988006696
                    linhnc308@gmail.com
                    http://linhnc308.blogspot.com

                    Comment


                    • #11
                      Nguyên văn bởi MinhHa Xem bài viết
                      uh. chỉ LED thôi. gần 5mA vì LED + 680 ôm.
                      Thử 10 con 877A mới tinh ( mới nhập từ thailand) đều chung 1 kết quả.
                      nhưng
                      nếu dùng lệnh kép thì k bị thế mới chuối chứ.
                      lệnh
                      output_bit(PIN_B0,0);thực hiện ngon lành.
                      nhưng
                      output_bit(PIN_B0,1) ; lại lỗi

                      nhưng để 2 lênh liền nhau
                      output_bit(PIN_B0,0);
                      output_bit(PIN_B0,1);

                      thì ra 1 OK.
                      Em đã test thử lại bằng MPASM với các lệnh điều khiển.

                      Xoá TRISB,
                      Xoá PORTB
                      Gọi làm delay
                      SET RB0 (hoạt động bình thường)

                      Thậm chí không xoá PORTB vẫn hoạt động bình thường.

                      Em lưu ý bác không biết bác có viết cái hàm while(1){} không? Nhiều người chủ quan khi test không viết cái hàm này nó có thể làm bác gặp vấn đề đấy.

                      Ngoài ra khi bác xem ở cuối chương trình chỗ Debug, nó có cái lệnh SLEEP ở cuối chương trình của bác không? Khi bỏ cái while vào thì nó khoá bằng SLEEP ở dòng lệnh cuối để tránh bị nhảy ra khỏi đoạn viết code này.

                      Em test trực tiếp trên PICDEM2 Plus, cho nên về mặt mạch nguyên lý thì chắc là em không bị sai, về code MPASM em viết thì chắc không bị sai. Em thử với một kit bộ 3 con PIC6F877A em có ở đây (hàng sample). Thử trực tiếp với LED, nó có sẵn 4 con LED trên PICDEM2 Plus RB0 - RB3.

                      Bác thử kiểm tra lại hai điểm em nói. Nếu không có thì bác thử thêm cái #asm SLEEP #endasm vào cuối chương trình xem nó có chạy không.

                      Chúc vui
                      Falleaf
                      Công ty TNHH Thương mại và Giao nhận R&P
                      58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
                      mail@falleaf.net - VP: (04) 36408561 - (08) 38119870

                      Comment


                      • #12
                        vấn đề là nếu test thử thì nó chạy OK. Nhưng một số trường hợp lại không OK. Thế mới củ chuối chứ.
                        Mình nói ban đầu rồi.
                        Nếu không tải ( tải chỉ dưới 5mA) nó vẫn OK. Chỉ khi có thêm tải 5mA mới bị.
                        Tức là bật lên 1.
                        Đo chân ra vẫn là 0.
                        Nhưng cắt tải ra là nó lại lên 1 ( chỉ cắt tải chứ không làm gì cả).
                        Sau đó nối tải tới 30mA vào thì nó vẫn là mức 1.
                        Vậy nó vẫn chạy đúng.
                        Chỉ chuối là.
                        Có tải trước thì một số trường hợp không kéo lên 1 được. Mặc dù tải rất nhỏ.
                        Chứ lập trình sai ai lại đổ lỗi cho PIC tội nghiệp thằng 877A quá.
                        Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                        Biến tần
                        Máy giặt
                        Lò vi sóng
                        Bếp từ.
                        Tủ lạnh.
                        Điều hòa

                        Comment


                        • #13
                          Anh em ghi nhận là đã BUG được vài lỗi của PIC nhé.
                          Lần trước hỏi về ADC của 87J10, Watchdog 877A và nay là lỗi IO này nhé. Để sau biết đâu lại được M trả tiền thì khỏi đánh nhau nhé.
                          Mình vẫn DEMO lại được các trường hợp trên.
                          Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                          Biến tần
                          Máy giặt
                          Lò vi sóng
                          Bếp từ.
                          Tủ lạnh.
                          Điều hòa

                          Comment


                          • #14
                            Sao không cao thủ nào giúp vậy?
                            Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                            Biến tần
                            Máy giặt
                            Lò vi sóng
                            Bếp từ.
                            Tủ lạnh.
                            Điều hòa

                            Comment


                            • #15
                              Nguyên văn bởi MinhHa Xem bài viết
                              Sao không cao thủ nào giúp vậy?
                              Bác có thể gửi mấy cái file .hex có các đoạn code mà bác đã thử không? Tôi cũng muốn giúp bác, nhưng không hề dùng CCS C. Viết bằng hợp ngữ thì không hề gặp chuyện này. Bác nhớ chú thích file .hex nào ứng với đoạn code nào của bác nhé.

                              Thân,
                              Biển học mênh mông, sức người có hạn

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X