You are currently viewing FRDM-KL46 #5: Cổng GPIO

FRDM-KL46 #5: Cổng GPIO

Trong vi điều khiển, chúng ta có hai loại I/O gồm có:

  • I/O đa chức năng (GPIO: General Purpose I/O): Các cổng GPIO được sử dụng để giao tiếp với các thiết bị ngoại vi thông dụng như đèn LED, công tắc, LCD, bàn phím, v.v.
  • I/O chức năng đặc biệt (Special purpose I/O): Các cổng I/O này có chức năng được chỉ định cho mục đích sử dụng đặc biệt như chuyển đổi tương tự-số ADC (Analog-to-Digital), bộ định thời Timer, truyền thông nối tiếp không đồng bộ UART (Universal Asynchronous Receiver Transmitter), v.v.

Các cổng I/O có chức năng đặc biệt sẽ được trình bày trong một số bài viết khác. Trong bài viết này, chúng ta khảo sát cấu trúc của các cổng GPIO và việc ghép nối nó với các thiết bị ngoại vi đơn giản như đèn LED, phím bấm và bộ hiển thị LED 7-đoạn và chỉ ra cách truy cập chúng bằng các chương trình C.

1.        Các chân I/O trên kit FRDM-KL46Z

Trong các chip ARM của Freescale, các cổng (Port) I/O được đặt tên bằng các chữ cái A, B, C, v.v. Mỗi cổng có thể có tối đa 32 chân (Pin) và chúng được gán tên là PTA0-PTA31, PTB0-PTB31, v.v. Cần lưu ý rằng không phải tất cả 32 chân của mỗi cổng đều được thực hiện. Chip ARM được sử dụng trong bo mạch FRDM là KL46Z256VLL4 thuộc dòng Kinetis L được tích hợp năm cổng là A, B, C, D và E như chỉ ra trong Hình 1‑2. Lưu ý trong Hình 1‑2 rằng với mỗi cổng chỉ có một số chân giới hạn được triển khai. Ví dụ, đối với cổng A chỉ có các chân PTA1-PTA2, PTA4-PTA5 và PTA12-PTA17.

Bố trí các đầu cắm mở rộng (Expand Header) trên kit FRDM-KL46Z

Hình 1 -2. Bố trí các đầu cắm mở rộng (Expand Header) trên kit FRDM-KL46Z

Mỗi chân của chip vi điều khiển ARM của Freescale có thể được sử dụng cho một số chức năng. Ví dụ, một chân cho trước có thể được sử dụng làm đầu I/O số đơn giản (GPIO), đầu vào tương tự hoặc chân I2C… như chỉ ra trong Hình 3‑2. Tất nhiên không phải tất cả các chức năng này được dùng cùng một lúc mà chúng ta phải đảm bảo rằng một chân được gán chỉ một chức năng ngoại vi tại một thời điểm. Chúng ta chọn một chức năng cho một chân bằng cách lập trình một thanh ghi chức năng đặc biệt (SFR: Special Function Register) của vi điều khiển. Kỹ thuật sử dụng một chân đơn cho nhiều chức năng được gọi là hợp kênh chân (pin multiplexing) và được sử dụng rộng rãi trong các bộ vi điều khiển. Điều này là bởi vì nếu không sử dụng hợp kênh chân thì một vi điều khiển có thể cần đến vài trăm chân để hỗ trợ tất cả các tính năng trên chip của nó.

Thanh ghi chức năng đặc biệt PORTx_PCRn (Portx Pin Control Register) (Hình 3‑1) cho phép chúng ta lập trình một chân được sử dụng cho một chức năng nhất định. Cần lưu ý rằng mỗi chân của các cổng A-E có một thanh ghi PORTx_PCRn riêng, trong đó x thay thế cho một trong số các cổng A-E và n được sử dụng cho chân số 0 đến 31. Như đã được đề cập trước đó, mỗi cổng của A-E có thể có tối đa 32 chân và không phải tất cả các chân cho một cổng nhất định đều được thực hiện. Các bit quan trọng nhất của thanh ghi PORTx_PCRn là D10-D8 được dùng làm các bit điều khiển chức năng hợp kênh chân (Mux bits) như chỉ ra trong Hình 3‑2. Sau khi reset, tất cả các cổng từ A đến E bị vô hiệu hóa. Để sử dụng một chân làm đầu GPIO số, chúng ta phải đặt các bit MUX = 001.

Các trường điều khiển của thanh ghi PORTx_PCRn (Chapter 11 của MKL46Z Reference manual)

Hình 3‑1: Các trường điều khiển của thanh ghi PORTx_PCRn (Chapter 11 của [14]).

Hợp kênh nhiều chức năng vào một chân trên KL46Z256-MCU

Hình 3‑2. Hợp kênh nhiều chức năng vào một chân trên KL46Z256-MCU.

Với thanh ghi PORTx_PCRn, chúng ta không chỉ chọn chức năng I/O cho một chân nhất định mà còn có thể điều khiển cưởng độ tải (Drive Strength) và điện trở kéo lên (Pull-up) hoặc kéo xuống (Pull-down) bên trong của chân. Hình 3‑1 và Bảng 3‑1 miêu tả các bit của thanh ghi PORTx_PCRn và chức năng của chúng. Bit #1 (PE, Pull enable) của PORTx_PCRn được sử dụng để bật tùy chọn điện trở kéo bên trong. Nếu PE = 1, thì chúng ta sử dụng bit #0 (PS, Pull Select) để bật tùy chọn điện trở kéo lên hoặc điện trở kéo xuống. Chúng ta cũng có thể kiểm soát khả năng tải (fan-out và fan-in. Xem Phụ lục A) của một chân I/O số với bit #6 (DSE, Drive Strength Enable). Các tùy chọn này được sử dụng phổ biến khi kết nối chân với công tắc hoặc đèn LED. Trong các chương sau, chúng ta sẽ xem cách sử dụng các bit PORTx_PCRn để chọn các chức năng chân khác khi đề cập đến các thiết bị ngoại vi onchip của chip KL46Z.

Bảng 3‑1. Miêu tả các các trường điều khiển của thanh ghi PORTx_PCRn

Bit Trường Miêu tả
0 PS (Pull Select) Nếu trường PE được đặt thì trường này được sử dụng để chọn giữa điện trở treo cao (pull-up resistor) và điện trở kéo xuống (pull-down resistor)

0: pull-down resistor, 1: pull-up resistor

1 PE (Pull Enable) Cho phép điện trở kéo

0: cấm điện sử dụng treo bên trong

1: cho phép sử dụng điện trở treo bên trong

2 SRE (Slew Rate Enable) Cho phép tốc độ quay

0: Tốc độ quay nhanh

1: Tốc độ quay chậm

4 PFE (Passive Filter Enable) Cho phép bộ lọc thụ động

0: Cấm bộ lọc thụ động lối vào

1: Cho phép bộ lọc thụ động lối vào

6 DSE (Drive Strength Enable) Cho phép chọn cưởng độ tải

0: Chọn cường độ tải yếu khi chân được cấu hình là đầu ra

1: Chọn cường độ tải mạnh khi chân được cấu hình là đầu ra

10-8 MUX (Pin Mux Control) Điều khiển chức năng hợp kênh chân

000: chân bị cấm (mạch analog được chọn)

001: Chức năng 1 (GPIO)

010 Chức năng 2 (phụ thuộc vào chip)

011 Chức năng 3 (phụ thuộc vào chip)

100 Chức năng 4 (phụ thuộc vào chip)

101 Chức năng 5 (phụ thuộc vào chip)

110 Chức năng 6 (phụ thuộc vào chip)

111 Chức năng 7 (phụ thuộc vào chip)

19-16 IRQC (Interrupt Configuration) Cấu hình ngắt chỉ dùng cho các chân được thiết lập làm đầu vào số.

0000: Yêu cầu ngắt hoặc DMA bị cấm

0001: Yêu cầu DMA trên sườn tăng

0010: Yêu cầu DMA trên sườn giảm

0011: Yêu cầu DMA trên hai sườn

1000: Ngắt ở mức logic 0

1001: Ngắt ở sườn tăng

1010: Ngắt ở sườn giảm

1011: Ngắt ở cả hai sường

1100: Ngắt ở mức logic 1

Các tổ hợp còn lại: Chưa dùng

24 ISF (Interrupt Status Flag) Cờ trạng thái ngắt

0: Không có ngắt

1: Có ngắt

2.        Mạch cấp clock cho các cổng I/O

Thanh ghi điều khiển cấp xung nhịp hệ thống SIM_SCGC5 (System Clock Gating Control Register 5) được sử dụng để cho phép nguồn xung nhịp được kết nối tới một mạch cổng I/O. Nếu cổng I/O không được sử dụng, nguồn xung nhịp cấp đến cổng có thể bị ngắt để tiết kiệm năng lượng. Chỉ có duy nhất một thanh ghi chức năng đặc biệt SIM_SCGC5 cho tất cả các cổng GPIO và một số bit của thanh ghi này được sử dụng để cho phép cấp nguồn xung nhịp đến các cổng A đến E. Trong trường hợp chip Freescale KL46Z256VLL4, vì chỉ có các cổng từ A đến E, nhiều bit của thanh ghi này không được sử dụng hoặc sử dụng cho các chức năng khác. Chi tiết về chức năng của thanh ghi này có thể tham khảo từ chương 12 của tài liệu tham khảo [14]. Các bit của thanh ghi này cũng được hiển thị trong Hình 3‑3.

Ký hiệu Định dạng Địa chỉ
SIM_SCGC5

SIM→SCGC5

Thanh ghi SIM_SCGC5 (System Clock Gating Control Register 5) của MKL46Z

Note: 0: clock disabled; 1: Clocl enabled

0x4004_8038 + 0x1038

=

0x4004_8038

Hình 3‑3. Thanh ghi SIM_SCGC5 (System Clock Gating Control Register 5).

Trong mô-đun SIM thanh ghi SIM_SCGC5 có địa chỉ offset là 0x1038. Biết địa chỉ cơ sở của mô-đun SIM là 0x4004_7000, do đó địa vật lý của thanh ghi SIM_SCGC5 sẽ là 0x4004_8038. Đây là một thanh ghi rất quan trọng. Không có tín hiệu xung nhịp, cổng sẽ không hoạt động. Mọi quyền truy cập vào các thanh ghi được liên kết với cổng trước khi tín hiệu xung nhịp được cấp sẽ dẫn đến lỗi phần cứng và chương trình gặp sự cố.

Ví dụ 31
Hãy chỉ ra cách để:

a)    Cấp tín hiệu xung nhịp tới cổng PTB

b)    Chọn chức năng GPIO cho các chân PTB18 và PTB19

Đáp án:

a)    Để cho phép cấp tín hiệu xung nhịp tới cổng PTB, chúng ta cần đặt bit D10 của thanh ghi SIM_SCGC5 ở địa chỉ 0x4004_8038 lên ‘1’. Chúng ta có thể thực hiện điều này bằng cách OR thanh ghi SIM_SCGC5 với giá trị 0x400 để đảm bảo không ảnh hưởng tới các bit còn lại.

b)    Để chọn chức năng GPIO cho chân PTB18 và PTB19 chúng ta cần phải ghi giá trị 0x0100 tới các thanh ghi PORTB_PCR18 và PORT_PCR19. Địa chỉ của các thanh ghi này là 0x4004_A048 và 0x4004_A04C (tham khảo chương 11 của [14]).

3.        Khối GPIO

3.1.     Địa chỉ của các khối GPIO

Chi tiết về mô-đun GPIO được trình bày chi tiết trong chương 42 của [14].

Các chip ARM có hai bus: Bus ngoại vi nâng cao APB (viết tắt cửa cụm từ tiếng Anh Advanced Peripheral Bus) và Bus hiệu suất cao nâng cao AHB (Advanced High-Performance Bus). Bus AHB nhanh hơn nhiều so với APB. AHB cho phép truy cập tới các thiết bị ngoại vi trong một chu kỳ xung nhịp. Bus APB chậm hơn và thời gian truy cập của nó tối thiểu là 2 chu kỳ xung nhịp.

Các cổng I/O được ánh xạ tới không gian địa chỉ của giao diện bus APB và AHB như trong Bảng 3‑2. Có nhiều thanh ghi được liên kết với mỗi cổng I/O ở trên và chúng được gán các địa chỉ xác định trong bản đồ bộ nhớ của hệ thống. Lưu ý các địa chỉ trong Bảng 3‑2 là các địa chỉ Cơ sở (Base addresses) có nghĩa là trong địa chỉ cơ sở đó có nhiều thanh ghi được liên kết với cổng đó như chỉ ra trong Hình 3‑4.

Bảng 3‑2. Địa chỉ cơ sở của các cổng I/O trên bus AHB và APB

Cổng GPIO Bus APB Bus AHB
GPIO Port A 0x400F F000 0xF80F F000
GPIO Port B 0x400F F040 0xF80F F040
GPIO Port C 0x400F F080 0xF80F F080
GPIO Port D 0x400F F0C0 0xF80F F00C0
GPIO Port E 0x400F F100 0xF80F F100

Ánh xạ các thanh ghi của các cổng GPIO trong không gian bộ nhớ của MKL46Z

Hình 3‑4. Ánh xạ các thanh ghi của các cổng GPIO trong không gian bộ nhớ.

3.2.     Các thanh ghi bên trong mỗi cổng GPIO

Bảng 3‑3 cho thấy một số thanh ghi liên quan đến PORTA. Sau khi chúng ta cấu hình thanh ghi hướng dữ liệu GPIOA_PDDR để quy định cổng làm đầu ra, chúng ta có thể sử dụng các thanh ghi GPIOA_PDOR, GPIOA_PSOR, GPIOA_PCORGPIOA_PTOR theo thứ tự để xuất dữ liệu ra cổng, đặt (gán giá trị 1) tới cổng, xóa (gán giá trị 0) tới cổng và đảo giá trị hiện tại của cổng. Tương tự, sau khi thanh ghi hướng dữ liệu GPIOA_PDDR được cấu hình để quy định cổng làm đầu vào, thanh ghi GPIOA_PDIR được sử dụng để nhập dữ liệu vào CPU từ các chân. Cần lưu ý rằng các thanh ghi này tồn tại trong tất cả các cổng từ A đến E trong chip Freescale ARM.

Bảng 3‑3. Các thanh ghi GPIO trong cổng PORTA

Địa chỉ Ký hiệu Tên thanh ghi Loại đọc/viết Giá trị sau Reset
0x400F F000 GPIOA_PDOR Port Data Output Register Đọc/Viết 0x00000000
0x400F F004 GPIOA_PSOR Port Set Output register Viết (luôn đọc được giá trị 0) 0x00000000
0x400F F008 GPIOA_PCOR Port Clear Output Register Viết (luôn đọc được giá trị 0) 0x00000000
0x400F F00C GPIOA_PTOR Port Toggle Output Register Viết (luôn đọc được giá trị 0) 0x00000000
0x400F F010 GPIOA_PDIR Port Data Input Register Đọc 0x00000000
0x400F F014 GPIOA_PDDR Port Data Direction Register Đọc/Viết 0x00000000

Nói chung mỗi vi điều khiển có tối thiểu hai loại thanh ghi được liên kết với mỗi cổng I/O, bao gồm các thanh ghi dữ liệu và thanh ghi hướng dữ liệu như chỉ ra trong Hình 3‑5. Thanh ghi hướng dữ liệu được sử dụng để xác định một chân là đầu vào hoặc đầu ra. Trong họ vi điều khiển Kinetis của Freescale, mỗi cổng GPIO có một thanh ghi hướng dữ liệu 32 ký hiệu là GPIOx_PDDR (Port Data Direction Register). Sau khi thanh ghi hướng vào/ra đã được cấu hình đúng thì chúng ta sử dụng các thanh ghi dữ liệu để ghi dữ liệu vào chân hoặc đọc dữ liệu từ chân. Các thanh ghi dữ liệu lại được chia làm 2 loại là thanh ghi dùng để xuất dữ liệu và thanh ghi để đọc dữ liệu. Trong trường hợp vi điều khiển Kinetis của Freescale, mỗi cổng GPIO có bốn thanh ghi 32 bit được dùng để điều khiển việc xuất dữ liệu ra một chân là GPIOx_PDOR (Port Data Output Register), GPIOx_PSOR (Port Set Output Register), GPIOx_PCOR (Port Clear Output Register), GPIOx_PTOR (Port Toggle Output Register). Việc viết tới những thanh ghi này chỉ tác động tới chân tương ứng với các bit được viết giá trị tới. Điều này giúp dễ dàng bật hoặc tắt một hoặc một vài chân mà không ảnh hưởng đến các chân khác. Ví dụ, viết giá trị 4 (có giá trị nhị phân là 0b0100) vào thanh ghi PCOR sẽ xóa mức logic trên chân số 2 của cổng đó về 0 mà không sửa đổi bất kỳ chân nào khác. Ở chiều ngược lại, vi điều khiển dòng Kinetis của Freescale chỉ có một thanh ghi cho nhập dữ liệu từ chân vào trong vi điều khiển ký hiệu là GPIOx_PDIR (Port Data Input Register).

Các thanh ghi dữ iệu và thanh ghi hướng dữ liệu trong cấu trúc một chân I/O của MKL46Z

Hình 3‑5. Các thanh ghi dữ iệu và thanh ghi hướng dữ liệu trong cấu trúc một chân I/O.

a)    Thanh ghi hướng dữ liệu PDDR (Port Data Direction Register)

Trong trường hợp chip ARM Freescale, mỗi bit của thanh ghi hướng dữ liệu cần phải gán giá trị 0 để định cấu hình chân cổng làm đầu vào và giá trị 1 để định cấu hình chân cổng làm đầu ra. Ví dụ, viết giá trị 0x03 (hoặc giá trị nhị phân 0b00000011) vào thanh ghi GPIOA_PDDR dẫn đến các chân 0 và 1 của cổng PORTA trở thành đầu ra dữ liệu trong khi các chân khác trở thành đầu vào dữ liệu. Thanh ghi hướng dữ liệu được đặt tại địa chỉ offset 0x0014 từ địa chỉ cơ sở của cổng đó. Định dạng của thanh ghi này được mô tả trong Hình 3‑6.

Ký hiệu Định dạng Địa chỉ
GPIOx_PDDR

GPIOx→PDDR

Thanh ghi GPIOx_PDDR cuaar MKL46Z

Chú ý: 0: chân được cấu hình làm đầu vào; 1: chân được cấu hình làm đầu ra

Base address + 0x0014 offset

Hình 3‑6. Thanh ghi GPIOx_PDDR.

b)    Thanh ghi xuất dữ liệu GPIO_PDOR (Port Data Output Register)

Khi mô-đun GPIO được cấu hình làm đầu ra dữ liệu thì thanh ghi GPIO_PDOR được dùng để đệm dữ liệu mà vi điều khiển muốn xuất ra bên ngoài. Thanh ghi xuất dữ liệu GPIO_PDOR có độ dịch địa chỉ là 0x0000 so với địa chỉ cơ sở của cổng.

Ký hiệu Định dạng Địa chỉ
GPIOx_PDOR

GPIOx→PDOR

Thanh ghi GPIOx_PDOR (Port Data Output Register). của MKL46Z

Chú ý: 0: xuất mức logic 0 ra chân; 1: xuất mức logic 1 ra chân

Base address + 0x0000 offset

Hình 3‑7. Thanh ghi GPIOx_PDOR (Port Data Output Register).

c)    Thanh ghi đặt dữ liệu lối ra GPIOx_PSOR (Port Set Output Register)

Khi mô-đun GPIO được cấu hình làm đầu ra dữ liệu thì thanh ghi GPIO_PSOR được dùng để vi điều khiển đặt mức logic của một chân lên 1. Thanh ghi GPIO_PSOR có độ dịch địa chỉ là 0x0004 so với địa chỉ cơ sở của cổng.

Ký hiệu Định dạng Địa chỉ
GPIOx_PSOR

GPIOx→PSOR

Thanh ghi GPIOx_PSOR (Port Set Output Register)

Chú ý: 0: mức logic trên chân không thay đổi; 1: mức logic trên chân được đặt bằng 1

Base address + 0x0004 offset

Hình 3‑8. Thanh ghi GPIOx_PSOR (Port Set Output Register).

d)    Thanh ghi xóa dữ liệu lối ra GPIOx_PCOR (Port Clear Output Register)

Khi mô-đun GPIO được cấu hình làm đầu ra dữ liệu thì thanh ghi GPIO_PCOR được dùng để vi điều khiển xóa mức logic của một chân xuống 0. Thanh ghi GPIO_PCOR có độ dịch địa chỉ là 0x0008 so với địa chỉ cơ sở của cổng.

Ký hiệu Định dạng Địa chỉ
GPIOx_PCOR

GPIOx→PCOR

Thanh ghi GPIOx_PCOR (Port Clear Output Register)

Chú ý: 0: mức logic trên chân không thay đổi; 1: mức logic trên chân được xóa về 0

Base address + 0x0008 offset

Hình 3‑9. Thanh ghi GPIOx_PCOR (Port Clear Output Register).

e)    Thanh ghi đảo trạng thái dữ liệu lối ra GPIOx_PTOR (Port Toggle Output Register)

Khi mô-đun GPIO được cấu hình làm đầu ra dữ liệu thì thanh ghi GPIO_PCOR được dùng để vi điều khiển đặt mức logic của một chân tới trạng thái đảo của mức logic hiện tại trên chân. Thanh ghi GPIO_PTOR có độ dịch địa chỉ là 0x000C so với địa chỉ cơ sở của cổng.

Ký hiệu Định dạng Địa chỉ
GPIOx_PTOR

GPIOx→PTOR

Thanh ghi GPIOx_PTOR (Port Toggle Output Register)

Chú ý: 0: mức logic trên chân không thay đổi; 1: mức logic trên chân được đặt tới trạng thái đảo của mức logic hiện tại

Base address + 0x000C offset

Hình 3‑10. Thanh ghi GPIOx_PTOR (Port Toggle Output Register).

f)     Thanh ghi đọc dữ liệu lối vào GPIOx_PDIR (Port Data Input Register)

Khi mô-đun GPIO được cấu hình làm đầu vào dữ liệu thì thanh ghi GPIO_PDIR được dùng để vi điều khiển đọc mức logic của một chân. Thanh ghi GPIO_PDIR có độ dịch địa chỉ là 0x0010 so với địa chỉ cơ sở của cổng.

Ký hiệu Định dạng Địa chỉ
GPIOx_PTOR

GPIOx→PTOR

Thanh ghi GPIOx_PDIR (Port Data Input Register)

Chú ý: 0: mức logic đọc được từ chân là 0; 1: mức logic đọc được từ chân là 1

Base address + 0x0010 offset

Hình 3‑11. Thanh ghi GPIOx_PDIR (Port Data Input Register).

Ví dụ 32
Tìm địa chỉ vật lý của các thanh ghi GPIOA_PDOR và GPIOA_PDDR nếu địa chỉ cơ sở của GPIO cổng PORTA là 0x400F_F000.
Đáp án:

Địa chỉ vật lý của thanh ghi GPIOA_PDOR là 0x400F_F000 + 0x0000 = 0x400F_F000.

Địa chỉ vật lý của thanh ghi GPIOA_PDDR là 0x400F_F000 + 0x0014 = 0x400F_F014

Nguyễn Kiêm Hùng

Hung K. Nguyen studied “Electronic Engineering” in both his bachelor’s and master’s degrees at the Vietnam National University, Hanoi, Vietnam. He received the bachelor’s degree in 2003. After receiving his bachelor’s degree, He worked as an internship in the Research Center of Electronics and Telecommunications. In 2006, He received the master’s degree in electronic engineering from VNU University of Engineering and Technology (VNU-UET). Before pursuing his Ph.D’s degree, He worked as a researcher at the Laboratory for Smart Integrated Systems in VNU University of Engineering and Technology for two years. In 2008, He went to Southeast University, Nanjing, China to get his Ph.D degree. He received the Ph.D. degree in Microelectronics and Solid State Electronics from Southeast University in 2013. After got his Ph.D’s degree, He returned to VNU University of Engineering and Technology to continue his research in VLSI design. He works currently as an assistant professor and senior researcher at VNU Key Laboratory for Smart Integrated Systems. His research interests mainly include multimedia processing, reconfigurable computing, and SoC designs.

This Post Has One Comment

Trả lời