Thông báo

Collapse
No announcement yet.

AVR cho người mới bắt đầu

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Chào các bạn.Mình cũng mớii học avr. Đang gặp khó khăn về timer, các bác có thể giúp em về cái này được chứ?
    Mình từng bị bầm dập về timer nhiều nên bạn cứ trao đổi có thể mình giúp được.

    Đầu tiên ban nên nhớ đặc tính cơ bản của 3 timer như sau:
    timer0 8bit, đếm ngoài
    timer1 16bit, đếm ngoài, PWM
    timer2 8bit, PWM
    Cài đặt cho các timer vào thanh ghi TCCR0/ 1(A/B)/ 2

    timer0/1 vừa là timer vừa là bộ đếm, nếu là bộ đếm thì lấy xung từ chân T0/1. Nếu là timer thì lấy tần số dao động, qua một bộ chia tần (prescaler). Để dễ chọn mức chia tần phù hợp, tặng bạn một file exel có gì dễ tra cứu, chỉ cần thay đổi mục "freq" thì các tần số qua prescaler ra kết quả tự động. Nói thêm một tí là mình học được cách làm này ở một tay chơi dân kế toán, rất hiệu quả mà nhẹ nhàng.
    Cài đặt cho 1 timer tương đối phức tạp, nếu làm quen bạn nên chọn chế độ normal, đơn giản thì 5 bit đầu của TCCR0/1A/2 để 0; 3 bit còn lại chọn chia tần hoặc ngõ vào

    Cứ mỗi lần có xung, hoặc prescaler xuất 1 xung thì thanh ghi TCNT0/1/2 tăng lên 1. Đến khi tràn thì các cờ tràn TOV0/1/2 trong thanh ghi TIFR set từ 0 lên 1. Điều khá củ chuối ở đây là muốn xóa cờ tràn thì bạn phải chép đè bit 1 lên nó!!!
    Nguyên văn datasheet của ATMega8, trong phần nói về timer1, thanh ghi TIFR:
    "...In normal and CTC modes, the TOV1 Flag is set when the timer overflows...
    ... TOV1 can be cleared by writing a logic one to its bit location"

    Hơi rắc rối vậy nếu bạn muốn xóa cờ thì phải kiểm tra xem nó đang ở mức nào, nếu là 1 thì chép đè 1 lên còn nếu là 0 thì cứ để nguyên đấy.
    Cách dùng 1 timer hiệu quả là dùng ngắt hoặc giải thuật sau:
    ...
    kiểm tra cờ tràn;
    khởi động timer;
    while(timer chưa tràn)
    {
    thực hiện;
    }
    ...
    Attached Files
    Last edited by Kilodeth; 24-07-2008, 00:29. Lý do: /file hỏng, upload lại
    Đẹp từng kilomét

    Comment


    • file mình vừa upload trên cho phép tính độ trì hoãn tối đa 1 timer có thể. Giả sử bạn cho chạy thạch anh 8M, muốn delay 5 giây thì chỉ còn cách dùng timer1-16 bit, prescale /1024 (CS12..0 =101)
      cũng theo file trên, tần số ra của bộ chia có chu kỳ 0.128 ms. vậy 5s tốn 5000/.128=39062 chu kỳ
      vậy có thể cài đặt


      #define CLEAR_TIM2_OVFL_FLAG if (TIFR & 0x40) TIFR|=0x40
      #define CLEAR_TIM1_OVFL_FLAG if (TIFR & 0x04) TIFR|=0x04
      #define CLEAR_TIM0_OVFL_FLAG if (TIFR & 0x01) TIFR|=0x01
      //định nghĩa cách xóa các cờ tràn cho khỏi cực thân

      ...
      TCNT1= -39062; //đặt điểm đầu
      TCCR1B=0x05; //cho chạy normal mode với bộ chia tần 1024
      CLEAR_TIM1_OVFL_FLAG;
      while (!(TIFR & 0x04)) //cờ vẫn chưa tràn
      {
      //lặp lại việc gì đó hoặc không làm gì cả
      ...
      };
      TIFR|=0x04; //xóa cờ cho chắc
      TCCR1B=0x00;//ngưng chạy timer
      ...


      (*) codevision cho phép viết TCNT1 như một biến int thay vì phải viết TCNT1H và TCNT1L
      (**) các cờ so sánh cùng cách xóa tương tự
      Đẹp từng kilomét

      Comment


      • chào các bác e mới học về avr, e đang sử dụng mấy con mega32 đang bị lỗi ở portc.6+7 đọc trang trước mấy bác bảo bỏ JTAGEN. e chưa hiểu JTAGEN là gì.bác nào giải thích giùm e với? cách bỏ nó thế nào?
        thanks!

        Comment


        • Nguyên văn bởi dhebip Xem bài viết
          chào các bác e mới học về avr, e đang sử dụng mấy con mega32 đang bị lỗi ở portc.6+7 đọc trang trước mấy bác bảo bỏ JTAGEN. e chưa hiểu JTAGEN là gì.bác nào giải thích giùm e với? cách bỏ nó thế nào?
          thanks!
          JTAGEN được sử dụng trong chế độ Debug.
          Khi nạp chọn Fuse để Enable/Disable JTAGEN Fuse.

          Nếu sử dụng SPI Flash Programmer 3.7 thì tham khảo lại:
          http://dientuvietnam.net/forums/show...?t=139&page=17
          post #167
          More friends more foods

          Comment


          • mình dùng atmega 16 để chạy 16 led.Nối 16 led vào 2 port b và d,mình muốn cho led sáng từ 1 đến 16 và ngược lại nhưng ko biết lập trình c.có ai giúp mình được không,minh dùng phần mềm CODEVISION .mong được hồi âm sớm.
            |

            Comment


            • Bác nào có 1 chương trình chạy được = C , có lập trình ngắt (nếu có thêm định thời thì càng tốt) thì post cho em nhé!Tại mấy quyển sách em đọc chỉ có ví dụ từng đoạn 1 thôi!
              Không có một trương trình đầy đủ nên 0 biết ghép các đoạn lại thế nào! Mà ngắt thì phải có cách dánh dấu chương trình phục vụ ngắt nhưng sách của em chỉ nói vị trí vector ngắt chứ 0 hướng dẫn phải khai báo thế nào để khi đạt ĐK ngắt thì nhảy đến chương trình con!

              Comment


              • Mình sử dụng chế độ CTC tạo ra một xung ở chân OC0. Sau đó dùng ngắt để thay đổi giá trị OCR0 nhưng không thấy sự thay đổi ở xung ra. Mình mô phỏng bang proteus. Ai làm rồi giúp mình với.

                Comment


                • xin hỏi bác kilodeht tí nha
                  nếu mình khai báo biến eeprom thi chi khi nao biến này thay đổi avr mới ghi vào eeprom à

                  Comment


                  • ví dụ mình làm bộ đếm muốn lưu giá trị đếm khi tắt nguồn thì có thể dùng cách trên được không

                    Comment


                    • ví dụ mình làm bộ đếm muốn lưu giá trị đếm khi tắt nguồn thì có thể dùng cách trên được không
                      Tùy xung nhịp đếm, theo AN "AVR100: Accessing the EEPROM" thì
                      - đọc ngẫu nhiên (random read) tốn 11 chu kỳ máy,
                      - ghi ngẫu nhiên - 15
                      - đọc tuần tự - 17
                      - ghi tuần tự - 19
                      Theo cách trên thì phải dùng ghi ngẫu nhiên rồi, vậy giá trị trên EEPROM so với con số thực tế lúc tắt nguồn sai số khoảng 15 chu kỳ. ví dụ ghi xong giá trị timer là 10 thì thực tế lúc đó đã là 25 rồi
                      Nếu timer qua chia tần thì có thể chính xác, tuy nhiên nếu mất nguồn ngay trong quá trình ghi thì không biết giá trị có chính xác không, phải thử mới biết
                      Đẹp từng kilomét

                      Comment


                      • Nguyên văn bởi Kilodeth Xem bài viết
                        Tùy xung nhịp đếm, theo AN "AVR100: Accessing the EEPROM" thì
                        - đọc ngẫu nhiên (random read) tốn 11 chu kỳ máy,
                        - ghi ngẫu nhiên - 15
                        - đọc tuần tự - 17
                        - ghi tuần tự - 19
                        Theo cách trên thì phải dùng ghi ngẫu nhiên rồi, vậy giá trị trên EEPROM so với con số thực tế lúc tắt nguồn sai số khoảng 15 chu kỳ. ví dụ ghi xong giá trị timer là 10 thì thực tế lúc đó đã là 25 rồi
                        Nếu timer qua chia tần thì có thể chính xác, tuy nhiên nếu mất nguồn ngay trong quá trình ghi thì không biết giá trị có chính xác không, phải thử mới biết
                        Thông thường với các thiết bị muốn lưu giá trị khi mất điện người ta thường dùng thêm một tụ điện lớn một chút nuôi cho con VĐK. Và sử dụng so sánh tín hiệu tương tự (AIN0 và AIN1 chẳng hạn) để phân biệt đã mất nguồn hẳn chưa. Nếu mất rồi thì ghi dữ liệu vào eeprom, khi đó phần thiết bị khác đã ngưng hoạt động do mất điện nên giá trị chốt lại khá chính xác.
                        n
                        ĐT: 0986 492 489

                        Tham khảo:

                        Comment


                        • đúng như bạn minhhieu nói mình đã dùng một tu lớn để nuôi avr.dùng một ngắt ngoài để báo mất nguồn.xung đếm của minh cũng la xung ngoài tần số thấp nên không sợ sai .vấn đề của mình là dùng cách truy nhập eeprom nào cho hợp lí.trước minh dùng truy nhập trực tiếp gio minh ko biết chuyển qua cách khai báo biến eeprom co hợp lí ko

                          Comment


                          • Các bác ơi ...em đang viết băng ASM , sau này chuyển qua C có khó không...em thấy viết bằng thằng C cũng nhàn ghê nhỉ?

                            Comment


                            • Nguyên văn bởi thanhtung86 Xem bài viết
                              đúng như bạn minhhieu nói mình đã dùng một tu lớn để nuôi avr.dùng một ngắt ngoài để báo mất nguồn.xung đếm của minh cũng la xung ngoài tần số thấp nên không sợ sai .vấn đề của mình là dùng cách truy nhập eeprom nào cho hợp lí.trước minh dùng truy nhập trực tiếp gio minh ko biết chuyển qua cách khai báo biến eeprom co hợp lí ko
                              Mình đã test thử kiểu khai báo biến trực tiếp vào eeprom thấy khá là thú vị.
                              Cách sử dụng như sau:

                              //Khai báo biến lưu trong eeprom
                              eeprom char i0,i1,i2;
                              eeprom char i3,i4,i5;


                              //cách ghi vào một giá trị

                              i0 = 10; //ghi số 10 vào địa chỉ 0x0000 trong eeprom
                              i1 = 1; //ghi số 1 vào địa chỉ 0x0001
                              i2 = 2; //ghi số 2 vào địa chỉ 0x0002
                              i3 = 3; //ghi số 2 vào địa chỉ 0x0003
                              i4 = 4; //ghi số 2 vào địa chỉ 0x0004
                              i5 = 5; //ghi số 2 vào địa chỉ 0x0005

                              //cách đọc một giá trị lưu trong eeprom

                              char temp;

                              temp = i0; // temp lúc này có giá trị = 10
                              temp = i3; // temp có giá trị = 3 đọc từ địa chỉ 0x0003 của eeprom

                              //================================================== ===

                              Chú ý:
                              + Khi khai báo biến eeprom, CodevisionAVR sẽ tự động gán địa chỉ tăng dần bắt đầu từ 0x0000 cho biến khai báo đầu tiên nhất, rồi đến các biến khai báo kế tiếp.
                              + Khi khai báo biến eeprom các bạn lưu ý phải sử dụng biến đã khai báo ít nhất một lần tại bất kỳ vị trí nào trong chương trình cũng được. Nếu ví dụ khai báo biến i0,i1...,i5 mà chỉ sử dụng i1,i2,...,i5 (i0 có khai báo mà không sử dụng) lúc này giá trị đọc được của i1,i2,...,i5 bị sai do địa chỉ được thay đổi, lúc này địa chỉ của i1 không còn là 0x0001 nữa mà bị dồn về địa chỉ đầu tiên.
                              + Khi khai báo biến eeprom cần khai báo thứ tự từ đầu chương trình xuống để địa chỉ tự động tăng lên. Khi sửa chương trình hoặc khai báo thêm biến nên cho xuống vị trí là biến được khai báo cuối cùng nhất của biến eeprom. Như vậy sẽ tránh được việc lẫn lộn gây sai địa chỉ của biến trong eeprom.
                              n
                              ĐT: 0986 492 489

                              Tham khảo:

                              Comment


                              • Nguyên văn bởi HiMas88 Xem bài viết
                                Các bác ơi ...em đang viết băng ASM , sau này chuyển qua C có khó không...em thấy viết bằng thằng C cũng nhàn ghê nhỉ?
                                Học C rất dễ, dễ hơn cả ASM. Vì C là ngôn ngữ cấp cao viết theo ngôn ngữ con người không như ngôn ngữ gần máy như ASM. Để viết chương trình dài mà dễ quản lý thì nên viết bằng C. Ưu điểm của ASM hơn C ở chỗ tạo ra mã máy ít hơn khi biên dịch làm chương trình tối ưu hơn dẫn đến chạy nhanh hơn. Vì thế bạn đã biết ASM rồi chuyển qua C đồng thời trong code C bạn nhúng cả code ASM vào thì tuyệt vời đấy.
                                n
                                ĐT: 0986 492 489

                                Tham khảo:

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X