Nghiên cứu sử dụng Atmega 8

24 497 2
Nghiên cứu sử dụng Atmega 8

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Phần 1: Tổng quan về VĐK Atmega8: Tốc độ tối đa: 16MHz. Dung lượng bộ nhớ chương trình: 8 KB. Bộ nhớ EEPROM: 512 Byte. Dung lượng bộ nhớ RAM: 1 KB. Bộ nhớ chương trình có khả năng ghi 10.000 lần, bộ nhớ EEPROM có thể ghi 100.000 lần. Hỗ trợ bootloader, có khả năng tự ghi vào bộ nhớ chương trình, cập nhật chương trình cho chip mà không cần mạch nạp. Timer 8 bit: 2. Timer 16 bit: 1. ADC: 6 kênh, 10 bit. Giao tiếp: TWI (I2C), UART, SPI Điện áp hoạt động: Atmega8L: 2.7V – 5.5V. Atmega8: 4.5V – 5.5V. … Sơ đồ chân: Hệ thống Clock: Nguồn Clock: Chip có thể hoạt động với các nguồn Clock tương ứng với việc thiết lập các FUSE tương ứng: Ta chỉ tập trung vào hai nguồn clock đó là sử dụng thạch anh ngoài và sử dụng mạch RC tích hợp trong chip (dao động nội). Sử dụng thạch anh ngoài: Để chip có thể hoạt động thì cần được FUSE đúng. Khi xuất xưởng thì mặc định chip được FUSE sử dụng dao động nội với tần số 1MHz. Nguồn RESET: Atmega8 có 4 cách RESET: Reset khi cấp nguồn. Reset ngoài (thông qua chân RESET). Watchdog RESET. Reset khi nguồn bị sụt áp. Điều khiển vào ra (IO): Atmega8 có 3 cổng vào ra: cổng B, cổng C, cổng D. Mỗi cổng được cấu hình, điều khiển thông qua 3 thanh ghi: DDRx, PORTx và PINx. (x: B, C, D). Các thanh ghi này có thể truy xuất từng bit để có thể điều khiển từng chân (Pin) của mỗi cổng. DDRx: quy định chiều của chân, DDRx=1: chân được cấu hình làm đầu ra, ngược lại DDRx=0 quy định chân làm đầu vào. PORTx: nếu PORTx=1 khi chân được cấu hình làm đầu vào thì sẽ kích hoạt điện trở treo dương tại chân tương ứng. Để vô hiệu hóa trở treo này thì PORTx phải được gán 0 hoặc chân được cấu hình làm đầu ra (DDRx=1). Nếu chân được cấu hình làm đầu ra (DDRx=1): Nếu PORTx=1 thì chân tương ứng sẽ được đưa lên cao (1 – VCC), ngược lại nếu PORTx=0 thì chân tương ứng sẽ được đưa xuống thấp (0 – GND) PINx: Đọc dữ liệu từ chân VĐK, độc lập với cấu hình chiều của chân (cả khi DDRx=0 và DDRx=1) trạng thái của chân có thể được đọc thông qua các bit của thanh ghi PINx. Chú ý: Nếu bit thứ 2 (PUD) của thanh ghi SFIOR được ghi giá trị 1 thì trở treo sẽ bị vô hiệu hóa bất chấp các thiết lập thông qua các thanh ghi PORTx, DDRx như đã nói ở trên. Mạch vi điều khiển cơ bản: + Mạch sử dụng thạch anh: + Mạch sử dụng dao động nội: Mạch nạp cho VĐK: ở đây mình dùng mạch nạp ISP do mình thiết kế, việc sử dụng mạch nạp khác là hoàn toàn tương tự: Bạn kết nối các chân tương ứng của mạch nạp vào các chân của chip: MOSI, MISO, SCK, RESET, VCC, GND. Sử dụng AVR Studio để viết chương trình: Khởi động AVR Studio chọn Project > New Project Ở mục 1 chọn AVR GCC (sử dụng ngôn ngữ C). Mục 2 đánh vào tên Project. Mục 3 chọn nơi lưu Project. Chọn Next Sau đó Finish. Cửa sổ 1: Quản lý file mã nguồn. Cửa sổ 2: Soạn thảo mã lệnh. Ví dụ 1: điều khiển Led đơn: Chương trình sẽ nhấp nháy các led nối với PORTD với tần số 1Hz (500ms ON và 500ms OFF) Mã lệnh: Mã: define F_CPU 8000000 include include int main() { DDRD=0xff; while(1) { PORTD=0xff; _delay_ms(500); PORTD=0x00; _delay_ms(500); } } Dòng thứ nhất khai báo tần số dao động, ta sẽ cấu hình cho chip chạy ở tần số 8MHz (Sẽ minh họa cách cấu hình Fuse sau). Dòng thứ 2 khai báo thư viện để sử dụng hàm _delay_ms. Dòng thứ 3 khai báo thư viện định nghĩa các thanh ghi của Atmega8. Chương trình chính đầu tiên cấu hình PORTD làm đầu ra sau đó tạo ra một vòng lặp vô hạn. Để cho led sáng ta xuất 1 ra các chân của PORTD: PORTD=0xff; Để cho led tắt ta xuất giá trị 0: PORTD=0x00; Sau đó ta có thể kiểm tra kết quả với mô phỏng Proteus hoặc nạp vào mạch và kiểm tra. Cách Fuse cho chip: Ở mục 1 chọn Atmega, mục 2 chọn Atmega8, ấn Advance Ấn Write Fuse. Trường hợp sử dụng thạch anh thì Fuse như sau: Ví dụ 2: Đọc trạng thái phím ấn. Chương trình sẽ liên tục kiểm tra phím ấn, nếu phím được ấn thì bật led và nếu phím nhấn không được ấn thì tắt led. Code: Mã: define F_CPU 8000000 include include int main() { DDRB=0x00; PORTB=0xff; DDRD=0xff; while(1) { if((PINB1)) { PORTD=1; } else { PORTD=0; } } } Chương trình chính sẽ cấu hình PORTB làm đầu vào, PORTD làm đầu ra. DDRB=0x00 và PORTB=0xff sẽ cho phép trở treo nội tại PORTB vì vậy bình thường giá trị tại chân nối với nút bấm luôn là 1, khi ta ấn phím lúc này chân nút bấm được nối GND và có giá trị 0. Để đọc trạng thái cổng B ta dùng thanh ghi PINB. Atmega8 có 3 bộ định thờibộ đếm (TimerCounter): Chúng có thể dùng để đếm thời gian, đếm sự kiện xảy ra bên ngoài VĐK, tạo ra các xung điều rộng PWM… Phần này ta sẽ tìm hiểu về TimerCounter 0 (TC 0). TC 0 là bộ đếm định thời 8 bit. Thanh ghi TCNT0 có độ rộng 8 bit. TC0 có thể đếm xung hệ thống (xung hệ thống có thể là thạch anh ngoài hay dao động nội… mà ta đã nói ở phần trước), xung hệ thống sau khi qua bộ chia tần hoặc xung bên ngoài tại chân T0. Ta có thể chọn nguồn xung để đếm thông qua việc cấu hình các thanh ghi điều khiển TC0 (các bit CS2..0 của thanh ghi TCCR0). TCNT0 sẽ tăng lên 1 mỗi khi nhận được 1 xung, sau khi TCNT0 đạt đến 0xff (255) nếu nhận thêm 1 xung nữa nó sẽ trở về 0x00. Đồng thời lúc này cờ TOV0 (bit thứ 0 của thanh ghi TIFR) sẽ được gán bằng 1. Lưu ý là TCNT0 là thanh ghi có thể đọc và ghi vì vậy ta có thể ghi giá trị vào nó bất cứ lúc nào. Sử dụng TC0: Chọn nguồn xung clock: Ta cấu hình chọn nguồn xung clock thông qua việc ghi giá trị vào 3 bit CS02..0 của thanh ghi TCCR0 Ví dụ 1: Tạo ra thời gian trễ 200ms sử dụng TC0: Vì ta sử dụng xung hệ thống là 8MHz nên 1 chu kỳ sẽ là 18MHz=0,125us. Vậy 200ms ta cần đếm 200ms0,125us=1.600.000 xung. TCNT0 là thanh ghi 8 bit nên giá trị lớn nhất là 255: (cộng với 1 chu kỳ đếm từ 255 về 0 là 256). Giá trị 1.600.000 lớn hơn rất nhiều so với 256 vì vậy ta sẽ chọn bộ chia tần là 1024, lúc này ta cần đếm 1.600.000 xung1024=1562,5 xung, lấy chẵn là 1562. Nếu ta khởi tạo TCNT0 bằng 0 thì cứ sau 256 xung TCNT0 sẽ tràn (TOV0=1) vậy sẽ có 1562256=6,1 lấy chẵn là 6 lần tràn. Ta sẽ dùng một biến đếm số lần tràn này, khi biến đạt giá trị 6 là đủ 200ms. Dựa trên phân tích trên ta bắt tay vào viết code: chương trình của chúng ta sẽ nhấp nháy led nối với chân PD0 như ở phần trước đã làm. Ở đây ta tìm hiểu thêm cách làm sao tác động vào từng bit củamộtPORT. Mã lệnh: Mã: define F_CPU 8000000 include include char t; bien dem so lan tran dat 6 la du 200ms void delay(); chuong trinh con delay 200ms int main() { DDRD|=0x01; khoi tao chan PD0 lam dau ra TCCR0=0b101; bo chia tan 1024 PORTD=0b11111110; tat led noi voi chan PD0 khong lam anh huong toi cac chan khac cua PORTD TCNT0=0; while(1) { PORTD=0b11111110; delay(); PORTD|=0b00000001; delay(); } } void delay() { while(1) { Bộ truyền thông nối tiếp trên Atmega8 có thể hoạt động ở nhiều chế độ và ở đây ta chỉ xét chế độ bất đồng bộ. Khởi tạo nguồn clock cho bộ truyền thông, khởi tạo tốc độ Baud. Để khởi tạo tốc độ Baud ta ghi giá trị tương ứng với tốc độ Baud vào thanh ghi UBRR. Liên hệ giữa UBRR và tốc độ Baud cho bởi công thức sau: Ví dụ chúng ta sử dụng xung hệ thống là 3.6864MHz, ta cần dùng tốc độ Baud là 9600 Có 2 trường hợp: nếu ta chọn U2X=0 thì UBRR=3.686.4009600161=23. Nếu ta chọn U2X=1 thì UBRR=3.686.400960081=47. Định dạng khung truyền: ta chỉ xét định dạng khung truyền là 1 bit start, 8 bit dữ liệu, 1 bit stop, không kiểm tra chẵn lẻ. Các thanh ghi cấu hình, điều khiển bộ USART: Thanh ghi UDR: + Để truyền dữ liệu đi thì ta ghi dữ liệu cần truyền vào thanh ghi này và bộ USART sẽ gửi dữ liệu cần truyền đi. + Sau khi nhận đươc dữ liệu thì thanh ghi này sẽ chứa dữ liệu nhận được. Thanh ghi USRCA: Các bit ta quan tâm: + bit 7 RXC: cờ này bằng 1 khi có dữ liệu nhận được và sẽ được xóa thành 0 khi không có dữ liệu trong bộ đệm (UDR). + bit 6 – TXC: cờ này được bật mỗi khi truyền xong dữ liệu. Muốn xóa thì ta ghi giá trị 1 vào bit này. + bit 5 – UDRE: UDRE được set thành 1 khi UDR là rỗng và sẵn sàng cho truyền dữ liệu. Thanh ghi UCSRB: Tạm thời ta quan tâm các bit sau: bit 4 RXEN: cho phép nhận, ghi giá trị 1 vào bit này cho phép USART nhận dữ liệu. bit 3 – TXEN: cho phép truyền dữ liệu, ghi 1 vào bit này cho phép USART truyền dữ liệu. bit 2 – UCSZ2: kết hợp với các bit UCSZ1..0 trong thanh ghi UCSRC để quy định số bit dữ liệu trong 1 khung truyền. Thanh ghi UCSRC: Có cùng địa chỉ với thanh ghi UBRRH: bit 7 – URSEL: xác định truy cập UBRRH hay UCSRC, khi URSEL=1: truy cập UCSRC, khi URSEL=0: truy cập UBRRH. bit 6 – UMSEL: chọn chế độ của USART: =0: truyền bất đồng bộ, =1 truyền đồng bộ. Và chúng ta chỉ tìm hiểu truyền bất đồng bộ. bit 3 – USBS: =1: 2 bit stop; =0: 1 bit stop. bit UCSZ1..0: kết hợp với UCSZ2 ở trên quy định số bit dữ liệu, ta chỉ tìm hiểu kiểu truyền 8 bit dữ liệu UCSZ2=0; UCSZ1=1; UCSZ0=1; Ví dụ về sử dụng USART: Chương trình sẽ bật led và gửi đi ký tự ‘O’ khi nhận được ký tự ‘A’; tắt led và gửi đi ký tự ‘F’ khi nhận được ký tự ‘B’. Để có thể mô phỏng ví dụ này ta cần sử dụng thêm một phần mềm tạo cổng COM ảo đó là VSPE và Terminal VSPE bạn tải tại đây: Eterlogic VSPE: tool for serial ports emulation Terminal bạn tải tại đây: Terminal Sử dụng VSPE và Terminal: Truyền nhận dữ liệu giữ 8951 và pc | Cộng đồng cơ điện tử Việt Nam | Mechatronics Mã lệnh: Mã: define F_CPU 3686400 include include unsigned char c; void uart_char_tx(char cData) { while(bit_is_clear(UCSRA, UDRE)); UDR=cData; while(bit_is_clear(UCSRA, TXC)); UCSRA|=1

Ngày đăng: 27/05/2016, 13:40

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan