Store and share experiences about robocon, IoT, Embedded...
  • Home
  • Linux
  • Window
    • Latex
    • Matlab
  • Embedded programming
    • Jetson Tx1
    • Raspberry Pi
    • Raspberry Pico
  • Internet of things
    • HTTP+MySQL cho IoT
    • Websocket+Nodejs
    • ESP32
  • Electronics and robots
    • Robocon
    • Arduino
    • RISCV
    • FPGA
  • Network and devices
    • Basic CCNA
  • IoT Server
  • Q&A (Hỏi đáp)
  • About
No Result
View All Result
  • Home
  • Linux
  • Window
    • Latex
    • Matlab
  • Embedded programming
    • Jetson Tx1
    • Raspberry Pi
    • Raspberry Pico
  • Internet of things
    • HTTP+MySQL cho IoT
    • Websocket+Nodejs
    • ESP32
  • Electronics and robots
    • Robocon
    • Arduino
    • RISCV
    • FPGA
  • Network and devices
    • Basic CCNA
  • IoT Server
  • Q&A (Hỏi đáp)
  • About
No Result
View All Result
Store and share experiences about robocon, IoT, Embedded...
No Result
View All Result
Home Điện tử- Robot Robocon

[Robocon cơ bản]- Khai báo cơ bản cho các cổng vào ra trên vi điều khiển AVR Atmega64/128

admin by admin
November 12, 2019
in Robocon
0 0
0

Main contents

  1. Include các thư viện cần thiết
  2. Khai báo output cho các chân điều khiển ( điều khiển Relay, van điện tử, màn hình LCD..)
  3. Khai báo cho việc đọc các giá trị input ( công tắc, nút nhấn, cảm biến dò đường,…)
  4. Khai báo cho điều xung PWM điều khiển mạch cầu H hoặc PID
  5. Khai báo cho ngắt ( đọc Encoder, đọc công tắc hành trình…)

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 Atmega128 “x” là B, C, D, E, G.

          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 (Nguồn: hocavr.com)

Include các thư viện cần thiết

C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
#include <string.h>
 
#include <stdlib.h>
 
#include <avr/io.h>
 
#include <avr/interrupt.h> // sử dụng ngắt
 
#include <util/delay.h>   // sử dụng các hàm delay
 
#include <avr/eeprom.h>  // dùng cho đọc ghi vào eeprom

Khai báo output cho các chân điều khiển ( điều khiển Relay, van điện tử, màn hình LCD..)

– Để khai báo cho 1 port là output ( ví dụ PORTA):

C
1
2
 DDRA=0xFF;
 PORTA=0xFF; // dùng điện trở trong kéo lên, mặc định output mức cao.

– Khai báo macro cho việc điều khiển các chân output: set (lên 1) hoặc clear (xóa về 0)

C
1
2
3
4
5
6
#ifndef cbi
#define cbi(port, bit) (port) &= ~(1 << (bit)) // macro cho clear bit
#endif
#ifndef sbi
#define sbi(port, bit) (port) |= (1 << (bit)) // macro cho set bit
#endif

– Giải thích macro:

          ~(1 << (bit) // ví dụ: ~(1<<3) = ~( 00000001<<3) = ~ (00001000) = 11110111

Trong file avr\include\avr\iom128.h ta có PORTG = _SFR_MEM8(0x65), chính là giá trị của thanh ghi tại địa chỉ 0x65 trong bộ nhớ.

Vì vậy cbi(PORTG, 3) = (gia_tri_thanh_ghi 0x65) &= 11110111 , lúc này bit số 3 của thanh ghi nối trực tiếp với PORTG được ghi vào 0 => Chân số 3 PORTG được đưa về 0.

Ví dụ:

C
1
2
3
4
5
6
7
8
9
10
  int main(void)
          {
          DDRG=0xFF; // thiết lập PORT G là output
          PORTG=0xFF;
          while(1)
                   {
                       cbi(PORTG, 3) // đưa chân số 3 PORTG về 0
                       sbi(PORTG, 1) // đưa chân số 1 PORTG lên 1
                   }
          }

Khai báo cho việc đọc các giá trị input ( công tắc, nút nhấn, cảm biến dò đường,…)

– Để khai báo cho 1 port là input ( ví dụ PORTA):    

C
1
2
DDRA=0;
PORTA=0xFF; // dùng điện trở trong kéo lên để nhận input chính xác.

– Để đọc được giá trị input cần sử dụng một số macro sau:

          #define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))

          Cách hoạt động của macro này như sau:

          Định nghĩa macro bit_is_set được khai báo trong hardware/tools/avr/avr/include/avr/sfr_defs.h

          + Trong đó _BV(bit) là một macro cũng được định nghĩa trong file nêu trên, với ý nghĩa là chuyển giá trị của một chân về dạng 8 bit.

          #define _BV(bit)  (1 << (bit)) 

          // ví dụ _BV(3) thì thực hiện 00000001 << 3 => 00001000=0x08

          + _SFR_BYTE(sfr) là một macro trả về giá trị theo dạng byte của một địa chỉ.

          #define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))

          Trong đó _MMIO_BYTE lại được định nghĩa như sau:

          #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

          Tóm lại, trình biên dịch sẽ thực hiện lệnh sau với _SFR_BYTE(sfr):

          _SFR_BYTE(sfr)   *(volatile uint8_t * uint8_t &(sfr))

Và kết quả nhận được đó là giá trị của thanh ghi có địa chỉ là sfr

(_SFR_BYTE(sfr) & _BV(bit)) sẽ thực hiện thao tác với 1 bít thứ tự là bit với thanh ghi sfr. Kết quả sẽ trả về 1 nếu bit đó bằng 1, trả về 0 nếu bit đó bằng 0.

Ví dụ:

Ta có câu lệnh kiểm tra giá trị input tại chân số 3 của PORTG như sau:

          bit_is_set(PING, 3)

Tương đương với thực hiện lệnh

          (_SFR_BYTE(PING) & _BV(3)) 

          ó (giá trị thanh ghi PING) AND (0x08)

          => Nếu giá trị tại chân 3, PORTG bằng 1, bit_is_set(PING, 3) trả về giá trị khác 0

          => Nếu giá trị tại chân 3, PORTG bằng 0, bit_is_set(PING, 3) trả về giá trị bằng 0

          Với trường hợp macro bit_is_clear tương tự.

          #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

Ứng dụng:

          Đọc nút nhấn, công tắc:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
#define nut_nhan   bit_is_clear(PING,0) // nút nhấn nối với chân số 0 PORTG
#define cong_tac   bit_is_clear(PING,1)// công tắc nối với chân số 1 PORTG
 
          int main(void)
          {
          DDRG=0; // thiết lập PORT G là input
          PORTG=0xFF;
          while(1)
                   {
                             if(nut_nhan) { thuc_hien_lenh;}
                             if(cong_tac) { thuc_hien_lenh;}
                   }         
          }

Khai báo cho điều xung PWM điều khiển mạch cầu H hoặc PID

Timer/Counter là các module độc lập với CPU. Chức năng chính của các bộ Timer/Counter, như tên gọi của chúng, là định thời (tạo ra một khoảng thời gian, đếm thời gian…) và đếm sự kiện. Trên các chip AVR, các bộ Timer/Counter còn có thêm chức năng tạo ra các xung điều rộng PWM (Pulse Width Modulation), ở một số dòng AVR, một số Timer/Counter còn được dùng như các bộ canh chỉnh thời gian (calibration) trong các ứng dụng thời gian thực. Các bộ Timer/Counter được chia theo độ rộng thanh ghi chứa giá trị định thời hay giá trị đếm của chúng, cụ thể trên chip Atmega128 có 2 bộ Timer 8 bit (Timer/Counter0 và Timer/Counter2) và 2 bộ 16 bit (Timer/Counter1 và Timer/Counter3). Chế độ hoạt động và phương pháp điều khiển của từng Timer/Counter cũng không hoàn toàn giống nhau. Ví dụ:

Timer/Counter1: là bộ định thời, đếm đa năng 16 bit. Bộ Timer/Counter này có 5 chế độ hoạt động chính. Ngoài các chức năng thông thường, Timer/Counter1 còn được dùng để tạo ra xung điều rộng PWM dùng cho các mục đích điều khiển. Có thể tạo 2 tín hiệu PWM độc lập trên các chân OC1A (chân 15) và OC1B (chân 16) bằng Timer/Counter1.

Timer/Counter2: tuy là một module 8 bit như Timer/Counter0 nhưng
Timer/Counter2 có đến 4 chế độ hoạt động như Timer/Counter1, ngoài ra nó nó còn được sử dụng như một module canh chỉnh thời gian cho các ứng dụng thời gian thực (chế độ asynchronous). (nguồn hocavr.com)

C
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
//Khai báo cho các cổng điều xung tương ứng với các thanh ghi điều khiển PWM
 
#define Banh_trai  OCR1AL         //PWM 4 onboard
 
#define Banh_phai OCR1BL        //PWM 5 onboard
 
#define Banh_1 OCR1CL             //PWM 6 onboard
 
#define tay_xoay_tr OCR3AL      //PWM 1 onboard
 
#define tay_xoay_ph OCR3BL     //PWM 2 onboard
 
//Khai bao timer 3 cho điều xung các cổng PWM1,2,3 trên board mạch //Atmega128
 
TCCR3A=0; // 0xfd//(WGM13=0, WGM12=0, WGM11=0, WGM10=1) giá tri TOP là 1 hang so, TOP = 255
 
TCCR3B=0; // 0x04// COMA1=COMA0=COMB1=COMB0 // GIA TRI XUNG RA HIGH(COMPARE) LOW(TOP)
 
OCR3AL=0; //pwm1A value => PWM1 onboard
 
OCR3BL=0; //pwm1B value => PWM2 onboard
 
OCR3CL=0; //=> PWM3 onboard
 
//Khai bao timer 1 cho PWM4,5,6 trên board mạch
 
TCCR1A=0xFD; //(WGM13=0, WGM12=0, WGM11=0, WGM10=1) giá tri TOP là 1 hang so, TOP = 255
 
TCCR1B=0x04; // COMA1=COMA0=COMB1=COMB0 => GIA TRI XUNG RA HIGH (COMPARE) LOW(TOP)
 
OCR1AL=0; //pwm1A value => PWM4 onboard
 
OCR1BL=0; //pwm1B value => PWM5 onboard
 
OCR1CL=0; //=> PWM6 onboard

Khai báo cho ngắt ( đọc Encoder, đọc công tắc hành trình…)

Ngắt là gì? Ngắt là một tín hiệu khẩn cấp gửi đến bộ xử lí, yêu cầu bộ xử lí tạm ngừng tức khắc các hoạt động hiện tại để “nhảy” đến một nơi khác thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này gọi là trình phục vụ ngắt – isr (interrupt service routine ). Sau khi kết thúc nhiệm vụ trong isr, bộ đếm chương trình sẽ được trả về giá trị trước đó để bộ xử lí quay về thực hiện tiếp các nhiệm vụ còn dang dở. 

Ví dụ:  Kkhai báo ngắt cho INT6,7 , bắt bất kì thay đổi nào trên chân vi điều khiển

C
1
2
3
4
5
EICRA=0x00; // INT0,1,2,3 không sử dụng
EICRB=0x50; // INT6,7 sử dụng chế độ ngắt bắt bất kì thay đổi nào của cạnh
EIMSK=0xC0; // khai báo cho INT0,1,2,3,4,5 off và INT6,7 on
EIFR=0xC0;  // cho phép cờ ngắt INT 6,7
sei(); // cho phep ngat toan cuc

Các khai báo và ứng dụng này sẽ được sử dụng cụ thể trong bài lập trình dò đường, nên tôi không để code mẫu hoàn chỉnh nào ở đây, nội dung bên trên chỉ dùng tham khảo để các bạn hiểu code hơn cho các bài tới.

Số lượt xem: 1,007
Tags: atmega 128atmega 64avrgpio avrkhai báo gpiokhai báo pwmkhai báo uartmacro avr

Related Posts

[Robocon cơ bản]- Lập trình dò đường cơ bản

[Robocon cơ bản]- Lập trình dò đường cơ bản

February 28, 2023
3.1k
[Robocon cơ bản]- Thiết kế mạch điều khiển cơ bản với AVR Atmega64/128

[Robocon cơ bản] Xử lý nhận nút nhấn, công tắc hành trình cho Robot.

November 18, 2019
1.3k
[Robocon cơ bản]- Thiết kế mạch điều khiển xilanh và role đơn giản với ULN2803

[Robocon cơ bản]- Thiết kế mạch điều khiển xilanh và role đơn giản với ULN2803

February 28, 2023
1.1k

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Bài viết đọc nhiều

IoT Webserver- ESP8266/ESP32 gửi dữ liệu lên Cloud, hiển thị ra trình duyệt web với MySQL và PHP

IoT Webserver- ESP8266/ESP32 gửi dữ liệu lên Cloud, hiển thị ra trình duyệt web với MySQL và PHP

February 9, 2023
17.6k
Điều khiển ESP8266/ESP32 từ xa qua internet, không cần mở Port modem

Điều khiển ESP8266/ESP32 từ xa qua internet, không cần mở Port modem

November 7, 2019
10.7k
ESP32-CAMERA: Cài đặt môi trường Arduino IDE và nạp chương trình

ESP32-CAMERA: Cài đặt môi trường Arduino IDE và nạp chương trình

December 27, 2019
7.3k
IoT webserver- Gửi thông báo bằng email từ ESP8266 không dùng IFTTT

IoT webserver- Gửi thông báo bằng email từ ESP8266 không dùng IFTTT

November 19, 2020
5.7k
Store and share experiences about robocon, IoT, Embedded…

Lưu và chia sẻ những gì đã đọc, đã làm, đã nghiên cứu về vi điều khiển, hệ thống nhúng, internet of things, kiến trúc máy tính và hệ điều hành.

Liên hệ với quản trị viên

Chủ đề

  • Arduino
  • CCNA cơ bản
  • Cisco
  • Điện tử- Robot
  • ESP32
  • FPGA
  • HTTP+MySQL cho IoT
  • IoT Server
  • Jetson Tx1
  • Lập trình nhúng
  • Latex
  • Linux
  • Mạng và thiết bị mạng
  • Raspberry Pi
  • Raspberry Pico
  • RISCV
  • Robocon
  • Web of things
  • Websocket+Nodejs
  • Window
  • WordPress

Quản trị trang

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

© 2019- 2023 luuvachiase.net - Phát triển và quản trị bởi Đỗ Ngọc Tuấn và Nguyễn Văn Tuấn ***Vui lòng ghi rõ nguồn khi trích dẫn bài viết từ Website này. DMCA.com Protection Status

No Result
View All Result
  • Trang chủ
  • Linux
  • Window
  • Lập trình nhúng
    • Jetson Tx1
    • Raspberry Pi
  • Web of things
    • HTTP+MySQL cho IoT
    • Websocket+Nodejs
  • Điện tử- Robot
    • Robocon
    • Arduino
    • RISCV
    • FPGA
  • Mạng và thiết bị mạng
    • CCNA cơ bản
  • IoT Server
  • Giới thiệu
  • Q&A (Hỏi đáp)

© 2019- 2023 luuvachiase.net - Phát triển và quản trị bởi Đỗ Ngọc Tuấn và Nguyễn Văn Tuấn ***Vui lòng ghi rõ nguồn khi trích dẫn bài viết từ Website này. DMCA.com Protection Status

Login to your account below

Forgotten Password?

Fill the forms bellow to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In