1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Hướng dẫn lập trình AVR rất hay

66 3,8K 19
Tài liệu đã được kiểm tra trùng lặp

Đ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

Thông tin cơ bản

Tiêu đề Hướng dẫn lập trình AVR rất hay
Trường học Trường Đại Học Bách Khoa Hà Nội
Chuyên ngành Kỹ Thuật Điện Tử, Lập Trình Vi Xử Lý
Thể loại Sách hướng dẫn
Năm xuất bản 2023
Thành phố Hà Nội
Định dạng
Số trang 66
Dung lượng 2,5 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Hướng dẫn lập trinh AVR hay Vi điều khiển AVR do hãng Atmel sản xuất được gới thiệu lần đầu năm 1996. AVR có rất nhiều dòng khác nhau bao gồm dòng Tiny AVR (như AT tiny 13, AT tiny 22…) có kích thước bộ nhớ nhỏ, ít bộ phận ngoại vi, rồi đến dòng AVR (chẳn hạn AT90S8535, AT90S8515,…) có kích thước bộ nhớ vào loại trung bình và mạnh hơn là dòng Mega (như ATmega32, ATmega128,…) với bộ nhớ có kích thước vài Kbyte đến vài trăm Kb cùng với các bộ ngoại vi đa dạng được tích hợp trên chip, cũng có dòng tích hợp cả bộ LCD trên chip (dòng LCD AVR).[1] Tốc độ của dòng Mega cũng cao hơn so với các dòng khác. Sự khác nhau cơ bản giữa các dòng chính là cấu trúc ngoại vi, còn nhân thì vẫn như nhau. Năm 2008, Atmel lại tiếp tục cho ra đời dòng AVR mới là megaAVR, với những tính năng mạnh mẽ chưa từng có ở các dòng AVR trước đó. Có thể nói XXmegaAVR là dòng MCU 8 bit mạnh mẽ nhất hiện nay.

Trang 1

Mục lục

Mở đầu 2

1 Giới thiệu vi xử lý AVR 3

2 Một số phần mềm, thiết bị hỗ trợ cho việc lập trình AVR 5

2.1 Phần mềm CodeVision 5

2.2 Phần mềm mô phỏng Proteus 5

2.3 Mạch nạp và phần mềm nạp 6

3 Ứng dụng của vi xử lý ATmega16 7

3.1 Điều khiển I/O (In/Out) 7

3.2 Ngắt ngoài (Interrupt) 8

3.3 Timer/Counter 9

3.4 Điều khiển độ rộng xung – PWM 11

3.4.1 Khái niệm độ rộng xung 11

3.4.2 Tạo PWM bằng ATmega16 11

3.5 Chuyển đổi ADC 14

3.6 Giao tiếp USART 16

3.6.1 Các thuật ngữ được dùng trong giao tiếp USART 16

3.6.2 Giao tiếp USART trên ATmega16 17

4 Các bài tập ví dụ 19

4.1 Lập trình điều khiển thiết bị ngoài (Led, động cơ…) 19

4.1.1 Phân tích mạch điện 19

4.1.2 Xây dựng nguyên lý điều khiển 19

4.1.3 Mô phỏng trên Proteus 21

4.1.4 Lập trình cho vi xử lý 22

4.1.5 Chạy thử trên mạch mô phỏng 29

4.2 Lập trình ngắt ngoài (INT) 31

4.2.1 Phân tích mạch điện 31

4.2.2 Nguyên lý điều khiển và xây dựng mạch mô phỏng trên Proteus 31

4.2.3 Lập trình cho vi xử lý 32

4.3 Lập trình Timer/Counter 35

4.3.1 Phân tích, xây dựng nguyên lý điều khiển và mạch mô phỏng 35

4.3.2 Lập trình cho vi xử lý 35

4.4 Điều khiển độ rộng xung PWM 42

4.4.1 Phân tích mạch điện 42

4.4.2 Nguyên lý điều khiển 42

4.4.3 Xây dựng mạch mô phỏng trên Proteus 43

4.4.4 Lập trình cho vi xử lý 43

4.5 Chuyển đổi ADC 46

4.5.1 Phân tích mạch điện 46

4.5.2 Nguyên lý điều khiển và mạch mô phỏng trên Proteus 47

4.5.3 Lập trình cho vi xử lý 49

4.6 Truyền nhận dữ liệu với máy tính 58

4.6.1 Phân tích mạch điện 58

4.6.2 Nguyên lý điều khiển và mạch mô phỏng 58

4.6.3 Lập trình cho vi xử lý 59

Phụ lục 64

Trang 2

Mở đầu

Hiện nay các vi xử lý, hay vi điều khiển (MCU – Micro Controller Unit) đang được sử dụng rộng rãi trong nhiều kĩnh vực như: điều khiển, tự động hóa, đo đạc, truyền thông… So với các phương pháp điều khiển, đo đạc truyền thống (cơ khí, điện tử tương tự…), thì sử dụng vi xử lý có các ưu điểm như: nhỏ gọn, ít tốn năng lượng, thời gian đáp ứng nhanh, có thể lập trình được…

Vi xử lý họ AVR của hãng ATMEL hiện đang được sử dụng tương đối phổ biến Vi xử

lý họ AVR là các vi xử lý lập trình được Sau khi được lập trình, vi xử lý sẽ hoạt động theo thuật toán được viết trong lập trình của người dùng Như vậy người dùng có thể lập trình cho

vi điều khiển hoạt động theo ý đồ của mình để giải quyết một các bài toán (điều khiển, đo đạc…)

Trong lập trình cho vi điều khiển, thường sử dụng ngôn ngữ lập trình C và có liên quan tới cấu trúc của vi xử lý, để người đọc chưa được học về ngôn ngữ lập trình C hoặc cấu trúc

vi xử lý có thể dễ dàng theo dõi, những phần đó sẽ được diễn giải theo cách càng đơn giản càng tốt Như vậy người đọc có thể theo dõi tài liệu mà không thấy quá khó hiểu, tuy nhiên cũng vì thế nên các kiến thức được trình bày không đầy đủ và chỉ ở mức cơ bản nhất, để người đọc có thể nhanh chóng tự lập trình được một số ứng dụng cơ bản với vi điều khiển AVR

Trang 3

1 Giới thiệu vi xử lý AVR

AVR là tên gọi chung các vi xử lý của hãng ATMEL Hãng ATMEL sản xuất các vi xử

lý với các chức năng, khả năng tính toán khác nhau, được đặt tên khác nhau: ATtiny25, ATtiny48…,ATmega8, ATmega16, ATmega128…

Các vi xử lý khác nhau thì khác nhau về dung lượng bộ nhớ ROM, RAM, các khối chức năng, số lượng chân… Trong tài liệu này, các hướng dẫn và ví dụ được viết cho vi xử lý ATmega16 Sơ đồ chân, các khối chức năng và cách sử dụng, đặc tính làm việc… của vi lý được nhà sản xuất ghi trong file “datasheet” kèm theo, có thể tìm trên internet

Hình 2:Sơ đồ chân của Atmega16

Tất cả các chân của ATmega16 được đánh số thứ tự từ 1 đến 40 như hình vẽ, chiều của

vi xử lý được lấy theo đầu lõm hoặc chấm tròn trên vi xử lý

Khi làm việc, các chân của vi điều khiển có hai mức trạng thái là 0 và 1 Trạng thái 0 ứng với mức điện áp 0 V còn trạng thái 1 ứng với mức điện áp +5V

Trang 4

Chức năng của các chân trên vi xử lý ATmega16 như sau:

 Chân 10 – VCC: Là chân cấp nguồn +5V cho vi xử lý

 Chân 11 và 31 – GND: Là hai chân nối với nguồn âm Khi thiết kế mạch, phải nối cả hai chân 11 và 31 với nguồn âm

 Chân 9 – RESET: Bình thường chân 9 ở trạng thái 0, khi cấp điện +5V vào chân RESET, trạng thái của nó từ 0 lên 1, và reset lại toàn bộ hoạt động của vi xử lý, tương đương với việc ngắt nguồn nuôi vi xử lý rồi cấp nguồn lại

 Chân 12 – XTAL1 và 13 – XTAL2: Là hai chân nối với thạch anh Thạch anh là một linh kiện có tác dụng tạo dao động điện, vi xử lý sẽ hoạt động theo các dao động này (ví dụ 4Mhz, 12 Mhz…) Trong một số trường hợp có thể dùng thạch anh được gắn sẵn trong vi xử lý, hai chân XTAL1 và XTAL2 được bỏ trống

 Chân 30 – AVCC: Là chân cấp nguồn cho khối chuyển đổi ADC (Analog to Digital Converter) ACD là một chức năng của vi xử lý, cho phép đo điện áp đặt tại chân 33, 34, …, 40 của vi xử lý Xem thêm mục Chuyển đổi ADC

 Chân 32 – AREF: Điện áp tham chiếu Chân AREF được sử dụng khi cần dùng chức năng ADC của vi điều khiển Khi cần dùng chức năng ADC, người dùng cần đặt vào chân AREF một điện áp, gọi là điện áp tham chiếu Xem thêm mục

Sử dụng ADC

 Các chân 1 … 8: Được nhóm chung thành một “cổng”, gọi là PORT B, từng chân trong Port B được ký hiệu PB0, PB1, …, PB7 ứng với các chân từ 1 đến 8 Các chân này có thể đảm nhiệm các chức năng khác nhau, tùy vào thiết lập của người dùng khi lập trình

 Các chân 14 … 21: Được nhóm chung thành một “cổng”, gọi là PORT D, từng chân trong Port D được ký hiệu PD0, PD1, …, PD7 ứng với các chân từ 14 đến

21 Các chân này có thể đảm nhiệm các chức năng khác nhau, tùy vào thiết lập của người dùng khi lập trình

 Các chân 22 … 29: Được nhóm chung thành một “cổng”, gọi là PORT C, từng chân trong Port C được ký hiệu PC0, PC1, …, PC7 ứng với các chân từ 22 đến

29 Các chân này có thể đảm nhiệm các chức năng khác nhau, tùy vào thiết lập của người dùng khi lập trình

 Các chân 33 … 40: Được nhóm chung thành một “cổng”, gọi là PORT A, từng chân trong Port A được ký hiệu PA0, PA1, …, PA7 ứng với các chân từ 1 đến 8 Các chân này có thể đảm nhiệm các chức năng khác nhau, tùy vào thiết lập của người dùng khi lập trình

Trang 5

2 Một số phần mềm, thiết bị hỗ trợ cho việc lập trình AVR

2.1 Phần mềm CodeVision

Phần mềm CodeVision là phần mềm hỗ trợ lập trình cho vi xử lý AVR bằng ngôn ngữ

C Cách sử dụng cụ thể CodeVision được viết trong các ví dụ trong tài liệu

Hình 3: Giao diện CodeVision

2.2 Phần mềm mô phỏng Proteus

Hình 4: Giao diện Proteus

Proteus là phần mềm mô phỏng mạch điện trên máy tính, có giao diện trực quan, với các linh kiện điện tử được sắp xếp trên màn hình và được nối dây, đặt các thông số để có thể chạy thử mạch điện trên máy tính

Proteus có sẵn rất nhiều các linh kiện điện tử có thể tìm thấy trên thị trường, bao gồm cả các vi xử lý AVR Các lệnh theo ngôn ngữ C sau khi được viết bằng CodeVision có thể được đưa vào Proteus để chạy vi xử lý AVR tương ứng Dùng Proteus ta có thể kiểm tra xem lập trình viết trong CodeVision đã đúng hay chưa, như vậy không cần thiết phải thử trên mạch thật, tiết kiệm thời gian, tiền bạc

Tuy nhiên do là mô phỏng trên máy tính, nên một số phần quan trọng trong mạch thực (nguồn điện, sự tương thích về công suất giữa các phần tử…) không được tính đến, dẫn tới mạch điện mô phỏng chỉ có giá trị tham khảo, kiểm tra nguyên lý hoạt động trước khi tiến hành làm mạch thật

Trang 6

2.3 Mạch nạp và phần mềm nạp

Sau khi thử trên Proteus, và làm một mạch điện thật bên ngoài có vi xử lý AVR, để cho

vi xử lý AVR chạy được những gì đã lập trình, phải nạp chương trình cho nó (gần giống như cài phần mềm cho máy tính), muốn làm điều đó chúng ta cần mạch nạp và phần mềm nạp Mạch nạp là một mạch điện nối giữa vi xử lý và máy tính, còn phầm mềm nạp được cài trên máy tính để điều khiển mạch nạp Sau khi nạp, chương trình chúng ta viết bằng AVRStudio sẽ được nhớ trong bộ nhớ của vi xử lý, và vi xử lý sẽ hoạt động theo như chương trình đó

Tóm tắt 2

 Lập trình bằng ngôn ngữ C cho vi điều khiển AVR bằng phần mềm CodeVision hoặc AVRStudio

 Chạy mô phỏng vi xử lý trên máy tính để kiểm tra bằng phần mềm Proteus

 Nạp chương trình cho vi xử lý bằng mạch nạp và phần mềm Khazama

Trang 7

3 Ứng dụng của vi xử lý ATmega16

Các chức năng cơ bản của vi xử lý ATmega16 sẽ được trình bày trong tài liệu gồm có:

 Chức năng I/O (In/Out)

 Ngắt ngoài (INT – INTerrupt)

 Đếm thời gian (Timer/Counter)

 Điều khiển độ rộng xung (PWM – Pulse Width Module)

 Chuyển đổi ADC (Analog to Digital Converter)

 Truyền nhận dữ liệu với máy tính (USART – Universal Synchronous and Asynchronous serial Receiver and Transmitter)

Còn các chức năng khác của ATmega16 như SPI, … sẽ không được trình bày ở đây

3.1 Điều khiển I/O (In/Out)

Điều khiển I/O, hay còn gọi là điều khiển Vào/Ra, là một chức năng cơ bản nhất của vi

xử lý Chức năng I/O cho phép người lập trình gán trạng thái 0 hoặc 1 (ứng với mức điện áp 0V và +5V tương ứng) cho một hoặc nhiều chân trong các Port A, B, C hoặc D Nói cách khác, người lập trình có thể điều khiển điện áp tại một chân bất kỳ trong số 4 port ở mức 0V hoặc +5V

Với chức năng In/Out, vi xử lý có thể điều khiển bật/tắt trực tiếp hoặc gián tiếp các thiết

bị ngoài như đèn Led, động cơ điện…

Nếu muốn sử dụng một chân nào đó trong số các port A, B, C hoặc D (chẳng hạn như chân PB6), khi lập trình người dùng phải thiết lập chức năng I/O cho chân PB6 Cách thiết lập sẽ được trình bày trong ví dụ Lập trình điều khiển thiết bị ngoài

Tóm tắt 3.1

Dùng chức năng I/O điều khiển trạng thái các chân vi xử lý

Trang 8

3.2 Ngắt ngoài (Interrupt)

Ngắt (Interrupt) trong AVR, bao gồm cả ngắt ngoài, là một tín hiệu khẩn cấp gửi đến bộ

xử lý, yêu cầu bộ xử lý dừng các công việc hiện tại (A) để thực hiện một việc nào đó (B) Sau khi khi kết thúc B, bộ xử lý sẽ quay về làm tiếp việc A đang dang dở Tín hiệu khẩn cấp đó

có thể đến từ bên trong vi xử lý (từ bộ Timer, USART…) hoặc từ bên ngoài (nhấn một nút bấm…)

Ngắt ngoài là loại ngắt duy nhất độc lập với các thiết bị của vi xử lý, vì tín hiệu ngắt đến

từ bên ngoài, ví dụ như khi người dùng bấm một nút bấm ở bên ngoài…

Trên Atmega16 có ba bộ ngắt ngoài, ứng với các chân 16 (PD2), 17 (PD3) và chân 3 (PB2), ký hiệu lần lượt là INT0, INT1 và INT2

Hình sau thể hiện một tín hiệu ngắt tạo ra bằng một button (nút bấm) tới ngắt INT0

Hình 5: Tín hiệu ngắt

Với mạch điện button như hình trên, khi chưa nhấn nút, điện áp đặt trên chân INT0 gần bằng +5V Khi nhấn nút, chân INT0 được nối với GND nên điện áp chân INT0 lúc này là 0V Sau khi nhả nút, điện áp chân INT0 lại trở về +5V

Quá trình điện áp chân INT0 giảm nhanh tử gần +5V xuống 0V gọi là Falling Edge (cạnh xuống), còn quá trình điện áp tăng từ 0V lên +5V gọi là Rising Edge (cạnh lên) Người dùng có thể lập trình cho ngắt INT0 hoạt động khi xảy ra Falling Edge, Rising Edge hoặc cả hai

 Nếu chọn Falling Edge, ngắt xảy ra khi vừa nhấn xong nút

 Nếu chọn Rising Edge, ngắt xảy ra khi nhả xong nút

 Nếu chọn cả Falling Edge và Rising Edge, ngắt sẽ xảy ra 2 lần khi vừa nhấn xong nút và sau khỉ nhả xong nút

Cách kích hoạt chức năng ngắt ngoài INT0, INT1 hoặc INT2 và cách lựa chọn cạnh xuống/cạnh lên được hướng dẫn trong ví dụ Lập trình ngắt ngoài

Ngắt ngoài thường dùng để thực hiện giao tiếp giữa người và vi xử lý (thông qua thao tác nhấn nút), hoặc có thể dùng để đếm sự kiện bên ngoài (ví dụ như số sản phẩm đi qua cảm biến)…

Tóm tắt 3.2

 ATmega16 có 3 ngắt

 Ngắt theo cạnh xuống, cạnh lên hoặc cả hai

Trang 9

3.3 Timer/Counter

Timer/Counter, hay còn gọi là bộ đếm thời gian, bộ định thời… có chức năng đếm, hoặc định ra một khoảng thời gian và cả đếm sự kiện Trên một số vi xử lý, timer/counter còn có thêm chức năng điều chỉnh độ rộng xung (PWM) Trên ATmega16 có 3 bộ timer/counter, gọi tắt là T/C0, T/C1,T/C2

Các bộ T/C hoạt động bằng cách đếm số xung dao động của thạch anh nuôi vi xử lý theo

tỉ lệ (Prescale) 1:1 hoặc 1:8, Thạch anh, như đã nói ở phần 1, tạo ra dao động để vi xử lý hoạt động Mỗi linh kiện thạch anh có một tần số dao động nhất định (ví dụ 4 Mhz, 12Mhz…) Mỗi chu kỳ dao động ứng với một khoảng thời gian Δt nhỏ, bằng cách đếm các dao động này, các bộ T/C có thể định ra các khoảng thời gian khác nhau Ví dụ với thạch anh 1Mhz, thì chu kỳ dao động là:

6 6

1

10 ( ) 1( )1.10

Nếu muốn xác định một khoảng thời gian 1 s 1000m  s, bộ T/C sẽ phải dùng một biến đếm để đếm đủ 1000 lần Các biến đếm đó được đặt tên là TCNT0, TCNT1 hoặc TCNT2 tùy theo bộ T/C0, T/C1, T/C2 tương ứng

Các biến đếm TCNT được lưu trong vi xử lý bằng 8 hoặc 16 bit (bit là các ô nhớ trong vi

xử lý và chỉ có hai trạng thái 0 hoặc 1, tổ hợp của các bit này sẽ tương ứng với giá trị của biến TCNT theo hệ nhị phân) Thường dùng tên gọi T/C 8 bit hoặc T/C 16 bit chính là nói tới

số bit dùng để lưu giá trị của biến TCNT

Vì số bit bị giới hạn, nên khả năng đếm của biến TCNT bị giới hạn (với 8 bit, có thể đếm tối đa từ 0 đến 255), dẫn tới khoảng thời gian xác định được nếu đếm trực tiếp số dao dộng của thạnh anh cũng bị giới hạn

Giải pháp đưa ra là đếm theo tỉ lệ (prescale) đã nói ở trên Thay vì đếm mỗi dao động một lần, nếu đếm theo tỉ lệ, ví dụ 1:8, thì cứ 8 dao động của thạnh anh, T/C mới đếm một lần, tức là giá trị TCNT tăng thêm 1

255 (đủ 125 lần đếm) Khi biến TCNT tới giá trị 255, thì sẽ được reset về giá trị ban đầu để đếm tiếp, đồng thời xảy ra ngắt Do vậy tín hiệu ngắt của T/C là khi biến TCNT tới giá trị cực đại, và ngắt có T/C tạo ra gọi là ngắt trong

Trang 10

Cách chọn tỉ lệ, giá trị ban đầu, giá trị tối đa và các thiết lập liên quan khác của T/C sẽ

được trình bày trong ví dụ Lập trình Timer/Counter

Tóm tắt 3.3

 Timer/Counter (T/C) tạo ngắt trong theo các quãng thời gian định trước

 ATmega16 có 2 T/C 8 bit và 1 T/C 16 bit

 Biến đếm TCNT và tỉ lệ Prescale

Trang 11

3.4 Điều khiển độ rộng xung – PWM

3.4.1 Khái niệm độ rộng xung

Để hiểu khái niệm độ rộng xung, ta xét mạch điện đơn giản sau đây:

Hình 7: Mạch điện ví dụ độ rộng xung

Một động cơ được mắc nối tiếp với một nút bấm như hình vẽ Nếu ta bấm nút, động cơ

sẽ chạy, nhả nút, động cơ sẽ dừng Điện áp giữa hai đầu động cơ có dạng xung như trên hình

7 Nếu nhấn, nhả nút bấm theo chu kỳ, thì điện áp hai đầu động cơ cũng thay đổi theo chu kỳ, lúc này sẽ có khái niệm Time Period và Duty Cycle Duty Cycle là thời gian điện áp ở mức +5V, còn Time Period là chu kỳ của xung, bao gồm Duty Cycle và thời gian điện áp bằng 0V còn lại

Nếu giảm Duty Cycle, thì động cơ chạy chậm lại Ngược lại, nếu tăng Duty Cycle thì động cơ chạy nhanh lên Duty Cycle giảm tối thiểu bằng 0 và tăng tối đa bằng Time Period Điều chỉnh độ rộng xung chính là điều chỉnh Duty Cycle, và đôi khi là cả Time Period

Hình 8: Vị trí các chân có thể dùng để tạo tín hiệu PWM

Trong đó PWM0 do T/C0 tạo ra, PWM1A và PWM1B dó T/C1 tạo ra, PWM2 do T/C2 tạo ra Muốn tạo PWM nào thì ta cần phải thiết lập T/C tương ứng

Trang 12

Để dễ hiểu hãy lấy ví dụ muốn tạo tín hiệu PWM tại chân PD4 (PWM1B), ta phải dùng T/C1 và thiết lập cho T/C1 ở chế độ tạo PWM T/C1 là timer/counter 16 bit, do đó biến TCNT1 có thể đếm tới giá trị MAX là 65535

Ý tưởng ở đây là biến TCNT1 chạy từ 0 tới giá trị OCR1B, sau đó chạy tiếp tới giá trị ICR1 Trong đó OCR1B là một giá trị do người dùng đặt trước ứng với khoảng thời gian Duty Cycle Giá trị ICR1 cũng là một giá trị do người dùng đặt trước nhưng ứng với Time Period Như vậy khi biến TCNT1 chạy từ 0 qua OCR1B tới ICR1, điện áp trên chân OC1B sẽ thay đổi theo Duty Cycle và Time Period tương ứng

T/C1 có 3 chế độ hoạt động để tạo PWM là:

 Fast PWM (PWM tần số cao)

 Phase correct PWM (PWM với pha chính xác)

 Phase correct and frequency correct PWM (PWM với pha và tần số chính xác)

Ba chế độ trên khác nhau ở cách tính Duty Cycle và sai số điều khiển Trong tài liệu này

sẽ giới thiệu hai chế độ thông dụng nhất là Fast PWM

Ở chế độ Fast PWM biến TCNT1 đếm xung thạch anh theo tỉ lệ Prescale định trước, chạy từ 0 tới OCR1B, lúc này điện áp trên chân OC1B là +5V Khi TCNT1 chạy từ OCR1B tới ICR1, điện áp chân OC1B là 0V Đồng thời khi TCNT1 chạm mốc ICR1, biến TCNT1 được reset về 0 để tiếp tục đếm cho chu kỳ tiếp theo

Như vậy thời gian biến TCNT1 chạy từ 0 tới OCR1B ứng với Duty Cycle, thời gian biến TCNT1 chạy từ 0 tới ICR1 ứng với Time Period

Trang 13

Chẳng hạn muốn tạo một xung PWM có Time Period là 2ms, Duty Cycle là 1 ms với thạch anh 4 Mhz, tỉ lệ Prescale = 8, ta có:

Mỗi dao động thạch anh ứng với khoảng thời gian là:

Tương tự, để tạo được Duty Cycle của PWM là 1 ms, thì giá trị OCR1B = 500

Thông thường khi lập trình, người ta cố định giá trị ICR1 ngay từ đầu (Time Period cố định), còn giá trị OCR1B được thay đổi khi vi xử lý hoạt động, nhằm tạo ra PWM có Duty Cycle thay đổi

Cách kích hoạt chế độ Fast PWM, chọn các giá trị OCR1B, ICR1 và các thông số khác

sẽ được trình bày trong ví dụ Điều khiển độ rộng xung PWM

Tóm tắt 3.4

 PWM tạo ra do bộ T/C, ATmega16 có 4 kênh PWM (tại chân OC0; OC1A; OC1B; OC2)

 PWM dùng điều chỉnh tốc độ động cơ, động cơ bước và động cơ servo

 Tạo PWM nhờ biến TCNT và các giá trị OCR và ICR Điều chỉnh độ rộng xung bằng cách điều chỉnh giá trị OCR

Trang 14

3.5 Chuyển đổi ADC

Trong các ứng dụng đo lường và điều khiển bằng vi xử lý, bộ chuyển đổi tương tự-số (ADC) là một thành phần rất quan trọng Các đại lượng vật lý như nhiệt độ, áp suất, dòng điện,… đều có thể dùng cảm biến và các mạch xử lý để chuyển về dạng tín hiệu điện áp Trên

vi xử lý ATmega16, có thể đo 8 điện áp khác nhau đặt trên các 8 chân thuộc PORT A, gọi là

8 kênh ADC, được ký hiệu là ADC0, …, ADC7 Điện áp cấp cho bộ chuyển đổi ADC là +5V

và được cấp qua chân AVCC

Hình 10: 8 kênh ADC của ATmega16

Điện áp đặt tại một trong số các kênh ADC, ví dụ ADC0, sẽ được bộ chuyển đổi ADC của ATmega16 đo và trả lại một giá trị tương ứng Để hiểu rõ hơn về hoạt động của ADC ta cần hiểu một số khái niệm sau:

Điện áp tham chiếu - V ref : Là giá trị lớn nhất mà bộ ADC có thể đo được Trong đo đạc

truyền thống, với các thiết bị đo, chúng ta cũng gặp khái niệm “giá trị lớn nhất mà thiết bị có thể đo được” Ví dụ như một đồng hồ đo áp suất có thể đo được tối đa 70 bar, có nghĩa là đồng hồ này chỉ dùng để đo áp suất nhỏ hơn 70 bar

Với ADC trên ATmega16, Vref (điện áp tham chiếu) được người lập trình đặt trước khi kích hoạt chức năng ADC Có 3 cách chọn điện áp tham chiếu như sau:

 Chọn điện áp so sánh bằng điện áp trên chân VREF

 Chọn điện áp so sánh bằng +5V, nối chân VREF với chân AVCC

 Chọn điện áp tham chiếu nội – Vref = 2,56 V Điện áp tham chiếu nội này được tạo ra bên trong vi xử lý, người dùng không cần cấp điện áp qua chân VREF

Độ phân giải: Cho biết mức độ chính xác của phép đo bằng chuyển đổi ADC, cũng là số

bit dùng để chứa giá trị đầu ra của bộ chuyển đổi ADC Chuyển đổi ADC trên ATmega16 là

bộ ADC 10 bit, giá trị bộ ADC trả về sau khi đo có giá trị từ 0 đến 1023, ứng với 1023 khoảng chia

Hoạt động của ADC có thể giải thích đơn giản như sau, đầu tiên vi xử lý chia nhỏ điện

áp tham chiếu Vref làm 1023 khoảng, sau đó so sánh giá trị điện áp đặt tại chân đầu vào ADC xem điện áp cần đo đó nằm ở khoảng bao nhiêu Giá trị ADC đo được chính là số thứ tự của khoảng điện áp tương ứng

Hình 11: Hoạt động của ADC

Trang 15

Như hình trên, Vref được chia làm 1023 khoảng, từ 0 đến 1023 Điện áp cần đo Vin đặt vào chân ADC0, sau khi đo, bộ ADC sẽ trả về giá trị i, là khoảng điện áp ứng với Vin Như vậy giá trị điện áp Vin cần đo là:

ef1023

Các cách kích hoạt bộ chuyển đổi ADC, chọn kênh đo, điện áp tham chiếu và đo bằng ADC sẽ được trình bày trong ví dụ Chuyển đôi ADC

Trang 16

3.6 Giao tiếp USART

USART được trình bày trong tài liệu này là một chuẩn truyền thông nối tiếp không đồng

bộ giữa các thiết bị digital Chức năng USART trên vi xử lý ATmega16 là một trong số các chức năng vi xử lý dùng để truyền/nhận dữ liệu với các thiết bị khác (máy tính, vi xử lý khác…)

3.6.1 Các thuật ngữ được dùng trong giao tiếp USART

Truyền thông nối tiếp không đồng bộ: Trong nhiều bài toán cần sử dụng vi xử lý và

máy tính kết nối với nhau Trong quá trình làm việc đó vi xử lý cần trao đổi dữ liệu với máy tính, ví dụ như vi xử lý gửi giá trị đo đạc bằng ADC về máy tính và máy tính gửi tín hiệu điều khiển xuống vi xử lý…

Giả sử dữ liệu cần trao đổi là các mã có chiều dài 8 bit, cách đơn giản nhất là kết nối 1 PORT (8 bit) của vi điều khiển với máy tính, mỗi dây nối sẽ chịu trách nhiệm truyền/nhận 1 bit dữ liệu Đây gọi là cách giao tiếp song song, cách này là cách đơn giản nhất, nhưng nhược điểm của cách truyền này là số đường truyền quá nhiều, giá trị càng lớn thì số đường truyền cũng sẽ nhiều thêm

Trong truyền thông nối tiếp dữ liệu được truyền từng bit trên 1 (hoặc một ít) đường truyền, vì thế tiết kiệm đường truyền dữ liệu Hình sau mô tả sự so sánh giữa 2 cách truyền song song và nối tiếp trong việc truyền con số 187 thập phân (tức 10111011 nhị phân)

Hình 12: Phương pháp truyền song song (a) và nối tiếp (b)

Vì dữ liệu cần được “chia nhỏ” thành từng bit khi truyền/nhận, tốc độ truyền nối tiếp sẽ

bị giảm Mặt khác, để đảm bảo tính chính xác của dữ liệu, bộ truyền và bộ nhận cần có những

“thỏa hiệp” hay những tiêu chuẩn nhất định

Khái niệm “đồng bộ” để chỉ sự “báo trước” trong quá trình truyền Lấy ví dụ thiết bị 1 (tb1) kết với với thiết bị 2 (tb2) bởi 2 đường, một đường dữ liệu và 1 đường xung nhịp Cứ mỗi lần tb1 muốn gửi 1 bit dữ liệu, tb1 điều khiển đường xung nhịp chuyển từ mức thấp lên mức cao báo cho tb2 sẵn sàng nhận một bit Bằng cách “báo trước” này tất cả các bit dữ liệu

có thể truyền/nhận dễ dàng với ít “rủi ro” trong quá trình truyền Tuy nhiên, cách truyền này đòi hỏi ít nhất 2 đường truyền cho 1 quá trình (gửi hoặc nhận dữ liệu)

Khác với cách truyền đồng bộ, truyền thông “không đồng bộ” chỉ cần một đường truyền cho một quá trình “Khung dữ liệu” đã được chuẩn hóa bởi các thiết bị nên không cần đường xung nhịp báo trước dữ liệu đến Ví dụ 2 thiết bị đang giao tiếp với nhau theo phương pháp này, chúng đã được thỏa thuận với nhau rằng cứ 1ms thì sẽ có 1 bit dữ liệu truyền đến, như thế thiết bị nhận chỉ cần kiểm tra và đọc đường truyền mỗi mili-giây để đọc các bit dữ liệu và sau đó kết hợp chúng lại thành dữ liệu có ý nghĩa Truyền thông nối tiếp không đồng bộ vì thế hiệu quả hơn truyền thông đồng bộ (không cần nhiều đường truyền) Tuy nhiên, để quá trình truyền thành công thì việc tuân thủ các tiêu chuẩn truyền là hết sức quan trọng

Baud rate (tốc độ Baud): như trong ví dụ trên về việc truyền 1 bit trong 1ms, bạn thấy

rằng để việc truyền và nhận không đồng bộ xảy ra thành công thì các thiết bị tham gia phải

“thống nhất” nhau về khoảng thời dành cho 1 bit truyền, hay nói cách khác tốc độ truyền phải

Trang 17

được cài đặt như nhau trước, tốc độ này gọi là tốc độ Baud Theo định nghĩa, tốc độ baud là

số bit truyền trong 1 giây Ví dụ nếu tốc độ baud được đặt là 19200 thì thời gian dành cho 1 bit truyền là 1/19200 ~ 52.083us

Frame (khung truyền): Khung truyền bao gồm các quy định về số bit trong mỗi lần

truyền, các bit “báo” như bit Start và bit Stop, các bit kiểm tra như Parity, ngoài ra số lượng các bit trong một data cũng được quy định bởi khung truyền Hình dưới là một ví dụ của một khung truyền theo UART, khung truyền này được bắt đầu bằng một start bit, tiếp theo là 8 bit data, sau đó là 1 bit parity dùng kiểm tra dữ liệu và cuối cùng là 1 bits stop

Hình 13: Khung truyền theo USART

Start: start là bit đầu tiên được truyền trong một frame truyền, bit này có chức năng báo

cho thiết bị nhận biết rằng có một gói dữ liệu sắp được truyền tới Start là bit bắt buộc phải có trong khung truyền

Data: data hay dữ liệu cần truyền là thông tin chính mà chúng ta cần gửi và nhận

Thường data gồm 8 bit

Parity bit: parity là bit dùng kiểm tra dữ liệu truyền đúng không (một cách tương đối)

Parity bit không phải là bit bắt buộc và vì thế chúng ta có thể loại bit này khỏi khung truyền (các ví dụ trong tài liệu này không dùng bit parity)

Stop bits: stop bits là một hoặc các bit báo cho thiết bị nhận rằng một gói dữ liệu đã

được gởi xong Stop bits là các bits bắt buộc xuất hiện trong khung truyền

3.6.2 Giao tiếp USART trên ATmega16

Vi điều khiển Atmega16 có 1 module truyền thông nối tiếp USART Với chế độ truyền nối tiếp không đồng bộ (cụ thể trong tài liệu này là giao tiếp với máy tính), chúng ta sử dụng

2 chân của Atmega16 để phục vụ cho truyền nhận dữ liệu là: chân truyền dữ liệu – TxD (Transmitted Data) và chân nhận dữ liệu – RxD (Reveived Data)

Hình 14: Hai chân RXD và TXD dùng trong giao tiếp với máy tính

Mô-đun USART trên chip Atmega16 hoạt động theo chế độ quá trình truyền và nhận dữ liệu có thể xảy ra đồng thời

Khi sử dụng USART để giao tiếp với máy tính, phải thiết lập các thông số hoạt động ở vi

xử lý và trên máy tính giống nhau, bao gồm:

Trang 18

 Baud rate: Baud rate càng cao, tốc độ truyền càng nhanh, tuy nhiên xác suất xảy

ra lỗi trong quá trình truyền/nhận cũng lớn hơn Thường chọn Baud rate = 9600 với các ứng dụng không đòi hỏi tốc độ cao

 Frame: Khung truyền bao gồm start bit, data, parity bit và stop bit, trong đó start bit là cố định và không thay đổi Ví dụ trong tài liệu này sẽ lấy khung truyền có 8 bit data, không dùng parity bit và 1 bit stop

USART của ATmega16 cũng có tính năng ngắt Ngắt của USART xảy ra khi hoàn tất gửi xong một dữ liệu, hoặc nhận xong một dữ liệu Tính năng ngắt khi nhận xong một dữ liệu

sẽ được dùng trong ứng dụng truyền dữ liệu từ vi xử lý về máy tính

Cách kích hoạt mô-đun USART, thiết lập các thông số Baud rate, Frame… và cách sử dụng USART sẽ được trình bày trong ví dụ Giao tiếp USART

Tóm tắt 3.6

 Kết nối với máy tính dùng chức năng USART

 Baud rate = 9600; khung truyền có 8 bit data, 1 bit stop, không dùng

parity

 Ngắt khi truyền/nhận dữ liệu hoàn tất

Trang 19

4 Các bài tập ví dụ

Tất cả các mạch điện sử dụng vi xử lý lập trình được đều được thiết kế theo trình tự:

 Phân tích mạch: Yêu cầu, đặc điểm làm việc, …

 Xây dựng nguyên lý điều khiển

sơ đồ nguyên lý và sơ đồ đi dây kèm theo

4.1 Lập trình điều khiển thiết bị ngoài (Led, động cơ…)

Đây là ví dụ đầu tiên và đơn giản nhất trong các ví dụ ứng dụng vi xử lý, vì vậy sẽ được viết kỹ từng bước và giải thích thật đơn giản

Bài ví dụ “Lập trình điều khiển thiết bị ngoài” đang nói tới thực ra là điều khiển ngắt các thiết bị ngoài (đèn Led, động cơ…) thay cho công-tắc điện, và là dạng điều khiển đơn giản nhất trong các ứng dụng của vi điều khiển

đóng-Mạch điện trong ví dụ này sẽ làm việc như sau: Điều khiển đèn Led sáng/tắt theo chu kỳ 0,5 giây

4.1.1 Phân tích mạch điện

Với bất cứ một dự án (Project) thiết kế mạch điện nào, công việc đầu tiên cũng đều là phân tích mạch điện cần thiết kế Dựa vào yêu cầu và đặc điểm làm việc, chúng ta có thể xây dựng được nguyên lý làm việc của các khối cơ bản của mạch (khối điều khiển, khối công suất…) và lập trình cho vi xử lý

Với ví dụ điều khiển Led như trên, yêu cầu và đặc điểm làm việc như sau:

 Led sáng rồi tắt theo chu kỳ 0,5 giây

 Giữa các lần sáng/tắt của Led, không điều khiển thêm thiết bị nào khác

 Led có công suất bé (cỡ 0,1 W)

4.1.2 Xây dựng nguyên lý điều khiển

Như ở phần 1 đã nói, người dùng có thể lập trình để điều khiển điện áp tại một hay một

số chân của vi điều khiển Có hai mức điện áp là 0V và +5V, và được gán với trạng thái 0 và

1 tương ứng Ví dụ chân số 6 (PB5) của vi điều khiển ở trạng thái 1, tức là tại chân đó có điện

áp +5V, còn nếu ở trạng thái 0, tức là tại chân đó có điện áp bằng 0 (nối đất – GND)

Ý tưởng đưa ra là ta có thể dùng điện áp này để chạy một thiết bị nào đó nối trực tiếp với chân của vi điều khiển Tuy nhiên với điện áp +5V, đồng thời dòng điện cho phép nhỏ (vài chục mA), nên ta chỉ có thể nối trực tiếp vào vi điều khiển những thiết bị có công suất rất nhỏ, ví dụ như: đèn LED

Trang 20

Hình 15: Nối trực tiếp vi xử lý với thiết bị có công suất nhỏ

Thực tế, để có thể điều khiển những thiết bị có công suất lớn hơn (hoặc làm cho Led sáng hơn), người ta không nối trực tiếp vi điều khiển với thiết bị, mà qua một mạch công suất Có thể hiểu mạch công suất như một rơ-le trong mạch điện dân dụng

Hình 16: Sơ đồ dùng điện thế 5V công suất nhỏ để điều khiển Mo-tơ 12V công suất lớn

Có nhiều linh kiện điện tử có thể thay thế cho một rơ-le, điển hình là các transistor Hình sau thể hiện nguyên lý hoạt động của mạch:

Hình 17: Vi xử lý điều khiển đóng/mở transistor để điều khiển tải

Một mạch tương tự như mạch transistor trình bày ở trên được gọi là mạch công suất, còn khối vi xử lý được gọi là mạch điều khiển

Bình thường khi chân 6 của vi điều khiển (nối với chân B của transistor) ở trạng thái 0 (0V), thì transistor đóng, tức là E và C không thông nhau

Khi vi điều khiển chuyển trạng thái chân 6 sang 1 (+5V), transistor mở, tức là dòng điện

từ nguồn có thể chạy từ E sang C, qua tải rồi về âm

Như vậy thay đổi trạng thái chân 6 sẽ điều khiển bật/tắt được Led

Trang 21

4.1.3 Mô phỏng trên Proteus

Mô phỏng trên Proteus tức là xây dựng mạch nguyên lý và chạy thử nghiệm trên máy tính bằng phần mềm Proteus

Trình tự tiến hành mô phỏng mạch nguyên lý đóng/mở transistor bằng Proteus như sau:

Hình 18: Mở thư viện Proteus

Mở phần mềm Proteus, click vào các biểu tượng “1” và “2” để chọn lịnh kiện Sau khi click vào “2”, một của sổ mới sẽ hiện ra, cho phép chọn linh kiện

Hình 19: Thư viện Proteus

Gõ tên linh kiện vào ô Keywords, ví dụ “mega16”, các linh kiện tìm được sẽ hiện bên ô Result, click chuột để chọn linh kiên ATMEGA16 như trên hình 2

Gõ tiếp “npn” để tìm linh kiện transistor loại PNP, gõ “led” để tìm linh kiện LED Sau

đó sắp xếp và nối dây cho các linh kiện như trong hình 3

Trang 22

Hình 20: Mạch mô phỏng ví dụ Điều khiển thiết bị ngoài

4.1.4 Lập trình cho vi xử lý

Lập trình chi vi xử lý AVR, cũng như với các vi xử lý khác, nên tiến hành theo các bước như sau, để tạo thuận lợi trong việc xây dựng thuật toán, kiểm tra và sửa lỗi lập trình

 Xác định yêu cầu làm việc của vi xử lý

 Xây dựng thuật toán điều khiển

 Chuẩn bị lập trình và viết chương trình điều khiển

 Kiểm tra và sửa lỗi

a) Xác định yêu cầu làm việc của vi xử lý

Trong ví dụ này, vi xử lý chỉ cần điều khiển trạng thái của chân số 6 của vi xử lý (có ký hiệu PB5/MOSI trên Proteus) thay đổi giữ mức 0 (0V) và 1 (+5V) theo chu kỳ 0,5 giây

b) Xây dựng thuật toán điều khiển

Thuật toán điều khiển ở trong bài ví dụ này khá đơn giản, theo sơ đồ sau:

Hình 21: Sơ đồ thuật toán điều khiển vi xử lý

Sơ đồ được giải thích như sau:

 Khi được cấp điện, vi xử lý chuẩn bị cho bước “Bắt đầu”, bao gồm thiết lập chân PB5 (ứng với chân số 6 của vi xử lý) là chân điều khiển, có trạng thái ban đầu là

Trang 23

c) Chuẩn bị lập trình bằng phần mềm CodeVision

Mở phần mềm CodeVision, nhấn Ctrl+N để tạo Project (dự án) mới, trong hộp thoại

“Create New File” chọn “Project” rồi nhấn “OK”  “Yes”

Hình 22: Tạo project mới

Hình 23: Sử dụng CodeWizardAVR

Hộp thoại “CodeWizardAVR” hiện ra, chọn tên chip là ATmega16, và chọn tần số hoạt động của chip (ví dụ 4000000 Hz = 4Mhz)

Hình 24: Chọn vi xứ lý và tần số hoạt động

Hộp thoại “CodeWizardAVR còn có nhiểu mục khác, ứng với các chức năng của vi xử

lý như USART, ADC, External IRQ (ngắt) đã nói trong phần giới thiệu Nhưng nếu chỉ cần điều khiển trạng thái các chân của vi xử lý, ta chỉ cần vào mục Ports để quy định chức năng vào/ra của chân vi xử lý

Trang 24

Hình 25: Thiết lập các Port

Trên Proteus chúng ta muốn dùng chân số 6 của vi xử lý, có ký hiệu PB5, tức là chân ứng với Bit 5 của Port B, vì vậy chúng ta set Bit 5 thành “Out” như trên hình

Sau khi thiết lập ban đầu cho Atmega16 xong, click “File”  “Generate, Save and Exit”

Hình 26: Tạo và lưu project

Sau đó sẽ có 3 hộp thoại hiện ra để lưu các file cần thiết Đặt tên và lưu các file đó vào cùng một thư mục như trong hình

Trang 25

Hình 27: Chọn thư mục lưu project

Sau khi lưu xong ta sẽ thấy một ô để viết các lệnh lập trình theo ngôn ngữ C Các dòng lệnh chúng ta viết sẽ được lưu trong file “bai1.c”

Hình 28: Nơi viết các dòng lệnh

d) Viết chương trình điều khiển

Khi mới tạo ra file bai1.c đã được ghi rất nhiều dòng lệnh, do phần mềm tự tạo ra theo các thiết lập ở phần “CodeWizardAVR” chúng ta vừa làm Tuy nhiên với bài này, chúng ta chỉ cần theo tác ở một vài vị trí trong file “bai1.c” Trình tự tiến hành được trình bày như sau: Include các file header: Viết thêm dòng lệnh #include <delay.h> vào vị trí như trong hình dưới File delay.h là một file có sẵn của phần mềm Codevision, dùng khi muốn delay (trì hoãn, tạm dừng) quá trình làm việc của vi xử lý trong một khoảng thời gian định trước, trong ví dụ ta dùng để tạm dừng 0,5 s

Trang 26

Hình 29: “Include” các file *.h cần thiết

CodeVision có nhiều file *.h khác nhau (h là viết tắt của header), mỗi file *.h đó được tạo sẵn cho các ứng dụng của vi xử lý Tên một số file *.h và chức năng của các file đó được cho như bảng

Tên file Chức năng liên quan delay.h Tạm dừng vi xử lý

stdio.h Giao tiếp với máy tính

LCD.h Ghi các ký tự ra LCD Một số file *.h và chức năng liên quan

Khi muốn sử dụng tính năng nào có liên quan, thì ta thêm dòng lệnh

#include <*.h>

vào vị trí đã nói ở trên

Vòng lặp while chính: Trong file bai1.c vừa tạo ra cũng đã có sẵn một vòng lặp while liên tục (vòng lặp while chính), đây là nơi viết các dòng lệnh (code) cho bài tập Điều khiển thiết bị ngoài

Hình 30: Vòng lặp while liên tục được tạo sẵn

Các dòng chữ sau ký hiệu “//” chỉ có ý nghĩa chú thích, không ảnh hưởng tới lập trình

Vòng lặp while có cú pháp:

while (x) {

Các dòng lệnh

}

Trong đó x gọi biến logic (chỉ nhận giá trị đúng hoặc sai tương ứng với 1 hoặc 0), vòng

lặp while có nghĩa là chừng nào biến x có giá trị đúng, vi xử lý sẽ thực hiện lặp đi lặp lại các

dòng lệnh viết trong vòng lặp

Trang 27

Như trên hình ta thấy while (1), có nghĩa là x luôn bằng 1, và vòng lặp này xảy ra

mãi trong suốt quá trình hoạt động có vi xử lý

Nhắc lại thuật toán điều khiển đơn giản đã được trình bày ở trên:

Hình 31: Thuật toán điều khiển đơn giản cho ví dụ

Quá trình lặp đi lặp lại các bước trên hình có thể được thực hiện bằng một vòng lặp while, ở đây ta dùng vòng lặp while mà phân mềm Code vision đã tạo sẵn

Như vậy có thể hình dung các lệnh trong vòng lặp while chính như sau:

- Đưa trạng thái (set trạng thái) chân PB5 về 1 hoặc 0:

Với phần mềm CodeVision, có thể set trạng thái cho các chân bằng lệnh:

PORTx.y = z;

Trong đó: x là tên PORT tường ứng, ví dụ chân PB5 thì x là B

Y là thứ tự chân (từ 0 đến 7), ví chân PB5 thì y là 5

Z là trạng thái muốn set, ví dụ 0 hoặc 1

Như vậy để set trạng thái chân PB5 lên 1, ta dùng lệnh:

Trong đó x là số ms hoặc µs tương ứng ta muốn chương trình đợi Trong ví dụ

ta muốn dừng chương trình trong khoảng thời gian là 0,5 s = 500 ms = 500 000 µs, thì dùng lệnh sau:

Trang 28

while (1) {

Hình 32: Đoạn code trong vòng lặp while

e) Kiểm tra lỗi cú pháp và complie

Sau khi viết hết các code, nhấn CTRL+F9 để tiến hành complie (biên dịch từ ngôn ngữ

C sang ngôn ngữ máy), phần mềm CodeVision sẽ tiến hành kiểm tra các lỗi cú pháp, cũng như các thủ tục khác được viết trong file “bai1.c” Nếu không có sai sót, phần mềm sẽ tạo ra file “bai1.hex” lưu trong thư mục “/bai1/exe/” File này sẽ dùng để chạy mô phỏng trên Proteus và nạp cho vi xứ lý khi làm mạch thật

Nếu có lỗi cú pháp hoặc các thủ tục khác trong quá trình lập trình, CodeVision sẽ thông báo có lỗi và có ghi chú lỗi để người lập trình có thể tìm ra và sửa lỗi

Hình 33: Ví dụ về lỗi thiếu dấu “;” ở câu lệnh

Chỉ dẫn báo lỗi tìm thấy sau khi check đến dòng 120, và lỗi thực sự thì nằm ở dòng 119 Quá trình kiểm tra và sửa lỗi cú pháp lặp đi lặp lại tới khi CodeVision thông báo không còn lỗi và tạo file *.hex thành công

Trang 29

4.1.5 Chạy thử trên mạch mô phỏng

Sau khi lập trình và có được file “bai1.hex”, ta tiến hành chạy thử trên mạch mô phỏng Trở lại mạch mô phỏng bằng phần mềm Proteus:

Hình 34: Mạch nguyên lý xây dựng trên Proteus của ví dụ

Click đúp vào biểu tượng vi xử lý ATmega16 trên mạch mô phỏng, hợp thoại Edit Component của ATmega 16 sẽ mở ra:

Hình 35: Hộp thoại Edit Component

Trong hộp thoại Edit Component, ở ô Program File, click chọn đường dẫn tới file bai1.hex vừa tạo ra bằng phần mềm CodeVision Ở ô CKSEL Fuses, chọn tần số cho thạch anh là 4Mhz

Sau khi thiết lập xong, nhấn nút Start ở góc dưới bên trái màn hình để chạy mạch mô phỏng, nếu các bước trên làm chính xác, thì kết quả trên màn hình sẽ thấy đèn Led sáng nhấp nháy theo chu kỳ 0,5s Nếu muốn dừng mô phỏng, nhấn nút Stop

Trang 30

Hình 36: Nút Start và Stop

Quan sát trên màn hình, sẽ thấy màu của chân PB5 nhấp nháy xanh đỏ theo chu kỳ 0,5s Màu đỏ ứng với mức điện áp +5V, màu xanh ứng với mức điện áp 0v Khi chân PB5 màu đỏ thì Led sáng, khi chân PB5 màu xanh thì đèn tắt đúng như nguyên lý điều khiển đã trình bày Như vậy sau bài tập Điều khiển thiết bị ngoài, người đọc có thể tự mở rộng thêm, ví dụ như nháy nhanh rồi nháy chậm theo chu kỳ, điều khiển 2 hay nhiều đèn Led cùng lúc và cho chúng phối hợp sáng/tắt với nhau theo ý muốn, hiển thị trên led 7 thanh, điều khiển bật/tắt động cơ

Tóm tắt 4.1

 Điều khiển thiết bị ngoài qua mạch công suất

 Các theo tác trên các phần mềm Proteus và CodeVision

 Khái niệm delay, lặp…

 Các file header, set trạng thái các chân của vi xử lý

Câu hỏi mở rộng:

 Điều khiển nhiều led bằng nhiều chân của vi điều khiển

 Hiển thị số trên led 7 thanh (cấu tạo và nguyên lý hoạt động của led 7 thanh xem ở phần phụ lục)

Trang 31

Ban đầu khi cấp điện, vi xử lý điều khiển sáng/tắt đèn led theo chu kỳ 0,5s

Khi người dùng nhấn nút điều khiển, chu kỳ sáng/tắt đèn led được điều chỉnh thành 2s Khi người dùng nhấn nút điều khiển lần nữa, chu kỳ sáng/tắt đèn led lại được điều chỉnh

về 0,5s

Như vậy ta thấy về cơ bản, phần lập trình điều khiển sáng/tắt led tương tự như ví dụ Điều

khiển thiết bị ngoài, chỉ khác ở chỗ chu kỳ sáng/tắt (trong hàm delay_ms()) được thay đổi

theo tác động bấm nút của người dùng nhờ tính năng ngát ngoài

4.2.2 Nguyên lý điều khiển và xây dựng mạch mô phỏng trên Proteus

Nguyên lý điều khiển giống như trong bài ví dụ Điều khiển thiết bị ngoài

Mạch mô phỏng trên Proteus cũng tương tự ví dụ Điều khiển thiết bị ngoài, trừ việc có thêm một nút bấm đưa vào chân PD2/INT0 để điều khiển ngắt INT0

Hình 37: Mạch mô phỏng ví dụ Lập trình sử dụng ngắt

Trang 32

4.2.3 Lập trình cho vi xử lý

a) Xác định yêu cầu làm việc của vi xử lý

Vi xử lý điều khiển bật/tắt đèn Led theo chu kỳ 0,5s và 2s theo tác động bấm nút của người dùng

b) Xây dựng thuật toán điều khiển

Thuật toán cho ví dụ được thể hiện trên sơ đồ sau:

Hình 38: Sơ đồ thuật toán ví dụ Lập trình sử dụng ngắt ngoài

Ý tưởng của thuật toán này như sau

Chu kỳ nháy được đặt bằng một biến x, trong chương trình, x hoặc có giá trị 500 (0,5s)

hoặc 2000 (2s)

Khi ngắt ngoài được kích hoạt, chương trình ngắt gán giá trị x = 2000 (nếu giá trị hiện thời của x = 500), hoặc gán giá trị x = 500 (nếu giá trị hiện thời của x = 2000) Chương trình chính sẽ thực hiện điều khiển nháy led với chu kỳ x

Như vậy khi người dùng nhấn nút, sẽ kích hoạt ngắt ngoài, đổi giá trị biến x, đèn led sẽ được điều khiển nhấp nháy theo giá trị biến x tương ứng

Trong ô “Mode”, click chọn “Falling Edge” để chọn chế độ kích hoạt ngắt ở cạnh lên

d) Viết chương trình điều khiển

Trong ví dụ này có sử dụng biến x để đặc trưng cho chế độ làm việc của mạch Biến là

một khái niệm trong lập trình, để chỉ các giá trị số, giá trị logic, chuỗi ký tự, matrận… Biến

có thể có giá trị không đổi hoặc thay đổi trong lập trình tùy thuộc vào cách sử dụng

Trang 33

Mỗi kiểu biến có đặc trưng khác nhau (để chỉ giá trị số, giá trị logic…), muốn sử dụng biến trong lập trình cần phải có bước “khai báo” Bao gồm khai báo tên biến (x, y, bien1, bien2,…) và kiểu dữ liệu(char, str, …) Các kiểu và thuộc tính của kiểu dữ liệu được cho trong bản phần phụ lục

Trong ví dụ này ta khai báo biến x là biến kiểu int (giá trị số nguyên từ -32768 ~

+32767)

Include thêm file header sau: delay.h

Khai báo biến bằng dòng lệnh: char x=500; Ở đây chúng ta gán cho x giá trị x=500 ngay từ đầu, để khi cấp điện, đèn led nhấp nháy ngay với chu kỳ 0,5s

Hình 40: Khai báo biến và nơi viết chương trình ngắt

Viết chương trình phục vụ ngắt ngoài: Trình phục vụ ngắt ngoài được viết tại vị trí như trong hình trên Cấu trúc chương trình ngắt có thể được hình dung như sau:

interrupt [EXT_INT0] void ext_int0_isr(void)

Ký hiệu hai dấu bằng “==” là ký hiệu của phép so sánh, như dòng lệnh trên, giá trị trả về

sẽ bằng 0, vì giá trị hiện thời của x là 2000 khác 500

x == 500 = 0;

Nếu biểu thức so sánh trả về giá trị 1, các dòng lệnh a sẽ được thực hiện, nếu giá trị biểu thức so sánh trả về bằng không, các dòng lệnh B sẽ được thực hiện

Ngày đăng: 27/03/2014, 23:56

HÌNH ẢNH LIÊN QUAN

Hình 1: Vi xử lý ATmega16 - Hướng dẫn lập trình AVR rất hay
Hình 1 Vi xử lý ATmega16 (Trang 3)
Hình 2:Sơ đồ chân của Atmega16 - Hướng dẫn lập trình AVR rất hay
Hình 2 Sơ đồ chân của Atmega16 (Trang 3)
Hình 3: Giao diện CodeVision - Hướng dẫn lập trình AVR rất hay
Hình 3 Giao diện CodeVision (Trang 5)
Hình 25: Thiết lập các Port - Hướng dẫn lập trình AVR rất hay
Hình 25 Thiết lập các Port (Trang 24)
Hình 29: “Include” các file *.h cần thiết - Hướng dẫn lập trình AVR rất hay
Hình 29 “Include” các file *.h cần thiết (Trang 26)
Hình 32: Đoạn code trong vòng lặp while - Hướng dẫn lập trình AVR rất hay
Hình 32 Đoạn code trong vòng lặp while (Trang 28)
Hình 34: Mạch nguyên lý xây dựng trên Proteus của ví dụ - Hướng dẫn lập trình AVR rất hay
Hình 34 Mạch nguyên lý xây dựng trên Proteus của ví dụ (Trang 29)
Hình 35: Hộp thoại Edit Component - Hướng dẫn lập trình AVR rất hay
Hình 35 Hộp thoại Edit Component (Trang 29)
Hình 36: Nút Start và Stop - Hướng dẫn lập trình AVR rất hay
Hình 36 Nút Start và Stop (Trang 30)
Hình 53: Code của ví dụ Timer/Counter - Hướng dẫn lập trình AVR rất hay
Hình 53 Code của ví dụ Timer/Counter (Trang 41)
Hình 55: Mạch nguyên lý điều khiển động cơ DC bằng PWM - Hướng dẫn lập trình AVR rất hay
Hình 55 Mạch nguyên lý điều khiển động cơ DC bằng PWM (Trang 43)
Hình 58: Thiết lập T/C1 tạo PWM - Hướng dẫn lập trình AVR rất hay
Hình 58 Thiết lập T/C1 tạo PWM (Trang 45)
Hình 64: Mạch môp hỏng trên Proteus - Hướng dẫn lập trình AVR rất hay
Hình 64 Mạch môp hỏng trên Proteus (Trang 48)
Hình 67: Kích hoạt chức năng ADC - Hướng dẫn lập trình AVR rất hay
Hình 67 Kích hoạt chức năng ADC (Trang 51)
Hình 84: Thiết lập các thông số USART của trình Terminal giống với trên vi xử lý - Hướng dẫn lập trình AVR rất hay
Hình 84 Thiết lập các thông số USART của trình Terminal giống với trên vi xử lý (Trang 62)

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w