Latest Post

10 4.104 8051 9 Acquy adc pic All datasheet ALTIUM Altium Designer AM-FM Arduino ARM ARM là gì Ấn Tượng Bản tin công nghệ Bản tin Thiết Bị Số Barobo bất động sản biến Binary Bit board lpc2378 Bộ chuyển đổi ADC Bộ Đếm Bộ điều khiển cửa cuốn Bộ Định Thời Buy Khóa Số Điện Tử Buy Mạch đếm sản phẩm Buy Mạch giao thông Buy Mạch nạp Buy Matrix Byte C cho AVR các hàm vào ra các loại lõi arm các mạch DAC cơ bản các ngắt trong pic Cách đọc điện trở Cách Đọc Giá Trị Điện Trở Cách đọc giá trị tụ điện Cách hàn linh kiện dán cách làm mạch khóa số cách tạo linh kiện dán cad/cam Cài Đặt cài đặt proteus 8 cảm biến Cấu Kiện Logic Khả Trình cấu tạo cấu trúc arm cấu trúc lệnh CCS Chân chân Transistor Chip Khả Trình chuyển đổi Chuyển đổi số tương tự Chuyển Đổi Tương Tự/Số - ADC Chuyển động số chương trình City Clip Điện Tử Code 8051 - ASM Code 8051 - C Code 8051-C code ASM code ASM mẫu 8086 Code AVR - C code C Code Lập Trình Code led sao băng code maupic code mẫu 8051 Code Mẫu 8086 Code Mẫu cho ARM - LPC1343 code mẫu pic Code PIC - C codemaupic Counter Cổng Vào Ra Cơ Bản Cuộn Cảm Cửa cuốn DA DAC Debug Decimal Delay8051 Dev-C++ Diode DIY Dò đường Do It Yourself doanh nghiệp Download DTMF Mobile đảo chiều động cơ Điện Trở Điện Tử Điện Tử Cơ Bản điều chế độ rộng xung điều chế xung PWM điều khiển bằng điện thoại Điều khiển cửa cuốn Điều khiển cửa cuốn bằng điện thoại điều khiển động cơ đo điện áp đo nhiệt độ đo nhiệt độ hiển thị lên lcd trên 8051 Đo Nhiệt Độ LM35 + LCD Đo Nhiệt Độ LM35 + Led 7 thanh đọc màu điện trở đồ chơi động cơ chân không Động cơ nhiên liệu Động cơ robo đồng hồ thời gian thực Ebook Đại Học ebook điện tử Ebook đồ án Ebook Tin Học Encoder Encoder là gì Full Giải Thuật Giải thuật PID Giáo Dục giao tiếp i2c pic 16f877a giao tiếp i2c pic16f877a với ic ds1307 giao tiếp máy tính qua rs232 Giao Tiếp Máy Tính VB6 giao tiếp rs232 giao tiếp spi giữa 2 pic giao tiếp spi trong pic Giáo Trình Điện Tử Giới thiệu 8051 Giới thiệu cơ bản GPIO Graphic Design hàm Hàn linh kiện dán Hexadecimal Hệ Hexa Hệ Nhị Phân Hệ Thập Lục Phân Hệ Thập Phân hiển thị lên lcd 16x2 Hoạt Động Học Học 8051 qua các ví dụ đơn giản Học ALtium Designer học AVR Học Corel Draw X3 Học Eagle HỌC LẬP TRÌNH 16F877A Học Lập Trình 8051 Học Lập Trình C Học Orcad Học Protues hoc-lam-robot-do-duong-qua-video Hồng ngoại hướng dẫn hướng dẫn Altium Designer hướng dẫn đo đồng hồ VOM hướng dẫn keil - C lập trình 8051 hướng dẫn làm led sao băng hướng dẫn làm led trái tim hướng dẫn lập trình ARM Hướng Dẫn Lập Trình ARM - LPC1343 hướng dẫn lập trình ARM-LPC2378 hướng dẫn lập trình CCS hướng dẫn lập trình PIC Hướng Dẫn Led Trái Tim hướng dẫn module sim548c hướng dẫn sử dụng keil hướng dẫn sử dụng proteus 8 Hyper Terminal hercules 3.2.4 I/O IC 555 IC 7447 IC 74HC151 IC 74HC154 IC 74HC245 IC 74HC595 IC 74LS138 IC DS1307 IC đồng hồ thời gian thực IC LM324 IC LM342 IC LM7805 IC số IC số opamp LM324 IC Thông Dụng IC555 Interrupt Keil 4 Full keil arm Keil C Keil uVision3 kế toán kiểm toán khái niệm Khái Niệm Cơ Bản Kho Vật Liệu khóa điện tử khóa số dùng 8051 khóa số dùng 89s52 Khóa Số Điện Tử khuếch đại kiểm tra Kinh doanh maketing kinh tế quản lí Kỹ Thuật Kỹ Thuật Vi Xử Lý làm mạch điện lý thú Làm quen AVR Lap Trinh Dieu Khien Robot Lập Trình lập trình 8051 Lập Trình AVR Lập Trình C lập trình c++ Lập Trình Led Quảng Cáo Lập Trình Nhúng Lập trình pic Lập trình Robot Lập Trình Vi Điều Khiển Lập Trình Với AVR Studio LCD 16x2 Lcd16x2 Led Clock Led Quay led sao băng led trai tim Led Trái Tim Lịch sử ra đời Linh Kiện Cơ Bản linh kiện điện tử Loa LPC 2378 LSB lý thú Mã AVR - C Mạch 7seg Mạch Amply.Mạch Loa Mạch Autorobo Mạch bảo vệ Mạch Cảm Biến mạch cảm ứng sờ tay Mạch Cầu H Mạch cube Mạch Đếm Sản Phẩm Mạch điện cơ bản Mạch điện hay Mạch Điện Ứng Dụng Mạch Điều khiển động cơ Mạch Động Cơ Mạch đồng hồ Mạch đồng hồ 4 led Mạch giao thông Mạch IC số Mạch in mạch khóa số mạch khuếch đại thuật toán mạch led chúc mừng năm mới mạch led đẹp Mạch Led đơn Mạch Led Quảng Cáo mach led trai tim mạch led trái tim Mạch Led Vumeter mạch lý thú Mạch Ma trận Phím Mạch Matrix Mạch nạp Mạch nguồn Mạch Nút Bấm mạch sóng rf mạch tăng áp Mạch thu phát Mạch tổ hợp MSI Mạch trái tim Mạch Vi điều khiển Microbicho module module GSM/GPS Module Sim548 Module Sim548 giao tiếp với vi điều khiển PIC Module Sim548C Mosfet Motor Mô Phỏng Phần Cứng Mô Tả Phần Cứng MSB mua led sao băng News Ngắt Ngắt Trong LPC23xx ngân hàng Ngôn Ngữ Ngôn Ngữ C Ngôn Ngữ Tự Học Lập Trình C Ngôn Ngữ VHDL Nguyên Lý nguyên lý ic 555 Nguyên Tắc nháy led Nhập môn C Nhỏ Gọn Nibble opamp People Phần Mềm phần mềm altium Designer Phần mềm điện tử Phần Mềm Điện Tử Phần Mềm Điện Tử Hay Phần Mềm Hay Phần Mềm Led Quảng Cáo phần mềm proteus 8 Phần mềm vi tính Phần Mền Phương pháp hàn linh kiện dán PIC pic16f877a Print Design Proteus Proteus 7.8 SP2 FULL PWM quà tặng bạn gái quà tặng độc đáo quản trị doanh nghiệp quản trị kinh doanh quét led 7 đoạn Relay robocon Robot ROBOT DÒ ĐƯỜNG rút gọn mạch logic tổ hợp Sach Dien Tu Sản Phẩm Thú Vị Sản Phẩm Thương Mại Sáng tạo Short Smart Home SMD sơ đồ nguyên lý spi Sports Sử Dụng Sử Dụng Đồng Hồ sử dụng đồng hồ VOM sử dụng ngắt trong pic sự khác nhau Sức mạnh số Tải tài chính tài chính doanh nghiệp tài chính ngân hàng Tài Khoản Chia Sẻ Tài Liệu Tài Liệu 8051 tài liệu avr Tài liệu Điện Tử Tài Liệu Pic Tài liệu robocon tài liệu về ngân hàng Tài Liệu Vi Điều Khiển tailieuvn Tạo cổng Com ảo Tạo cổng nối tiếp ảo tạo dự án trong keil arm Tạo Project trong Vi Xử Lý ARM tạo thư viện altium designer tạo xung vuông Tạp chí Tạp Chí Hay tăng áp Tập lệnh AT Team Support TEAMPLATE PROTEUS Test thị trường tài chính Thiết Bị Thú Vị Thiết kế robot Thiết lập Fuse Bits Thiết Lập Pin Thuật Toán Thuật Toán Điều Khiển PID Thuật Toán Quine MCCluskey Thư viện Protues Thực Hành Thyristor Timer Timer/Counter Tin Học Chia Sẻ Tổ Chức Bộ Nhớ tổng quan về proteus 8 Transistor Tranzito Tranzitor Trao đổi học tập Travel Trình Biên Dịch Trình Dịch Trong Suốt Truyền Thông Nối Tiếp Không Đồng Bộ- UART truyền thông nối tiếp RS232 Tụ điện TUT - 8051 - ASM TUT - 8051 - KeilC tự hành Tự Học C Tự Học Lập Trình C Tý hon UART Update USB Ứng Dụng Led Quảng Cáo ứng dụng mạch khuếch đại thuật toán vẽ mạch in vẽ mạch nguyên lý VHDL Vi Điều Khiển Vi điều khiển - Ứng dụng vi điều khiển PIC Vi mạch số Vi Xử Lý Vi Xử Lý 8051 Vi Xử Lý 8086 Vi Xử Lý ARM Vi Xử Lý PIC Video Video Mach Điện Virtual Serial Port Driver VOM vxl Web Design xác định góc quay động cơ xử lý chuỗi

 AVR có sẵn một số mạch điện và các thiết bị hỗ trợ bên trong, việc “điều khiển” các mạch điện này được thực hiện thông qua các Fuse bits. Ví dụ bên trong các chip AVR có bộ tạo dao động cho chip, nếu muốn sử dụng hoặc vô hiệu hóa bộ tạo dao động này chúng ta sẽ set các Fuse bits điều khiển nguồn xung clock(cụ thể ở phần sau). Như thế, Fuse bits cũng giống như các “cầu chì” hay các “công  tắc cứng”  nối AVR với các mạch điện hỗ trợ. Vì là các “công tắc cứng” nên chúng phải được set riêng biệt, không set được bằng lệnh "mềm". 
      Mỗi loại AVR có số lượng mạch điện hỗ trợ khác nhau và vì thế số lượng Fuse bits sẽ khác nhau. Vị trí các Fuse bits cũng khác nhau trên mỗi dòng chip tuy nhiên tên gọi thì như nhau. THIETKEMACHDIENTU.NET sẽ dùng chip ATmega32 làm minh họa. Chip ATmega32 có 16 Fuse bits được bố trí trong 2 byte gọi là “Fuse High Byte” và “Fuse Low Byte”. Vị trí các Fuse bits không quan trọng (vì chúng ta dùng phần mềm hỗ trợ set từng Fuse bit) nhưng tên gọi và chức năng thì cần khảo sát. Bảng 1 tóm tắt các bits trong Fuse High Byte và bảng 2 tóm tắt các bits trong Fuse Low Byte.
Bảng 1. Fuse High Byte 
  

Bảng 2. Fuse Low Byte 

     Đa số các chương trình nạp chip đều hỗ trợ nạp Fuse bits. Các Fuse được nạp độc lập đối với file chương trình. Các phần mềm nạp như PonyProg, phần mềm nạp trong CodevisionAVR, Bascom, ICCAVR…hỗ trợ set từng Fuse bit một trong khi một số chương trình như avrdude chỉ hỗ trợ nạp các byte Fuse, nếu muốn sử dụng các chương trình nạp này để nạp Fuse bạn cần tính toán giá trị 2 byte Fuse trước. Một chú ý rất quan trọng là đối với các Fuse bits, gán giá trị  0cho 1 Fuse bit đồng nghĩa với Fuse bit đó được lập trình (programmed), trong khi 1 nghĩa là không được lập trình (unprogrammed).
     THIETKEMACHDIENTU.NET sẽ sử dụng phần mềm PonyProg để làm minh họa nạp Fuse bits cho chip ATmega32. Trước khi nạp Fuse bits bạn cần chọn device và loại mạch nạp trong PonyProg (xem lại bài Mạch nạp). Để nạp Fuse bits bạn hãy chọn menu “Command/Security and Configuration Bits…” hoặc nhấn “Ctrl+S” (mạch nạp phải được nối sẵn với máy tính và mạch AVR). Nhấn nút “Read” để đọc các cấu hình Fuse bits trên chip của bạn, nếu đây là lần đầu tiên chip ATmega32 của bạn được nạp Fuse bits thì bạn sẽ thu được kết quả cấu hình các Fuse bits như trong hình 1. 

Hình 1. Cấu hình Fuse bits mặc định trên chip ATmega32. 
       Chúng ta sẽ lần lượt khảo sát các Fuse bit theo nhóm chức năng của chúng. 
      1. JTAGEN (JTAG Enable): trên AVR có tích hợp sẵn bộ JTAG, đó là một module giao tiếp với phần cứng của chip. Nhìn chung, JTAG thường được dùng để kiểm tra hoạt động của chip. Trên AVR, JTAG có thể được dùng để nạp chương trình nhưng phổ biến hơn là dùng để debug lỗi chương trình (gỡ rối chương trình). Module JTAG làm việc thông qua 4 chân TCK, TMS, TDO và TDI, trên chip ATmega32 4 chân lần lần lượt là PC2, PC3, PC4 và PC5. Theo mặc định JTAG được kích hoạt, bit JTAGEN=0 (programmed) như trong hình  1. Vì thế với các chip ATmega32 mới mua về, các chân PC2:5 trên PORTC có thể không sử dụng để xuất nhập thông thường được. Nếu bạn không muốn sử dụng chức năng Debug trực tiếp trên chip thì hãy uncheck bit JTAGEN(uncheck tương đương unprogrammed, tương đương JTAGEN=1) để dùng các chân JTAG như các chân xuất nhập thông thường. 
      2. OCDEN (On Chip Debug Enable): như đã trình bày ở trên, AVR cho phép chúng ta gỡ rối chương trình trực tiếp trên chip thông qua module JTAG. Trong khi bit JTAGEN cho phép kích hoạt JTAG thì bit OCDEN cho phép thực hiện Debug trên chip (Nghĩa là cho dù đã kích hoạt JTAG bạn chưa thể dùng chức năng debug nếu chưa kích hoạt OCDEN). Nếu bạn có một mạch Debug cho AVR như mạch JTAG ICE của Atmel (xem bài Debug với JTAG ICE) và bạn muốn debug chương trình thì hãy set bit OCDEN bằng 0 (check vào ô OCDEN). Bạn cần nhớ rằng, khi lập trình cho bit OCDEN thì AVR sẽ hoạt động trong mode Debug, trong mode này chip  sẽ ở trong trạng thái “ngủ” (Sleep mode), bạn chỉ có thể thực hiện Debug mà không thể chạy chương trình thật. Theo mặc định, OCDEN không được lập trình và chế độ Debug được vô hiệu hóa. Lời khuyên là bạn nên để bit này unprogrammed trước khi đưa chip vào sử dụng. (đừng đụng vào bit này nếu bạn không có ý định Debug trên chip).
     3. BODEN (Brown-Out Detection Enable) và BODLEVEL(BOD Level): AVR có sẵn một mạch điện Brown-Out Detection, hiểu nôm na là mạch phát hiện sụt điện áp nguồn. Nếu fuse BODEN được lập trình  thì mạch BOD được kích hoạt, khi đó fuse bit BODLEVEL chọn mức điện áp của BOD (mức điện áp dùng so sánh sụt nguồn). Nếu BODLEVEL=1 (unprogrammed) thì mức điện áp BOD mặc định là 2.7V, ngược lại nếu BODLEVEL được lập trình thì mức điện áp BOD là 4.0V. Khi mạch BOD được sử dụng, nếu điện áp VCC giảm xuống thấp hơn mức điện áp BOD thì 1 Reset BOD xảy ra. Nếu không thật sự cần thiết hãy để các bit này không được lập trình như mặc định. Hình 2 mô tả một sự kiện BOD trên AVR.    


Hình 2. Sự kiện BOD trên AVR. 
      4. EESAVE (EEPROM Erase SAVE): nếu bit EESAVE được lập trình (bằng 0), thì  bộ nhớ EEPROM sẽ không bị xóa khi xóa chip, ngược lại EESAVE =1 (unprogrammed) thì EEPROM sẽ bị xóa theo chip.
      5. BOOT LOADER: đây là một tính năng rất hay trên các chip AVR mới (chú ý không phải dòng AVR nào cũng có Boot Loader), Boot Loader là phần bộ nhớ chương trình được kích hoạt đầu tiên khi khởi động chip. Boot Loader trên các chip AVR được bố trí phía dưới của bộ nhớ chương trình (xem lại bài 2, cấu trúc AVR). Boot Loader thường được sử dụng để ghi hoặc đọc nội dung bộ nhớ chương trình, vì thế ứng dụng phổ biến nhất của nó là update chương trình cho chip một một cách nhanh chóng mà không cần mạch nạp. Cơ chế như sau: 
 -Trước hết chúng ta cần có 1 chương trình Boot Loader được nạp sẵn trong phần bộ nhớ Boot Loader (phía dưới bộ nhớ chương trình). Chương trình này có khả năng giao tiếp với máy tính (thông qua UART chẳng hạn) và đọc, ghi bộ nhớ chương trình của chip.
 -Khi cần update chương trình mới cho AVR, trên máy tính có 1 chương trình giao tiếp với Boot Loader, kết nối AVR với máy tính, chương trình trên máy tính sẽ gởi nội dung cần update cho AVR, chương trình Boot Loader sẽ đọc nội dung này và ghi vào bộ nhớ chương trình của AVR. Bằng cách này chúng ta đã “nạp” chương trình cho AVR mà không cần dùng mạch nạp.
      Nạp chương trình bằng Boot Loader cho phép khách hàng của bạn tự cập nhật các chức năng mới mà không cần trao chip cho bạn. Sử dụng hay không sử dụng Boot Loader sẽ được xác lập thông qua các Fuse bits BOOTRST, BOOTSZ1 và BOOTSZ0. 
-BOOTRST (Select Reset Vector) : Nếu Fuse bit BOOTRST không được lập trình (bằng 1) thì khi vừa khởi động chip, con trỏ chương trình sẽ nhảy đến vị trí đầu tiên trong chương trình (0x0000) để lần lượt thực thi phần chương trình như thông thường. Nếu BOOTRST được lập trình (bằng 0) thì vị trí Reset là địa chỉ đầu của phần Boot Loader, không phải địa chỉ 0x0000 như thường lệ. Khi đó phần chương trình trong Boot Loader sẽ được thực thi thay cho chương trình chính phía trên (xem hình 3). 

Hình 3. Ảnh hưởng của Fuse bit BOOTRST.
-BOOTSZ1  BOOTSZ0 (Select Boot Size): kích thước phần bộ nhớ dành cho Boot Loader không cố định, nếu Boot Loader không được kích hoạt (fuse BOOTRST=1) thì toàn bộ bộ nhớ chương trình dành cho chương trình chính. Khi Boot Loader được kích hoạt, 2 Fuse bits BOOTSZ1 và BOOTSZ0 sẽ quyết định kích thước Boot Loader. Bảng 3 tóm tắt các kích thước của phần Boot Loader phụ thuộc vào 2 bit BOOTSZ1:0. Chú ý là kích thước tính theo INSTRUCTION WORD, với AVR 1 INSTRUCTION WORD = 2 bytes. Phải nhắc lại đối với Fuse bits, giá trị 1 nghĩa là không được lập trình (không check trong PonyProg). Nếu bit BOOTRST không được lập trình thì 2 bit BOOTSZ không có tác dụng.
Bảng 3. Kích thước Boot Loader.

      Trong các ứng dụng lập trình thông thường, Boot Loader không được quan tâm, vì thế tối khuyên bạn nên để các Fuse bit BOOTRST, BOOTSZ1:0 như mặc định, khi nào cần sử dụng THIETKEMACHDIENTU.NET sẽ nói rõ (xem bài Debug với mạch JTAG ICE).
      6. Chọn Nguồn Xung giữ nhịp và thời gian khởi động (start-up times): Đây là phần rất được quan tâm khi set Fuse bits. Có đến 7 Fuse bits tham gia vào việc này đó là 4 bits CKSEL3:0, 2 bis SUT1:0 và bit CKOPT. Trong đó 2 bit SUT1:0 chủ yếu dùng để chọn thời gian khởi động, phần này không ảnh hưởng nhiều trong hầu hết các trường hợp (ít nhất là các ví dụ trong Cùng học AVR) vì thế THIETKEMACHDIENTU.NET sẽ bỏ qua, chúng ta để 2 fuse bits  như mặc định. Nếu start-up time thật sự ảnh hưởng đến chương trình của bạn, bạn hãy tham khảo thêm phần “System Clock and Clock Option” trong datasheet của chip. Phần này THIETKEMACHDIENTU.NET chủ yếu trình bày cách chọn nguồn xung giữ nhịp cho chip.
      Có tất cả 5 loại nguồn xung giữ nhịp chính cho chip nhưng để đơn giản chúng ta chỉ xét 2 trường hợp là dùng nguồn thạch anh ngoài và dùng xung giữ nhịp được tạo bởi mạch RC trong chip. 

      Xung giữ nhịp trong chip (xung nội): Hầu hết các chip AVR được trang bị 1 mạch tạo xung giữ nhịp RC bên trong, nếu sử dụng nguồn xung giự nhịp này chúng ta có thể bỏ qua mạch tạo xung bên ngoài. Nguồn xung giữ nhịp được tạo ra bên trong chip được cố định ở 1 trong 4 mức : 1MHz, 2 MHz, 4 Mhz và 8 MHz. Các Fuse bits CKSEL3:0 quyết định việc chọn nguồn xung này. Bảng 4 tóm tắt cách phối hợp các Fuse bits CKSEL để chọn nguồn xung nội.
Bảng 4. Chọn xung giữ nhịp nội bằng các Fuse bits CKSEL.

(Nomial frequency: tần số danh nghĩa, giá trị thực có thể khác do sai số)
     Đối với chip ATmega32, nguồn xung nội 1MHz được set mặc định trên các chip mới. Xem lại hình 1 bạn thấy CKSEL3=0 (được checked), CKSEL2=0 (được checked), CKSEL1=0 (được checked), CKSEL0=1 (không check). Các hình 4, 5, 6 và 7 bên dưới gợi ý bạn cách chọn nguồn xung nội bằng phần mềm nạp PonyProg, chú ý sau khi chọn các bits bạn phải nhấn bút “Write” để ghi vào chip. 

Hình 4. Chọn nguồn xung nội 1MHz (đồng thời tắt JTAG, Boot Loader, BOD). 


Hình 5. Chọn nguồn xung nội 2MHz (đồng thời tắt JTAG, Boot Loader, BOD). 


Hình 6. Chọn nguồn xung nội 4MHz (đồng thời tắt JTAG, Boot Loader, BOD). 


Hình 7. Chọn nguồn xung nội 8MHz (đồng thời tắt JTAG, Boot Loader, BOD). 

       Xung giữ nhịp từ mạch thạch anh bên ngoài (Crystal): dùng xung nội có nhược điểm là tấn số xung đã được giữ cố định trong 4 mức và tấn số cao nhất có thể đạt là 8MHz trong khi AVR cho phép làm việc ở 16Mhz, mặc khác sai số cũng tương đối lớn khi xùng xung nội. Dùng thạch anh để tạo xung giữ nhịp là một giải pháp tốt, có thể tạo một mạch thạch anh đơn giản và nối với 2 chân XTAL1 và XTAL2 của AVR như trong hình 8. 


Hình 8. Mạch tạo xung ngoài bằng thạch anh. 

     Để “báo” cho AVR biết là chúng ta muốn sử dụng thạch anh ngoài làm mạch tạo xung, hãy set các Fuse bits CKSEL3:0 thành 1 trong 2 giá trị: 1111 hoặc 1010 (nhị phân). Trong trường hợp này, Fuse bit CKOPT có tác dụng chọn giữa 2 chế độ khuyếch đại, chế độ CKOPT = 0 (programmed)  thích hợp với thạch anh có tần số lớn nhất là 16MHz và CKOPT=1 (unprorgammed) khi tần số thạch anh nhỏ hơn hoặc bằng 8MHz. Các hình 9 và 10 gợi ý cách set Fuse bits để chọn nguồn xung nhịp là mạch thạch anh ngoài với  các tần số lớn nhất 8MHz và lớn nhất 16MHz. 


Hình 9. Chọn xung giữ nhịp từ thạch anh ngoài với tần số lớn nhất là 8MHz. 


Hình 10. Chọn xung giữ nhịp từ thạch anh ngoài với tần số lớn nhất là 16MHz. 

    Sau khi đã chọn các Fuse bits, việc cuối cùng và rất quan trọng là ghi các Fuse bits này vào chuip bằng cách nhấn nút “Write” (PonyProg).
    Đối với các chương trình nạp chip khác, Fuse bits cũng được set tương tự.

THIETKEMACHDIENTU.NET

NGUỒN: HOCAVR.COM

 Một trong những ưu điểm lớn nhất của các chip AVR là tính đơn giản khi sử dụng trong đó có việc nạp chương trình cho chip. AVR hỗ trợ khả năng nạp chương trình ngay trong hệ thống - ISP(In-System Programming), có thể nạp trực tiếp chương trình vào chip mà không cần tháo chip ra khỏi mạch ứng dụng.
      Mạch nạp cho AVR rất phong phú nhưng hầu hết đều rất đơn giản. Trong bài này phamhoangvuong.com giới thiệu 2 loại mạch nạp rất phổ biến trong những người sử dụng AVR đó là mạch ISP SKT200/300 (gọi tắt là AVR ISP) và mạch USB AVR910. Mỗi loại có ưu và nhược điểm riêng, tùy theo nhu cầu và khả năng bạn sẽ chọn chế tạo cho mình 1 loại mạch nạp phù hợp. 
I. Mạch nạp STK200/300.
      Mạch nạp loại này sử dụng cho các board STK200/300 của Atmel nên thường được gọi là STK200/300. Mạch này giao tiếp với máy tính qua cổng LPT (cổng song song). Có 2 phiên bản phổ biến của mạch STK200/300 đó là phiên bản thu gọn và phiên bản sử dụng IC đệm 74xx244.
      Sơ đồ mạch nạp thu gọn được trình bày trong hình 1. Đây là loại mạch đơn giản nhất trong tất cả các loại mạch nạp cho AVR, mạch chỉ bao gồm 4 điện trở. Nhược điểm của mạch này là không an toàn, có thể gây hại cho cổng LPT (thật ra phamhoangvuong.com chưa mắc phải vấn đề này khi sử dụng mạch STK200/300 thu gọn). Mặt khác mạch này không đảm bảo nạp được cho tất cả các chip AVR. Tuy nhiên, nếu bạn không có nhiều kinh nghiệm làm các mạch điện tử thì có thể chế tạo mạch này để test chương trình AVR mà bạn đã học.

Hình 1. Sơ đồ mạch nạp STK200/300 thu gọn.
      Một loại mạch STK200/300 khác được sử dụng rất phổ biến là loại mạch có dùng IC đệm 74HC244 (hoặc 74LS244), so với mạch thu gọn, mạch này có phức tạp hơn đôi chút (xem hình 2) nhưng bù lại nó là mạch nạp rất ổn định và an toàn. Mạch này được hỗ trợ bởi rất nhiều chương trình nạp và sử dụng được cho hầu hết các loại chip AVR.

Hình 2. Sơ đồ mạch nạp STK200/300 đầy đủ.
      Như quan sát trong hình 1 và 2, việc nạp ISP cho AVR thường được thực hiện thông qua 6 đường nạp cơ bản, đó là GND, VCC, RESET, SCK, MISO và MOSI. Khi chế tạo mạch nạp, bạn phải chú ý thứ tự của các đường nạp này sao cho phù hợp với thứ tự mà bạn đã bố trí cho mạch ứng dụng. Một điều đặc biệt là ở các chip ATmega16, ATmega32, ATmega8535, AT90S8535...6 đường dành cho việc nạp ISP nằm cạnh nhau và theo thứ tự GND, VCC, RESET, SCK, MISO, MOSI. Vì thế phamhoangvuong.com khuyên bạn nên bố trí theo thứ tự này để tiện trong việc kết nối với mạch ứng dụng (nhất là khi bạn sử dụng các loại chip trên và làm mạch test bằng bread board)..Các mạch nạp STK200/300 được mô tả trong hình 3.

Hình 3. Mạch nạp STK200/300. 
II. Chương trình nạp PonyProg.
      Chương trình nạp là một tiện ít giúp đổ file hex sau khi biên dịch vào chip thông qua các mạch nạp. Hầu hết các bộ công cụ lập trình cho AVR đều tích hợp sẵn một chương trình nạp chip. avrdude là chương trình nạp miễn phí hỗ trợ rất nhiều loại mạch, được tích hợp với WinAVR. Tuy nhiên, đây là chương trình nạp console (không có giao diện) nên sử dụng tương đối khó khăn nhất là khi cần nạp các bit Fuse hay Lock. Các phần mêm lập trình cho chip như CodevisionAVR, ICCAVR, Bascom,...đều có chương trình nạp riêng rất đa năng và dễ sử dụng. Nhưng do đây là các công cụ thương mại nên bạn cần mua nếu muốn sử dụng. AVR Studio, tất nhiên, có chương trình nạp chip AVR Prog nhưng chương trình này lại không hỗ trợ mạch nạp mà STK200/300 mà phamhoangvuong.com giới thiệu bên trên. Cuối cùng là PonyProg, PonyProg không phải là hoàn hảo nhất nhưng là lựa chọn tối ưu nhất để nạp bằng mạch STK200/300. Đây là chương trình nạp hoàn toàn miễn phí, hỗ trợ nhiều loại mạch và nhiều dòng vi điều khiển (như AVR, PIC...), giao diện lại khá dễ sử dụng. Trong phần này phamhoangvuong.com dùng PonyProg để minh họa cho cách nạp chương trình vào AVR thông qua mạch nạp STK200/300.
      Download và cài đặt PonyProg: bạn có thể download miễn phí PonyProg tại website chính thức của Lancos . Cài đặt và tiến hành setup phần mềm.
      Setup: Trước khi sử dụng PonyProg để nạp AVR bạn cần Setup một số thông số cho phần mềm như loại chip, loại mạch nạp...Chạy PonyProg, chọn menu Device và chọn loại chip mà bạn cần nạp (ví dụ "AVR micro/ ATmega32"). Tiếp đến xác nhận loại mạch nạp và giao diện cổng bằng cách vào menu "Setup/Interface Setup"...Với mạch nạp STK200/300, hãy set các thông số trong dialog "I/O Port setup" như trong hình 4 và nhấn OK để xác nhận Setup.


Hình 4. Setup port cho ponyProg.
      Ghi fuse bits và Lock bits: Ponyprog cho phép người dùng ghi và đọc các bit cấu hình của chip như fuse bits và lock bits, để thực hiện, chọn menu "Command/Security and Configuration bits" hay đơn giản là nhấn tổ hợp phím Ctrl+S. Dialog mới xuất hiện cho phép bạn cài đăt các bit cấu hình cho chip (chọn các bit mong muốn và nhấn button write - xem thêm bài fuse bits để hiểu rõ hơn chức năng các bit này).
      Download chương trình vào chip: Hãy mở file chương trình cần nạp vào chip bằng cách vào menu "File/Open Program (FLASH) file" hoặc nhấn nút công cụ "P" trên thanh công cụ. Nội dung file FLASH sẽ được hiển thị trong 1 cửa sổ con. Để nạp chương trình cho chip, hãy vào menu "Command/Write Program(FLASH)" hoặc nhấn nút công cụ "Write Program Memory(FLASH)" trên thanh công cụ.
     Ngoài ra, PonyProg còn có rất nhiều chức năng khác như đọc nội dung chip, xóa chip, kiểm tra...với các chức năng này bạn hãy tự khám phá và sử dụng. 
III. Mạch nạp USB AVR910.
        Khuyến cáo: theo phản hồi của một số bạn đọc trên hocavr.com, mạch USB AVR910 dễ mắc lỗi set sai fuse bit và dẫn đến một số khó khăn nhất định để reset lại fuse. Vì vậy nếu là người chưa có nhiều kinh nghiệm xử lí sự cố với AVR, bạn được khuyên nên làm mạch USBasp thay cho  mạch AVR910.
       Tuy mạch nạp STK200/300 đơn giản, dễ chế tạo nhưng có một hạn chế là mạch này sử dụng cổng LPT làm cổng giao tiếp. Trên một số máy tính gần đây cổng LPT đã bị loại bỏ, thay vào đó các cổng USB đã trở thành cổng giao tiếp không thể thiếu của máy tinh. Một mạch nạp sử dụng cổng USB sẽ tiện lợi hơn rất nhiều so với cổng LPT hay COM. Có một số dự án nghiên cứu chế tạo mạch nạp USB cho AVR, trong số đó có lẽ phổ biến nhất là mạch nạp AVR910 USB của Prottoss. Gọi là mạch AVR910 vì nguyên lý nạp chương trình của mạch này áp dụng hướng dẫn trong application note 910 của Atmel về In-System Programming. Mạch AVR910 USB được điều khiển bởi một chip Master Atmega8, chip này chứa một firmware bên trong, firmware thực hiện 2 chức năng: thứ nhất là một cầu chuyển USB-UART dựa trên thư viện của Objective Development và thứ hai là điều khiển quá trình nạp theo "chuẩn" AVR910.
      Mạch nạp ARV910 USB không quá phức tạp cho bạn tự chế tạo, hãy download các công cụ cần thiết từ website của Prottoss (đã dịch bằng google translate)  và thực hiện theo các chỉ dẫn bên dưới.
      Giải nén file rar vừa download về bạn sẽ thấy có 3 files bên trong. File thứ nhất là sơ đồ mạch điện (file pdf), file thứ hai là driver cho máy tính (file inf) và file thứ 3 là firmware cho chip master ATmega8 (file hex - xem hình bên dưới).

      Chế tạo mạch: tham khảo sơ đồ mạch điện và chế tạo một mạch điện theo mạch nguyên lý trong file pdf hoặc trong hình 5 bên dưới.

Hình 5. Sơ đồ mạch nạp AVR910 USB của Prottoss.
      Khi chế tạo mạch điện trên, bạn lưu ý một số điểm như sau: hãy bỏ qua các Jumper J1, J2 và J3, nối trực tiếp chân 16 của ATmega8 với điện trở R13. Nếu bạn không biết cách xác định thứ tự chân của cổng USB thì hãy dùng một đổng hồ đo điện áp, chân 1 sẽ có điện áp dương (khoảng 5V) và chân 4 là chân GND).
      Nạp firmware cho chip mega8: trước khi gắn chip mega8 vào mạch điện hình 5, bạn phải nạp firmware (file USB.910.Programmer.hex) vào chip này bằng một mạch nạp bất kỳ mà bạn có (ví dụ mạch STK200/300). Chú ý bạn cần set fuse bit cho chip này sao cho nguồn thạch anh ngoài 12MHz đươc sử dụng (hãy đặt 2 bit BOOTZS0 và BOOTSZ1 bằng 0 (checked), các bit còn lại bằng 1 (bỏ trống) - tham khảo bài Fuse bits).
      Cài driver cho windows: sau khi chế tạo mạch và nạp firmware cho chip master, bạn kết nối mạch nạp với cổng USB của máy tính. Một cách tự động, Windows sẽ nhận diện một phần cứng mới được kết nối và yêu cầu cài đặt driver cho thiết bị. Hãy browse đến thư mục chứa file driver inf mà bạn đã giải nén. Quá trình cài driver sẽ bắt đầu, nếu trong quá trình cài đặt Windows thông báo lỗi bạn hãy nhấn "Continue anyway..." để tiếp tục cài đặt đến khi hoàn tất. Sau khi cài đặt driver một cổng COM ảo sẽ xuất hiện trong Hardware list của bạn, hãy mở tiện ích Device manager của Windows để kiểm tra, hãy ghi lại chỉ số cổng COM ảo (COM1, COM2, COM3...) để khai báo trong các chương trình nạp.
      Sử dụng AVR910 USB: mạch nạp AVR910 USB được hỗ trợ bởi phần mềm nạp của CodevisionAVR và AVR Prog của AVRStudio. Kết nối mạch với máy tính, chạy AVRStudio và chương trình nạp AVR Prog (vào menu Tools/AVR Prog). Trong mục Hex file hãy browse đến file hex cần nạp cho chip, mục Device chọn loại chip AVR và sau đó nhấn button Write trong mục Flash để nạp vào file hex vào chip. Nếu muốn xác lập fuse bits hay lock bits, hãy nhấn button Advance.

Hình 6. Nạp chip bằng mạch nạp AVR910 USB và AVR Prog.
IV. Mạch nạp USBasp.
      So với mạch nạp AVR910, mạch nạp USBasp của Thomas Fischl được người viết đánh giá cao hơn về tính ổn định và tính tiện lợi (chương trình nạp phong phú). Mạch điện nguyên lý cũng tương đối đơn giản, sử dụng chip Atmega8 hoặc Atmega48.
      Trước hết hãy download các công cụ cần thiết từ website của Flischl  và thực hiện theo các chỉ dẫn bên dưới.
      Giải nén file gz (hoặc file rar) vừa download về bạn sẽ thấy có 3 thư mục và 2 files bên trong. Thư mục thứ nhất tên bin, bên trong thư mục này có chứa 2 thư mục con là firmware chứa file hex cho chip master và win-driver chứa driver cho máy tính. Thư mục thứ hai tên circuit chứa sơ đồ mạch nguyên lý của mạch nạp USBasp (cả file pdf và file sch cho phần mềm Eagle). Thư mục thứ ba tên firmware chứa mã nguồn của firmware cho chip Master. Nếu bạn chỉ muốn làm mạch nạp thì bỏ qua thư mục thứ ba này.
      Chế tạo mạch: tham khảo sơ đồ mạch điện và chế tạo một mạch điện theo mạch nguyên lý trong file pdf hoặc trong hình 5 bên dưới.

Hình 7. Sơ đồ mạch nạp USBasp của Flisch.
      Khi chế tạo mạch điện trên, bạn lưu ý một số điểm như sau: hãy bỏ qua Jumper JP2, nối trực tiếp JP1 lại (dùng mạch nạp cấp nguồn luôn cho chip).  Bạn có thể dùng 1 trong 2 loại chip là Atmega8 hoặc Atmega48, chú ý dùng loại chip cho phép tần số clock lên đến 16MHz (các chip có mã 16 ở phía sau, ví dụ Atmega8-16PU).
      Nạp firmware cho chip Master (Atmega8 hoặc Atmega48): trước khi gắn chip mega8 vào mạch điện hình 7 bạn phải nạp firmware (file hex trong thư mục bin\firmware) vào chip này bằng một mạch nạp bất kỳ mà bạn có (ví dụ mạch STK200/300). Chú ý bạn cần set fuse bit cho chip này sao cho nguồn thạch anh ngoài 12MHz đươc sử dụng (hãy đặt 2 bit BOOTZS0 và BOOTSZ1 bằng 0 (checked), các bit còn lại bằng 1 (bỏ trống) - tham khảo bài Fuse bits).
      Cài driver cho windows: sau khi chế tạo mạch và nạp firmware cho chip master, bạn kết nối mạch nạp với cổng USB của máy tính. Một cách tự động, Windows sẽ nhận diện một phần cứng mới được kết nối và yêu cầu cài đặt driver cho thiết bị. Hãy browse đến thư mục "bin\win-driver\libusb_0.1.12.1". Quá trình cài driver sẽ bắt đầu, nếu trong quá trình cài đặt Windows thông báo lỗi bạn hãy nhấn "Continue anyway..." để tiếp tục cài đặt đến khi hoàn tất. Sau khi cài đặt driver trong Device list sẽ xuất hiện một thiết bị gọi là USBasp. Hãy vào Device manager (Nhấn tổ hợp phím Wins+Break, chọn tab Hardware và nhấn Device manager) bạn sẽ thấy thiết bị này như hình bên dưới.

      Sử dụng mạch nạp USBasp: bạn có thể dùng mạch nạp USBasp với phần mềm nạp avrdude tích hợp sẵn trong Winavr, hoặc Bascomavr, hoặc eXtreme Burner, hoặc Khazama AVR Programmer. Theo gợi ý của người viết, bạn nên dùng phần Khazama cho mạch USBasp vì phần mềm này có giao diện thân thiện, việc set fuse bit cũng dễ dàng như các phần mềm Ponyprog hay CodevisionAVR programmer. 

Hình 8. Phần mềm Khazama cho mạch nạp USBasp
Sáng lập Bởi:
phamhoangvuong.com

NGUỒN: HOCAVR.COM

I. Giới thiệu

      AVR là một họ vi điều khiển do hãng Atmel sản xuất (Atmel cũng là nhà sản xuất dòng vi điều khiển 89C51 mà có thể bạn đã từng nghe đến). AVR là chip vi điều khiển 8 bits với cấu trúc tập lệnh đơn giản hóa-RISC(Reduced Instruction Set Computer), một kiểu cấu trúc đang thể hiện ưu thế trong các bộ xử lí.  
      Tại sao AVR: so với các chip vi điều khiển 8 bits khác, AVR có nhiều đặc tính hơn hẳn, hơn cả trong tính ứng dụng (dễ sử dụng) và đặc biệt là về chức năng:
  • Gần như chúng ta không cần mắc thêm bất kỳ linh kiện phụ nào khi sử dụng AVR, thậm chí không cần nguồn tạo xung clock cho chip (thường là các khối thạch anh).
  • Thiết bị lập trình (mạch nạp) cho AVR rất đơn giản, có loại mạch nạp chỉ cần vài điện trở là có thể làm được. một số AVR còn hỗ trợ lập trình on – chip bằng bootloader không cần mạch nạp… 
  • Bên cạnh lập trình bằng ASM, cấu trúc AVR được thiết kế tương thích C. 
  • Nguồn tài nguyên về source code, tài liệu, application note…rất lớn trên internet. 
  • Hầu hết các chip AVR có những tính năng (features) sau:
  • Có thể sử dụng xung clock lên đến 16MHz, hoặc sử dụng xung clock nội lên đến 8 MHz (sai số 3%)
  • Bộ nhớ chương trình Flash có thể lập trình lại rất nhiều lần và dung lượng lớn, có SRAM (Ram tĩnh) lớn, và đặc biệt có bộ nhớ lưu trữ lập trình được EEPROM.
  • Nhiều ngõ vào ra (I/O PORT) 2 hướng (bi-directional).
  • 8 bits, 16 bits timer/counter tích hợp PWM.
  • Các bộ chuyển đối Analog – Digital phân giải 10 bits, nhiều kênh.
  • Chức năng Analog comparator.
  • Giao diện nối tiếp USART (tương thích chuẩn nối tiếp RS-232).
  • Giao diện nối tiếp Two –Wire –Serial (tương thích chuẩn I2C) Master và Slaver.
  • Giao diện nối tiếp Serial Peripheral Interface (SPI)
  • ...
Một số chip AVR thông dụng:
  • AT90S1200
  • AT90S2313
  • AT90S2323 and AT90S2343
  • AT90S2333 and AT90S4433
  • AT90S4414 and AT90S8515
  • AT90S4434 and AT90S8535
  • AT90C8534
  • ATtiny10, ATtiny11 and ATtiny12
  • ATtiny15
  • ATtiny22
  • ATtiny26
  • ATtiny28
  • ATmega8/8515/8535
  • ATmega16
  • ATmega161
  • ATmega162
  • ATmega163
  • ATmega169
  • ATmega32
  • ATmega323
  • ATmega103
  • ATmega64/128/2560/2561
  • AT86RF401.
  • ....
     Trong bài viết này chúng mình sử dụng chip ATmega8 để làm ví dụ, chúng tôi chọn ATmega8 vì đây là loại chip thuộc dòng AVR mới nhất, nó có đầy đủ các tính năng của AVR nhưng lại nhỏ gọn (gói PDIP có 28 chân) và low cost nên các bạn có thể mua để tự mình tạo ứng dụng.
     Tại sao Assembly (ASM): bạn có thể không cần biết về cấu trúc của AVR vẫn có thể lập trình cho AVR bằng các phần mềm hỗ trợ ngôn ngữ cấp cao như BascomAVR (Basic) hay CodevisionAVR (C), tuy nhiên đó không phải là mục đích của bài viết này. Để hiểu thấu đáo về AVR bạn phải lập trình bằng chính ngôn ngữ của nó, ASM. Như vậy lập trình bằng ASM  giúp bạn hiểu tường tận về AVR, và tất nhiên để lập trình được bằng ASM bạn phải hiểu về cấu trúc AVR….Một lý do khác bạn mà chúng tôi khuyên bạn nên lập trình bằng ASM là các trình dịch (compiler) ASM cho AVR là hoàn toàn miễn phí, và nguồn source code cho AVR viết bằng ASM là rất lớn. Tuy nhiên một khi bạn đã thành thạo AVR và ASM bạn có thể sử dụng các ngôn ngữ cấp cao như C để viết ứng dụng vì ưu điểm của ngôn ngữ cấp cao là giúp bạn dễ dàng thực hiện các phép toán đại số 16 hay 32 bit (vốn là vấn đề khó khăn khi lập trình bằng ASM).
 II. Công cụ.
     Trình biên dịch: có rất nhiều trình biên dịch bạn có thể sử dụng đế biên dịch code của bạn thành file intel hex để nạp vào chip, một số trình dịch quen thuộc có thể kể đến như sau:
  • AvrStudio: là trình biên dịch ASM chính thức cung cấp bởi Atmel, đây là trình biên dịch hoàn toàn miễn phí và tất nhiên là tốt nhất cho lập trình AVR bằng ASM. Phiên bản hiện tại là 4.18 SP1, bạn có thể download phần mềm AvrStudio tại trang web chính thức của Atmel .
  • Wavrasm: cũng được cung cấp bởi Atmel, nó chính là tiền thân của AvrStudio. Hiện tại wavrasm không còn được sử dụng nhiều vì so với AvrStudio trình biên dịch này có nhiều hạng chế.
  • WinAVR hay avr-gcc: là bộ trình dịch được phát triển bởi gnu, ngôn ngữ sử dụng là C và có thể được dùng tích  hợp với AvrStudio (dùng Avrstudio làm trình biên tập – editor). Đặc biệt bộ biên dịch này cũng miễn phí và đa số nguồn source code C được viết bằng bộ này, vì vậy nó rất lí tưởng cho bạn khi viết các ứng dụng chuyên nghiệp. Việc lập trình bằng avrgcc chúng tôi sẽ đề cập trong những phần sau.
  • CodeVisionAvr: một chương trình bằng ngôn ngữ C rất hay cho AVR, hỗ trợ nhiều thư viện lập trình. Tuy nhiên là chương trình thương mại. Bạn  có thể download bản demo (đầy đủ chức năng nhưng nhưng giới hạn dung lượng bộ nhớ chương trình 2KB) tại Website hpinfotech
  • ICCAVR: lập trình C cho avr, download bản demo.
  • BascomAVR: lập trình cho AVR bằng basic, đây là trình biên dịch khá hay và dễ sử dụng, hỗ trợ rất nhiều thư viện. Tuy nhiên rất khó debug lỗi và không thích hợp cho việc tìm hiểu AVR. Vì vậy chúng tôi không bạn khuyến khích bạn sử dụng trình dịch này. Bạn có thể download bản demo (4K limit).
  • Và còn rất nhiều trình biên dịch khác cho AVR mà chúng tôi không kể ra đây, nhìn chung tất cả các trình biên dịch này hỗ trợ C hoặc Basic hoặc thậm chí Pascal. Việc chọn 1 trình biên dịch tùy thuộc vào mục đích, vào mức độ ứng dụng, vào kinh nghiệm sử dụng và nhiều lý do khác nữa. Ví dụ chúng tôi thường dùng Avrstudio và avrgcc khi học sử dụng AVR và khi viết thư viện. Nhưng khi cần viết chương trình ứng dụng chúng tôi thường chọn avrgcc và CodeVisionAVR.
     Trong bài viết này chúng tôi hướng dẫn bạn sử dụng AvrStudio để viết chương trình cho AVR bằng ASM.
     Chương trình nạp (Chip Programmer): đa số các trình biên dịch (AvrStudio, CodeVisionAVR, Bascom…) đều tích hợp sẵn 1 chương trình nạp chip hỗ trợ nhiều loại mạch nạp nên bạn không quá lo lắng. Trong trường hợp khác, bạn có thể sử dụng các chương trình nạp như Icprog hay Ponyprog…là các chương trình nạp miễn phí cho AVR. Việc chọn và sử dụng chương trình nạp sẽ được giới thiệu trong các bài sau.
      Mạch nạp: tham khảo bài viết giới thiệu mạch nạp AVR.
     Chương trình mô phỏng: avr simulator là trình mô phỏng và debbug được tích hợp sẵn trong Avrstudio, avr simulator cho phép bạn quan sát trạng thái các thanh ghi bên trong AVR nên rất phù hợp để bạn debug chương trình. Proteus là chương trình thứ hai chúng tôi muốn nói đến, Proteus không những mô phỏng hoạt động bên trong chip mà còn mô phỏng mạch điện tử. Proteus mô phỏng rất trực quan, nó là 1 công cụ hữu ích khi các bạn chưa có điều kiện làm các mạch điện tử.
III. Ví dụ đầu tiên của bạn.
     Sau khi download AvrStudio, bạn hãy cài đăt phần mềm trên máy của bạn, quá trình cài đặt rất đơn giản, bạn hãy theo các mặc định và nhấn “next” để cài đặt. Trong bài đầu tiên này chúng ta sẽ viết thử 1 chương trình đơn giản cho AVR sau đó chạy mô phỏng bằng Proteus. Có thể có một số câu lệnh các bạn sẽ không hiểu, nhưng đừng lo lắng quá, trong bài thứ 2 chúng ta sẽ học về cấu trúc AVR các bạn sẽ được giải thich rõ hơn.
     Để thực hiện ví dụ này, bạn hãy tạo một Project bằng AVRStudio, phần hướng dẫn chi tiết cho việc tạo Project trong AVRStudio bạn hãy tham khảo ở bài hướng dẫn AVRStudio. Đoạn code ví dụ trong bài đầu tiên này được trình bày trong List1.
List 1. Đoạn code đầu tiên của bạn.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 61
.CSEG
.INCLUDE "M8DEF.INC"
.ORG 0x000
    RJMP BATDAU

.ORG 0x020
BATDAU:
; KHOI TAO CAC DIEU KIEN DAU
    LDI   R16, HIGH(RAMEND)
    LDI   R17, LOW(RAMEND)
    OUT SPH, R16
    OUT SPL, R17
    LDI   R16, 0xFF;
    OUT DDRB, R16  

; CHUONG TRINH CHINH
MAIN:
    LDI R16, 0B00000001
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B00000010
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B00000100
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B00001000
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B00010000
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B00100000
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B01000000
    OUT PORTB, R16
    RCALL DELAY

    LDI R16, 0B10000000
    OUT PORTB, R16
    RCALL DELAY
  
    RJMP MAIN
; CHUONG TRING CON DELAY 65535 chu ky (khoang 65535us neu  xung ;clock cho chip la 1M)
DELAY:
    LDI R20, 0xFF
    DELAY0:
        LDI R21, 0xFF
        DELAY1:
            DEC R21
            BRNE  DELAY1
        DEC R20
        BRNE DELAY0
RET 
     Trước khi tìm hiểu ý nghĩa đoạn code, hãy nhìn 1 lượt qua đoạn code. Trước hết việc viết HOA hay viết thường là không quan trọng, bạn có thể viết đoạn code với bất cứ hình thức nào miễn đúng cú pháp, từ khóa là được. Trong đoạn code:
  • Bạn thấy 1 số từ có màu BLUE (ví dụ LDI, OUT, RJMP, RCALL, RET…)đó là các INSTRUCTiON, tức là các câu lệnh của ngôn ngữ ASM, bạn có thể đọc tài liệu “AVR INSTRUCTION” để tìm hiểu tất cả các INSTRUCTION. Các INSTRUCTION sau đó sẽ được trình dịch dịch thành các mã tương ứng.
  • Một số từ bắt đầu bằng bằng dấu chấm “.” là các DIRECTIVE (ví dụ .INCLUDE hay .ORG )đó cũng là những từ khóa mặc định của ASM AVR, các DIRECTIVE không phải là mã lệnh mà chỉ là các chỉ dẫn về địa chỉ bộ nhớ, khởi động bộ nhớ, định nghĩa macro…và không được trình dịch dịch thành mã. Chi tiết về DIRECTIVE có thể tìm thấy trong  các tài liệu về ASM AVR, dưới đây chúng tôi tóm tắt các DIRECTIVE và chức năng của chúng như sau:
DIRECTIVE
  • Thông thường 1 INSTRUCTION được theo sau bởi 2 toán hạng – operand (tuy nhiên có nhiều trường hợp chỉ có 1 toán hạng hoặc không có toán hạng), khi đó toán hạng thứ nhất sẽ là các THANH GHI. của AVR (như đã đề cập, chúng ta sẽ khảo sát thanh ghi AVR trong các bài sau), ví dụ : “LDI R16, 0xFF;” trong đó toán hạng “R16” là tên 1 thanh ghi trong AVR, và “0xFF” là 1 hằng số dạng hexadecimal có giá trị tương ứng là 255 dạng thập phân hay 11111111 nhị phân.
  • Các từ theo sau bởi dấu “:” là các nhãn – label (ví dụ MAIN, DELAY…), đó là từ do chúng ta tự đặt, nó thực chất là 1 vị trí trong bộ nhớ chương trình, có thể sử dụng nhãn như 1 chương trình con.
  • Phần đi sau dấu “;” gọi là giải thích – comment, phần này không được biên dịch, bạn có thể ghi comment ở bất cứ đâu trong chương trình với yêu cầu phải sử dụng dấu “;” trước nó.
     Giải thích đoạn code:có thể chia đoạn code trên thành 4 phần: phần đầu chứa các DIRECTIVE và lệnh RJMP dùng để xác định các địa chỉ bộ nhớ chương trình, phần 2 là khởi tạo một số điều kiện đầu cho Stack Pointer và PORT, phần 3 là chương trình chính, và phần 4 là chương trình con ( chú ý đây chỉ là cách bố trí của riêng chúng tôi, một khi đã quen thuộc, bạn có thể bố trí chương trình theo cách riêng của bạn).
  • Phần 1 và phần 2:
    .CSEG
         Chỉ thị .CSEG: Code Segment báo cho trình biên dịch rằng phần code theo sau là phần chương trình thực thi, phần này sẽ được download vào bộ nhớ chương trình của chip.
    .INCLUDE "M8DEF.INC"
         Chỉ thị .INCLUDE báo cho trình biên dịch bắt đầu đọc 1 file đính kèm, trong trường hợp trên là file “M8DEF.INC”, đây là file chứa các khai báo cho chip Atmega8 như thanh ghi, ngắt…cho việc truy xuất trong chương trình của bạn, đây là dòng bắt buộc, nếu bạn lập trình cho chip khác bạn hãy đổi tên file đính kèm, ví dụ “m32def.inc” cho chip ATmega32… bạn có thể tìm thấy các file này trong thư mục “C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes”.
    .ORG 0x000
         Chỉ thị .ORG: Set Program Origin, set vị trí trong bộ nhớ sẽ được tác động đến, trong trường hợp trên, .ORG 0x000 xác định phần code theo ngay sau sẽ nằm ở địa chỉ 000, vị trí đầu tiên, trong bộ nhớ chương trình. Và dòng lênh trong vị trí đầu tiên đó là:
    RJMP BATDAU
         RJMP: Relative Jump là lệnh nhảy không điều kiện đến 1 vị trí trong bộ nhớ, trong trường hợp trên là nhảy đến nhãn BATDAU, và nhãn BATDAU nằm ở vị trí 0x020 (số hexadecimal, 0x020 =32 decimal) vì nó được khai báo ngay sau DIRECTIVE .ORG 0x020.
    .ORG 0x020
    BATDAU

         Như thế phần bộ nhớ chương trình nằm giữa 0 và 0x020 không được sử dụng trong đoạn code của chúng ta, phần này được sử dụng cho mục đích khác, đó là các vectơ ngắt ( không được đề cập ở đây). Tiếp theo:
    ; KHOI TAO CÁC DIEU KIEN DAU
    LDI R16, HIGH(RAMEND)
    LDI R17, LOW(RAMEND)
    OUT SPH, R16
    OUT SPL, R17


    Bốn dòng code trên khởi tạo cho Stack Pointer, chúng ta sẽ tìm hiểu phần này trong các bài về Stack và chương trình con.
    Lời khuyên: các bạn nên khởi động 1 chương trình theo cách trên và chúng ta sẽ hiểu chúng rõ hơn sau này !
    LDI R16, 0xFF
    OUT DDRB, R16

         Bạn chú ý 2 dòng trên và những gì chúng tôi giải thích sau đây, 2 dòng này có tác dụng khởi động PORTB của chip ATmega8 tác dụng như các ngõ xuất tín hiệu (OUTPUT). Trước hết hãy quan sát chip ATmega8 trong hình sau
    Atmega8
    Hình 1: chip ATmega8.
         Bạn có thể thấy chip này gồm 28 chân, trông đó có các chân được ghi là PB0(chân 14), PB1(chân 15),…,PB7(chân 10), đó là các chân của PORTB. PORT là khái niệm chỉ các ngõ xuất nhập. Trong AVR, PORT có thể giao tiếp theo 2 hướng (bi – directional), có thể dùng để xuất hoặc nhận thông tin, mỗi PORT có 8 chân. Chip Atmega8 có 3 PORT có tên tương ứng là PORTB, PORTC và PORTD (một số chip AVR khác có 4 hoặc 6 PORT). PORT được coi là “cửa ngõ” then chốt của vi điều khiển.
         Trong AVR, mỗi PORT liên quan đến 3 thanh ghi (8 bits) có tên tương ứng là DDRx, PINx, và PORTx với “x” là tên của PORT, mỗi bit trong thanh ghi tương ứng với mỗi chân của PORT. Trong trường hợp của Atmega8 “x” là B, C hoặc D. Ví dụ chúng ta quan tâm đến PORTB thì 3 thanh ghi tương ứng có tên là DDRB, PINB và PORTB, trong đó 2 thanh ghi PORTB và PINB được nối trực tiếp với các chân của PORTB, DDRB là thanh ghi điều khiển hướng ( Input hoặc Output). Viết giá trị 1 vào một bit trong thanh ghi DDRB thì chân tương ứng của PORTB sẽ là chân xuất (Output), ngược lại giá trị 0 xác lập chân tương ứng  là ngõ nhập. Sau khi viết giá trị điều khiển vào DDRB, việc truy xuất PORTB được thực hiện thông qua 2 thanh ghi PINB và PORTB.
         Quay lại với 2 dòng code của chúng ta, dòng đầu: “LDI R16, 0xFF”, với LDI – LoaD Immediately, dòng lệnh có ý nghĩa là load giá trị 0xFF vào thanh ghi R16, R16 là tên 1 thanh ghi trong bộ nhớ của AVR, 0xFF là 1 hằng số có dạng thập lục phân, ký hiệu “0x” nói lên điều đó, bạn cũng có thể dùng ký hiệu khác là “$” để chỉ 1 số thập lục phân, ví dụ &FF, và 0xFF=255(thập phân)=0B11111111 (nhị phân). Như thế sau dòng đầu thanh ghi R16 có giá trị là 11111111 (nhị phân). Dòng thứ 2: “OUT DDRB, R16” nghĩa là xuất giá trị từ thanh ghi R16 ra thanh ghi DDRB, tóm lại sau 2 dòng trên giá trị DDRB như sau:
    11111111
         Có thể bạn sẽ hỏi tải sao chúng không sử dụng 1 dòng duy nhất là “LDI DDRB, 0xFF” hay “OUT DDRB, 0xFF”, chúng ta không thể vì lệnh LDI chỉ cho phép thực hiện trên các thanh ghi R16,…R31 và lệnh OUT không thực hiện được với các hằng số.
         Và vì DDRB=11111111 nên trong trường hợp này tất cả các chân của PORTB đã sẵn sàng cho việc xuất dữ liệu. Lúc này thanh ghi PINB không có tác dụng, thanh ghi PORTB sẽ là thanh ghi xuất, ghi giá trị vào thanh ghi này sẽ tác động đến các chân của PORTB.1
  • Phần 3: Chương trình chính
    MAIN:
    LDI R16, 0B00000001
    OUT PORTB, R16
    RCALL DELAY
         Bạn chỉ cần chú ý 4 dòng trên trong toàn bộ phần chương trình chính, trước hết  “MAIN:” chỉ là 1 nhãn do chúng ta tự đặt tên, giống như 1 “cột mốc” trong chương trình thôi. Dòng “LDI R16, 0B00000001” thì bạn đã hiểu, chỉ có 1 khác biệt nhỏ là chúng tôi sử dụng hằng số dạng nhị phân cho bạn dễ hiểu hơn. Và dòng “OUT PORTB, R16” để xuất giá trị 0B00000001 có sẵn trong R16 ra thanh ghi PORTB, lúc này chân PB0 của chip sẽ lên 1 (5V) và các chân còn lại sẽ ở mức 0 (0V). Dòng thứ 3: “RCALL DELAY” là lệnh gọi chương trình con DELAY, tạm hoãn  trước khi thực hiện các dòng lệnh tiếp theo:
    LDI R16, 0B00000010
    OUT PORTB, R16
    RCALL DELAY

         Ba dòng lệnh này cũng giống ba dòng trên, nhưng giá trị xuất ra lúc này là 0B00000010, chân PB1 sẽ lên 5V và các chân khác xuống mức 0V. Và cứ như thế đến đoạn cuối:
    LDI R16, 0B10000000
    OUT PORTB, R16
    RCALL DELAY

    RJMP MAIN
  • Sau khi kết thức 3 dòng trên chân PB7 sẽ lên 5V, kết thúc 1 vòng xoay. Cuối cùng là quay vế đầu chương trình chính bằng dòng “RJMP MAIN”
  • Bây giờ chắc bạn đã đoán được chương trình của chúng ta thực hiện việc gì, đó là quét xoay vòng các chân của PORTB, nếu chúng ta kết nối các chân của PORTB với các LED, chúng ta sẽ có 1 hiệu ứng quét LED xoay vòng, chúng ta thực hiện điều này bằng phần mềm Proteus.
  • Phần 4:  chương trinh con DELAY: đoạn chương trình này không làm gì cả ngoài việc trì hoãn 1 khoảng thời gian, tuy nhiên bạn chưa thể hiểu nó ngay được.
    Đây chỉ là 1 ví dụ đơn giản, chúng tôi cố gắng thực hiện nó theo cách dễ hiểu nhất cho bạn, vì thế đoạn code có vẻ hơi dài dòng, bạn hãy thực hiện lại đoạn chương trình chính bằng đoạn code của bạn.
    Phần cuối cùng là biên dịch đoạn code thành file intel hex để đổ vào chip, nhấn phím F7 để biên dịch.
    Sau khi biên dịch bạn sẽ có 1 file tên “avr1.hex”  trong thưc mục project, chúng ta sẽ dùng file này đổ vào chip sau này.
IV. Mô phỏng bằng Proteus.
     Chúng ta hãy thử nghiệm đoạn chương trình của chúng ta bằng Proteus. Nếu bạn thực hiện đúng kết quả sẽ như minh họa trong hình 2 Hướng  dẫn cụ thể cách vẽ mạch điện và mô phỏng bằng phần mềm Proteus bạn hãy xem bài "Mô phỏng Proteus".

Hình 2. Mô phỏng.

Author Name

{picture https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN0PUWA2genMqX3Sm26mBTX_30OJgDenoIi4K6BR-E1vl3nI7LALp0X759QZgzqrMcGBB7jEbdZnubJbp4n2ZZ22KT196CWCg9DLs3MfEivocdmkjZEPEn-A42hyphenhyphen9dmsca0VIDQr_LjqM/s512-Ic42/pham-van-ngoc-anh.jpg}

Tôi là Ngọc Anh. Tôi đến từ Nghệ An. Tôi tốt nghiệp một trường đại học tại Sài Gòn. Hiện tôi đang phát triển công ty riêng. Liên lạc với tôi qua:

{facebook https://www.facebook.com/phamvanngocanh}
{twitter https://twitter.com/nghiphong1993}
{google https://plus.google.com/+dientuchiase/posts}
{youtube https://www.youtube.com/channel/UCeJKhA_goBNFmDw6RKNtmYQ}

Biểu mẫu liên hệ

Tên

Email *

Thông báo *

Được tạo bởi Blogger.