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

Labels

Thứ Hai, 24 tháng 10, 2016

TivaC - ADC


Trong phần này chúng ta cùng xem xét ADC trong TMC123GH6PM MCU. Một số cấu hình và tất cả các bảng được lấy từ datasheet của MCU. Sử dụng datasheet để biết thêm thông tin về ADC của Tiva. Tài liệu này chỉ đưa ra một số giới thiệu về ADC, để có nhiều thông tin chuyên sâu hơn về ADC bạn nên đọc trong datasheet.

Đầu tiên, một ADC là gì?

ADC là viết tắt của Analog to Digital Converter, nó cho phép một vi điều khiển làm việc với tín hiệu số và các mạch số khác để đọc tín hiệu tương tự. Có một số phiên bản của ADC, với các phương thức khác nhau để chuyển một tín hiệu tương tự sang một tín hiệu số. Và với các giao tiếp khác nhau, từ song song đến I2C.

Một vi điều khiển (MCU) chỉ làm việc với các dữ liệu 0 và 1. Một tín hiệu tương tự thay đổi điện áp với một dải đa giá trị, vì vậy cần đến ADC.

ADC trong Tiva có một điện áp tham chiếu nội là 3V và đó là giá trị điện áp lớn nhất có thể đo được. Giá trị nhỏ nhất bằng GND.

Các ADC cũng có một độ phân giải max, chẳng hạn như ADC 12bit, sẽ có thể phân biệt 4096 giá trị khác nhau giữa GND và điện áp tham chiếu. Với một điện áp tham chiếu là 3V thì nó có nghĩa là mỗi giá trị tương ứng với khoảng 0.73mV.

Độ phân giải lớn hơn của ADC, một tín hiệu tương tự analog tốt hơn được đọc và lưu trữ. Nếu bạn cần khôi phục tín hiệu tương tự lúc trước thì bạn cần ghi nó lại một cách chính xác nhất có thể. Bạn có thể xem hình dưới đây để thấy cách convert một tín hiệu tương tự có thể mất rất nhiều giá trị với một ADC độ phân giải thấp. Có một số giá trị đã bị mất giữa các lần đọc.

(một ảnh ở đây)

Tôi vi vọng bạn đã có cái nhìn tổng quan về ADC. Để có thêm thông tin về ADC bạn nên tìm kiếm trên Web. Và cũng nên tìm hiểu về DAC, Digital to Analog converter là một bộ chuyển đổi từ số sang tương tự, nó ngược với ADC. 

Các tính năng của modul ADC

Vi điều khiển TM4C123GH6PM cung cấp 2 modul ADC với các tính năng dưới đây:
+ 12 kênh đầu vào tín hiệu tương tự
+ Độ phân giải 12bit
+ Các cấu hình Single - ended và differential - input
+ Một cảm biến nhiệt độ nội
+Tần số lấy mẫu tối đa là 1Mhz
+ Tùy chọn chuyển đổi giai đoạn trong thời gian lấy mẫu khả trình từ 22.5 đến 337.5 độ C.
+ Điều khiển bộ kích linh hoạt
    - Bộ điều khiển: phần mềm
    - Các timer
    - Các bộ so sánh tương tự
    - PWM
    - GPIO

Đó là các tính năng. Một số khá phức tạp trong sử dụng.
Có 2 modul ADC và mỗi modul có 4 bộ lấy mẫu cho phép lấy mẫu đa nguồn mà không cần vi điều khiển can thiệp.
Phần lớn các ngoại vi có các chân xác định cho mỗi input/output. Adc cũng có chân xác định kết nối tới nó giống như bạn xem trong bảng dưới đây. Nhưng bạn có thể sử dụng bất kỳ cái nào cho bất kỳ bộ sequncer hoặc modul ADC. Chẳng hạn, bạn có thể sử dụng AIN9 cho ADC0 hoặc ADC1 và bất kỳ sequencer nào.



Lấy mẫu ADC có thể được kích hoạt bởi nhiều nguồn khác nhau. Đơn giản thì bằng phần mềm hoặc bất kỳ ngoại vi nào sau: timer, PWM, GPIO hoặc bộ so sánh tương tự. Bộ kích hoạt bắt đầu đọc một cấu hình có sẵn để bắt đầu.

Bạn có thể thấy rõ ràng trong ảnh sau rằng tất cả các kênh đầu vào ADC được kết nối tới cả 2 modul ADC và bộ kích có thể kích cho bất kỳ ADC nào.



Cảm biến nhiệt độ nội

Trong phần này tôi sẽ chỉ bạn cách lập trình cơ bản với ADC bằng cách đọc cảm biến nhiệt độ nội có trong kit TM4C123GH6PM.

Cảm biến này đưa ra nhiệt độ bên trong chip. Nhiệt độ thường lớn hơn nhiệt độ môi trường do chip có thể bị nóng lên. 

Ví dụ này sẽ giải thích với các hàm có trong TivaWare, tuy nhiên nó cần một số tinh chỉnh, vì vậy tôi sẽ sửa nó một chút.

Bắt đầu code thôi!

Để xem giá trị ADC nhận được, chúng ta cần sử dụng UART để truyền giá trị lên máy tính. Để làm điều đó, tôi sẽ sử dụng các cấu hình trong bài hướng dẫn về UART.

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlDelay(3);
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4|GPIO_PIN_5);
UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 115200 (UART_CONFIG_WLEN_8 |UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));

Khai báo một số biến

uint32_t ADCValues[1];

Mảng này chứa dữ liệu đọc được từ ADC FIFO. Nó cần là một mảng là do một số sequencer có các FIFO với độ rộng lớn hơn 1 giá trị. Mảng này cần có độ rộng của FIFO. Chẳng hạn sequencer 3 sẽ được sử dụng có một FIFO depth là 1. Thậm trí vậy thì mảng vẫn nên được sử dụng ở đây hoặc ít nhất là một con trỏ (đọc một hàm chỉ chấp nhận một con trỏ). Nhớ rằng, cần khai báo một mảng đủ lớn cho một sequencer FIFO nếu bạn quyết định sử dụng một sequencer khác sequencer 3.

uint32_t TempValueC;
uint32_t TempValueF;

Chúng sẽ chưa nhiệt độ với đơn vị độ C và độ F.

Bây giờ là cấu hình cho ADC
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); 
SysCtlDelay(3);

Sử dụng ADC0, kích hoạt clock cho nó giống như những ngoại vi khác. Nhớ rằng ADC0 và ADC1 chia sẻ cùng một chân.

ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

Bạn sử dụng ADC base như biến đầu tiên trong lệnh trên. Biến thứ 2 chính là sequencer. Sequencer 3 với FIFO có depth là 1 sẽ được sử dụng như đã nói ở trên. Biến thứ 3 là một loại bộ kích mà bạn muốn khởi động một bộ lấy mẫu. Trong trường hợp này kích nó bằng phần mềm. Bạn có thể có các bộ kích khác (xem trong TivaWare). Biến thứ 4 là độ ưu tiên so với các sequencer khác. Có 4 mức từ 0 đến 3, 3 là độ ưu tiên thấp nhất. Cài đặt này sẽ làm bộ lấy mẫu sequencer đến đầu tiên khi một kích ở một thời điểm. Nhớ rằng để cài đặt các sequencer thì cần phân biệt các giá trị độ ưu tiên nếu có lớn hơn 1 bộ sequencer được sử dụng. Điều này sẽ tránh các lỗi và tránh các giá trị không tương ứng.

ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_EN D);

Cấu hình này chỉ ra các bước ADC thực hiện một đọc. Trong trường hợp cấu hình này sequencer 3 (biến thứ 2) trong ADC0 (biến thứ nhất). 
Biến thứ 3 cài đặt step tới 0. Sequencer 3 chỉ có một khả năng cấu hình nên chỉ có duy nhất một lựa chọn. Sequencer 1 và 2 có 4 step trong khi sequencer 0 có 8 step. Những sequencer này sẽ hữu ích trong các ứng dụng khác, không cần thiết trong tutorial này.
Biến thứ 4 là một biến logic hoặc một loạt các biến logic.
+ ADC_CTL_TS cài đặt kênh của cảm biến nhiệt độ, Với các kênh khác bạn sẽ sử dụng ADC_CTL_CH0 đến ADC_CTL_CH23.
+ ADC_CTL_IE, một interrupt sẽ được tạo ra khi sequencer kết thúc. Tuy nhiên, một ngắt sẽ không được sử dụng, trạng thái ngắt sẽ được sử dụng sau.
+ ADC_CTL_END định nghĩa bước này như là bước cuối cùng của sequence. Luôn luôn sử dụng biến này khi bạn không muốn sử dụng đa bước.
+ Thêm vào đó bạn có thể thêm ADC_CTL_CMP0 đến ADC_CTL_CMP7 để ADC gửi giá trị lấy mẫu tới một bộ so sánh.

Tất cả các cấu hình sẽ được sử dụng bởi sequencer khi nó được kích hoạt.

ADCSequenceEnable(ADC0_BASE, 3); 
ADCIntClear(ADC0_BASE, 3);

Bây giờ, mọi thứ đã được cấu hình cho sequencer 3. 2 lệnh trên dùng để kích hoạt sequencer 3 và cũng xóa cờ sequencer.

Bây giờ, làm sao tạo một đọc?

ADCProcessorTrigger(ADC0_BASE, 3); 
           
while(!ADCIntStatus(ADC0_BASE, 3, false)) 
   
ADCIntClear(ADC0_BASE, 3); 
      
ADCSequenceDataGet(ADC0_BASE, 3, ADC0Values); 

Đầu tiên, một đọc được hoàn thành bởi lần kích đầu tiên. Từ một bộ kích phần mềm được cài đặt trên sequencer 3. Lệnh này cần ADC base và sequencer như bạn thấy.

Thứ 2, Sau đó tất nhiên việc lấy mẫu cần thời gian nên chúng ta cần đợi cho nó tới. Đó là vì sao trong bước cấu hình tôi cài đặt một ngắt được gọi khi lấy mẫu hoàn thành (tuy nhiên ngắt không bao giờ được cấu hình để xảy ra và đi tới bộ xử lý ngắt).
Chúng ta đợi cho cờ ngắt được update lên 1. Bằng cách sử dụng ADCIntStatus(ADC0_BASE, 3, false) sẽ trả về một giá trị khác 0 khi sequencer được hoàn thành.
Chú ý rằng biến thứ 3 là "false" thay vì "true" như trong các bộ xử lý ngắt để kiểm tra ngắt có xảy ra hay không.

Thứ 3, Xóa cờ ADC

Thứ 4, Nhận giá trị từ FIFO. Hàm này sẽ đưa các giá trị từ FIFO vào trong một mảng. Biến thứ 3 cần phải là một mảng có kích thước tương ứng với sequencer FIFO như đã nói ở trước.

Chúng ta đã có các giá trị. Bây giờ là lấy nhiệt độ.

Chúng ta đã có giá trị của ADC vậy làm cách nào để lấy được nhiệt độ từ đó?

Các giá trị từ ADC đi từ 0 tới 4095. Nhưng những giá trị này có nghĩa là gì? Nếu điện áp tham chiều là 3.3V thì điều này có nghĩa là mỗi giá trị tương ứng với 3.3/4096 = 0.00081V. Cảm biến nhiệt độ đưa ra một giá trị voltage khác phụ thuộc vào nhiệt độ đo được. Vậy làm sao để chuyển từ điện áp sang nhiệt độ? Trong datasheet đã chỉ ra các phép toán giúp lấy giá trị nhiệt độ từ giá trị ADC:

+ VTSENS = 2.7 ­ ((TEMP + 55) / 75): được chỉ ra ở hình 13-11 trang 814.
+ TEMP = 147.5 ­ ((75 * (VREFP ­- VREFN) × ADCCODE) / 4096): Chỗ VREFP ­- VREFN là 3.3V trên kit. ADCCODE là giá trị bạn nhận được từ lấy mẫu ADC.

Bây giờ bạn cần tạo phép toán và in kết quả nên màn hình.
Đồng thời một delay khoảng 250mS được thêm vào.

TempValueC= (uint32_t)(147.5 ‐ ((75.0*3.3 *(float)ADCValues[0])) / 4096.0); 
TempValueF= ((TempValueC* 9) + 160) / 5;
UARTprintf("Temperature = %3d*C or %3d*F\r", TempValueC, TempValueF); 
SysCtlDelay(80000000 / 12);

I hope you enjoyed this!!!

Dưới đây là code cho phần hướng dẫn này:

/*
 * main.c
 */
#include "stdint.h"
#include "stdio.h"
#include "stdbool.h"
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include <driverlib/uart.h>
#include <driverlib/gpio.h>
#include <driverlib/sysctl.h>
#include <driverlib/sysctl.c>
#include <driverlib/pin_map.h>
#include <driverlib/adc.h>

void delay_us(unsigned int time_us)
{
SysCtlDelay(time_us*26667/1000);
}

void delay_ms(unsigned int time_ms)
{
SysCtlDelay(time_ms*26667);
}

void put_string(unsigned char *string)
{
int i, length = 0;

while(string[length]!='\0') length++;

for(i=0; i<length; i++)
{
UARTCharPut(UART4_BASE, string[i]);
}
UARTCharPut(UART4_BASE, '\r');
UARTCharPut(UART4_BASE, '\n');
}

void toString(uint32_t temperature, unsigned char *temp)
{
uint32_t x;
uint32_t y;

x = temperature/1000;
y = temperature-x*1000;
if(y<10) sprintf((char *)temp, "Temperature = %d.00%d*C", x, y);
else if(y<100) sprintf((char *)temp, "Temperature = %d.0%d*C", x, y);
else sprintf((char *)temp, "Temperature = %d.%d*C", x, y);
}

int main(void) {
uint32_t ADCValues[1];
uint32_t TempValueC;
unsigned char temp[30] = "";

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
SysCtlDelay(3);

SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
SysCtlDelay(3);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlDelay(3);
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4|GPIO_PIN_5);
UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));

put_string("ADC:");
put_string("Internal Temperature Sensor");

SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlDelay(3);

ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
ADCSequenceEnable(ADC0_BASE, 3);

while(1)
{
ADCProcessorTrigger(ADC0_BASE, 3);
while(!ADCIntStatus(ADC0_BASE, 3, false));
ADCIntClear(ADC0_BASE, 3);
ADCSequenceDataGet(ADC0_BASE, 3, ADCValues);
TempValueC = (uint32_t)((147.5-((75.0*3.3*(float)ADCValues[0]))/4096.0)*1000);

toString(TempValueC, temp);
put_string(temp);
delay_ms(250);
}
}

Thứ Sáu, 14 tháng 10, 2016

TivaC - GPIO


Hiểu về GPIO


Trong phần này tôi sẽ chỉ cho bạn về các tính năng của modul GPIO có trên kit TM4C123. Các MCU khác của Tiva cũng có GPIO tương tự nhưng có thể có nhiều hoặc ít hơn modul hoặc tính năng nên tốt nhất là luôn luôn tham khảo datasheet để có đầy đủ thông tin. Tôi sẽ không đề cập tới các thanh ghi là vì để hiểu cách lập trình với TivaWare (Thư viện có sẵn dùng để hỗ trợ lập trình với kit Tiva). Các bảng để tham khảo luôn lấy từ TM4C123GH6PM MCU.

Nội dung:
+ Tổng quan về GPIO
+ Blinky với TivaWare
+ Đầu vào số đơn giản
+ Đầu vào số với NGẮT
+ Ví dụ về điều khiển màu sắc bóng đèn RGB

GPIO là gì?

GPIO là viết tắt của General Purpose Input/Outputs (Các IO với mục đích chung), nghĩa là nó là một modul có khả năng nhận hoặc truyền tín hiệu. Chúng làm việc với tín hiệu số nhưng có thể trở thành bộ trộn để sử dụng các pin (chân) với các ngoại vi khác như ADC, SSI, UART,...

Thông số kỹ thuật của Tiva GPIO

IC TM4C123GH6PM có 6 khối GPIO, mỗi khối có cổng riêng (port A, port B, port C, port D, port E, port F).
Các thông số kỹ thuật như dưới đây:
    + Lên tới 43 GPIO, phụ thuộc vào cấu hình
    + Tính linh hoạt cao cho phép sử dụng như GPIO hoặc một chuỗi các chức năng ngoại vi khác
    + 5V trong cấu hình đầu vào
    + Các port từ A-G được truy cập thông qua Advanced Peripheral Bus (APB)
    + Khả năng chuyển mạch nhanh ở mỗi chu kỳ xung clock cho các cổng trên AHB, mỗi hai chu kỳ  clock cho các port trên APB.
    + Điều khiển khả trình cho các ngắt GPIO
       - Bộ ngắt chung
       - Bộ kích ngắt trên cạnh lên, cạnh xuống hoặc cả hai
       - Độ nhạy ở giá trị cao hoặc thấp
    + Bit mặt nạ trên cả bộ đọc và viết thông qua các đường địa chỉ.
    + Có thể được sử dụng để khởi tạo một tần số lấy mẫu ADC hoặc một bộ truyền uDMA
    + Trạng thái chân có thể được giữ lại trong suốt chế độ ngủ
    + Các chân được cấu hình như đầu vào số  được kích hoạt Schmitt.
    + Điều khiển khả trình cho cấu hình các chân GPIO
       - Kéo điện trở lên hoặc xuống
       - 2mA, 4mA và 8mA cho giao tiếp số. Lên tới 4 chân có thể tạo ra dòng 18mA cho các ứng dụng cần dòng lớn
       - Điều khiển tốc độ Slew cho 8mA
       - Kích hoạt Open drain
       - Kích hoạt đầu vào số

Đó là các thông số kỹ thuật, nó có một số thứ rất tuyệt phải không, chẳng hạn như gần như tất cả các GPIO đều là 5V, một truy cập nhanh hơn bằng các gọi AHB và các biến ngắt trong tất cả GPIO. Chú ý răng chân PD4, PD5, PB0 và PB1 không là 5V và đầu vào tối đa là 3.6V.

Mỗi GPIO có 8 chân nên có tổng số là 48 chân nhưng một số là chân nội và không thể được sử dụng nên tối đa có 43 có thể được sử dụng. Vì lý do vật lý mà các kit thường có ít hơn vậy. Kit TM4C123 GH6PM chỉ có 37 chân GPIO.

Các chức năng thay thế

GPIO cho phép vi điều khiển của bạn giao tiếp với bên ngoài. Nó cho phép các đầu vào hoặc đầu ra số và cũng cho phép các chức năng thay thế. Vậy chúng là gì?
Các chức năng thay thế có thể được đọc các tín hiệu tương tự bằng cách sử dụng các chân ADC hoặc giao tiếp UART bằng cách cấu hình.
Các chức năng có sẵn phụ thuộc vào chân và bạn có thể thấy chúng trong bảng dưới đây:


Mỗi khi bạn muốn sử dụng một ngoại vi như modul PWM hoặc ADC, bạn cần sử dụng chân tương ứng. Nhớ là phải cài đặt GPIO với cùng chức năng thay thế.

Đặc biệt quan trọng: Các chân GPIO với sự xem xét đặc biệt

Một số chân bị khóa để có cấu hình chắc chắn và chỉ có thể được sử dụng nếu bạn mở khóa chúng. Bạn cần làm điều này trong thanh ghi GPIOLOCK và giải thoát chúng bằng cách cài đặt thanh ghi GPIOCR. Nếu bạn sử dụng TivaWare, chỉ cần làm như dưới đây:

HWREG(GPIO_PORTx_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY ;
HWREG(GPIO_PORTx_BASE + GPIO_O_CR)  |= 0x80;


Như vậy, bạn đã có cái nhìn tổng quan và hiểu cơ bản về GPIO trên dòng TivaC. Trong phần tiếp theo sẽ là một số ví dụ lập trình với GPIO. Bạn sẽ hiểu rõ hơn cách sử dụng TivaWare để lập trình cho TM4C123GH6PM.


Blinky với TivaWare

Trong phần này tôi sẽ chỉ cho bạn cách để nhấp nhảy một đèn led với kit TM4C123. 
Đèn led bạn sẽ sử dụng là red LED được kết nối với chân PF1 có sẵn trên kit. Bạn có thể xem rõ hơn từ kit user guide của hãng.
Ví dụ này được tạo bằng phần mềm CCS của hãng TI. Bạn nên tham khảo TivaWare Peripheral Driver Library USER’S GUIDE của hãng để hiểu rõ hơn về các câu lệnh sử dụng trong các ví dụ.

+ Đầu tiên, chúng ta cần phải cài đặt clock của hệ thống. Câu lệnh sau sẽ cài đặt chip chạy với tốc độ 80Mhz

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XT AL_16MHZ);

+ Tiếp theo, chúng ta cần enable clock của ngoại vi. 

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
SysCtlDelay(3);

Thông thường, clock ở trạng thái disable để tiết kiệm năng lượng nên để sử dụng một ngoại vi bạn cần enable chúng. Tiếp theo đến dòng lệnh delay, tôi khuyên bạn nên chờ ít nhất 3 chu kỳ xung clock trước khi việc cấu hình thực sự được enable. 
    - SysCtlPeripheralEnable(uint32_t ui32Peripheral) là lệnh bạn luôn sử dụng để enable một ngoại vi. Nó enable xung clock cho ngoại vi. Biến truyền vào là ngoại vi bạn muốn enable. Đối với GPIO thì SYSCTL_PERIPH_GPIOx x ở đây là ký tự của ngoại vi bạn muốn kích hoạt.
    - SysCtlDelay(uint32_t ui32Count) là một hàm delay. Nó dừng code trong một số chu kỳ xác định. Mỗi giá trị được delay trong 3 chu kỳ xung clock nên trong trường hợp của chúng ta thì giá trị là 3. Vậy sẽ delay trong 9 chu kỳ xung clock. Làm sao để biết thời gian delay là bao nhiêu? Ở trên, tôi cấu hình chip chạy với tần số 80Mhz, hàm delay giúp delay 9 chu kỳ xung clock nên nó sẽ delay trong khoảng 112.5nS. 

+ Cài đặt các chân ở chế độ Output
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
Phần này rất đơn giản, bạn sử dụng GPIOPinT ypeGPIOOutput(uint32_t ui32Port,uint8_t ui8Pins) để cài đặt chân thành một output. ui32Port là chân GPIO, trong trường hợp này là GPIO_PORTF_BASE. ui8Pins là chân bạn muốn cài đặt trở thành Output, trong trường hợp này là GPIO_PIN_1. Nhìn vào mạch nguyên lý của kit sẽ thấy rằng chân PF1 được kết nối tới red LED.

+ Giờ chúng ta đã có thể Blink led
Bây giờ để bật hoặc tắt LED, bạn sử dụng GPIOPinWrite(uint32_t ui32Port,uint8_t ui8Pins,uint8_t ui8Val). Biến thứ nhất và thứ 2 bạn đã biết. Biến thứ 3 là trạng thái của chân. Bạn sử dụng 0 để tắt nó, 1 để bật. Bạn cần sử dụng giá trị GPIO_PIN_x mà bạn sử dụng, ở đây là PF1.

/* 
This code was made using TivaWare 2.1.0.12573. TivaWare rights to it are all own by 
Texas Instruments 
This code shows how to blink the RED LED of the TM4C123 Launchpad using  
Tivaware. 
Luís Afonso 
*/ 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_types.h" 
#include "inc/hw_gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/sysctl.c" 
#include "driverlib/sysctl.h" 
#include "driverlib/gpio.c" 
#include "driverlib/gpio.h" 
/* 
    This are to help if you want to change the pin you want to use so you don't 
    have to change it in the entire code 
*/ 
#define LED_PERIPH SYSCTL_PERIPH_GPIOF 
#define LED_BASE GPIO_PORTF_BASE 
#define RED_LED GPIO_PIN_1       
int main(){ 
//Set the system clock to 80Mhz 
  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); 
   
/* 
    Enables the clock on the GPIO, or "turns on" 
    Also, delays for a bit since it's advised in the datasheet, i add problems 
    when i didn't have that delay. 
*/ 
  SysCtlPeripheralEnable(LED_PERIPH); 
  SysCtlDelay(3); 
   
  //Set the pin of your choise to output 
  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1); 
   
  /* 
    Here it blinks the LED with a 0.5 seconds interval. 
     
    To set a GPIO to the state HIGH you need in the third parameter to be the name 
    of the pin, ex: GPIO_PIN_1. To set to LOW just write 0. 
     
    SysCtlDelay math: 
      1/80Mhz = 12.6nS, 12,5*3= 37,5nS. 37,5*13333333=0.5 seconds 
   
  */ 
  while(1){ 
          GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, GPIO_PIN_1); 
          SysCtlDelay(13333333);  
          GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0); 
          SysCtlDelay(13333333); 
      } 
     


Đầu vào số đơn giản

Trong phần này tôi sẽ giải thích cách đọc giá trị đầu vào số. Đầu vào số sẽ được điều khiển bởi một nút nhấn có sẵn trên kit. Ý tưởng là bật tắt một LED khi bạn ấn nút. Nút ấn được sử dụng là SW1 được kết nối tới chân PF4.

+ Bước đầu tiên vẫn là cài đặt xung clock hệ thống, ở đây là 80Mhz

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

+ Enable clock của ngoại vi

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

+ Cài đặt nó là intput

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);

Nhớ lại trong Blinky cách cài đặt một chân trở thành output. Bây giờ, đơn giản là thay GPIOPinT ypeGPIOOutput thành GPIOPinTypeGPIOInput

Chúng ta cần thêm là sử dụng điện trở nội kéo lên

GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

Biến thứ 3 không thực sự quan trọng khi chân là một đầu vào, vấn đề là ở biến thứ 4. Cấu hình ở trên làm chân có một điện trở kéo lên. Nếu sử dụng lệnh GPIO_PIN_TYPE_STD_WPD sẽ cài đặt nó sử dụng điện trở kéo xuống. Để có nhiều thông tin hơn bạn có thể xem trong Peripheral Driver Library Guide.

+ Việc cấu hình Input đã xong. Tiếp theo, chúng ta cần cấu hình cho chân PF1 trở thành Output để có thể điều khiển LED. Các cấu hình cần thiết đã được viết ở trên, cái còn lại là cầu hình chân PF1 thành Output.

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);

+ Để đọc một đầu vào ta sử dụng câu lệnh sau:

GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4);

Thực sự là rất đơn giản để hiểu được câu lệnh này. Nó trả về một giá trị 32bit. Tại sao lại là 32bit? là vì có thể đọc toàn bộ 8 chân cùng một thời điểm nếu bạn muốn. Bit 31-8 từ gói trả về có thể được bỏ qua. Nếu chân GPIO_PIN_4 đang ở mức cao sau đó được trả về giá trị bằng với GPIO_PIN_4 (GPIO_PIN_4  được định nghĩa trong thư viện với giá trị 0x00000010). Ví dụ: Nếu đầu PF4 là 1 thì (value & GPIO_PIN_4) = GPIO_PIN_4. Nếu đầu vào là 0 thì trả về 0.

+ Bây giờ là các câu lệnh đổi trạng tại LED với button:

uint32_t value=0; 
uint8_t state=0; 
while(1){ 
    value= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
    if( (value & GPIO_PIN_4)==0) 
      state^=GPIO_PIN_1; 
    GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, state); 
    SysCtlDelay(7000000); 

Một biến được tạo để lưu trữ giá trị trả về của GPIOPinRead và sau đó kiểm tra nếu nó bằng 0 hay không. Button khi được nhấn, nó sẽ kết nối với đất nên sẽ trả về 0. Chúng ta sử dụng một biến "state" bởi vì trong GPIOPinWrite chúng ta cần để sử dụng GPIO_PIN_1 để đặt chân ở mức cao. Nên ta dùng phép XOR trạng thái với GPIO_PIN_1 để có thể lật trạng thái mỗi lần button được ấn.

Hàm Delay được gọi để delay 0.25s. Nút ấn là cơ khí, ví vậy sẽ không trả về tín hiệu 0, 1 hoàn hảo. Thay vào đó, nó sẽ chập chờn ở mức 0, 1 khi bạn nhấn trước khi thực sự ổn định.

/* 
  This code was made using TivaWare 2.1.0.12573. TivaWare rights to it are all own by 
Texas Instruments 
  This code shows how to toggle the RED LED (PF1) of the TM4C123 Launchpad 
with the left button at PF4, using Tivaware. 
  Luís Afonso 
*/ 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_types.h" 
#include "inc/hw_gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/sysctl.c" 
#include "driverlib/sysctl.h" 
#include "driverlib/gpio.c" 
#include "driverlib/gpio.h" 
/* 
  These defines help if you want to change the LED pin or the Button pin.
  Remember if you change to a diferent GPIO you need to enable the system
  clock on it 
*/ 
#define LED_PERIPH SYSCTL_PERIPH_GPIOF 
#define LED_BASE GPIO_PORTF_BASE 
#define RED_LED GPIO_PIN_1 
#define Button_PERIPH SYSCTL_PERIPH_GPIOF 
#define ButtonBase GPIO_PORTF_BASE 
#define Button GPIO_PIN_4 
int main(void) 
  
 //Set the clock to 80Mhz 
  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); 
  /*
No need to enable the button peripheral since it's the same as the LED 
    in this case 
  */ 
  SysCtlPeripheralEnable(LED_PERIPH); 
  SysCtlDelay(3); 
   
  /* 
    Configure the switch on the left of the launchpad, GPIO_PIN_4 to a input with 
    internal pull‐up. 
  */ 
  GPIOPinTypeGPIOInput(ButtonBase, Button); 
  GPIOPadConfigSet(ButtonBase ,Button,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); 
   
  /* 
    Configures the Red LED, GPIO_PIN_1, to output 
  */ 
  GPIOPinTypeGPIOOutput(LED_BASE, RED_LED); 
   
   
   
 /* 
  A variable is created to store the return value of GPIOPinRead and then checked  
 if it's 0 or not.The button when pressed, connected  the pin to the GND so it gives 0. 
  
 We use a variable "state" because in GPIOPinWrite we need to use GPIO_PIN_1 to set the pin HIGH.  
 So we XOR the state with GPIO_PIN_1 so it toggles the "state" every time the button is pressed. 
  
  The SysCtlDelay of about 0.25s is a rude way to avoid bouncing. The button being mechanical  
  doesn't give a perfect 1 and 0 signal, instead, to the "eyes" of the digital pin, it bounces 
  between 1 and 0 when you press it before stabilizing 
*/ 
  uint32_t value=0; 
  uint8_t state=0; 
  while(1){ 
    value= GPIOPinRead(ButtonBase,Button); 
    if( (value & GPIO_PIN_4)==0) 
      state^=RED_LED; 
    GPIOPinWrite(LED_BASE,RED_LED, state); 
    SysCtlDelay(7000000); 
  } 
}


Đầu vào số với NGẮT

Trong phần này tôi sẽ chỉ cho bạn cách đọc một đầu vào số sử dụng một ngắt. Sử dụng nút ấn SW1 trên kit, bật tắt để tạo một tín hiệu đầu vào. Ý tưởng là điều khiển bật tắt LED.

+ Đầu tiên là cấu hình xung clock cho hệ thống:

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

+ Tiếp theo là cầu hình nút ấn và Led như 2 ví dụ phía trên.

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
SysCtlDelay(3); 
   
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); 
  GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); 
   
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1); 

+ Bây giờ là ngắt.
Nếu bạn không biết một ngắt là gì? tôi khuyên bạn nên tham khảo tài liệu này. Thực sự có rất nhiều thứ để tìm hiểu đối với ngắt. Nếu bạn thực sự muốn biết về ngắt ARM-M4 bạn có thể tìm thấy ở A Beginner’s Guide on Interrupt Latency. Nhưng nói chung, việc xem xét nó cũng khá phức tạp.

Tôi hi vọng là bạn còn nhớ ở phần đầu tiên trong phần thông số kỹ thuật. IC xác định loại ngắt của GPIO có thể có:
   + Ngắt theo cạnh:
      - Cạnh lên, cạnh xuống hoặc cả hai.
     - Ngắt theo cạnh là khả năng ngắt khi một tín hiệu thay đổi từ một trạng thái này sang một trạng thái khác.
   + Ngắt theo mức:
      - Mức cao hoặc mức thấp
     - Ngắt theo mức là ngắt theo trạng thái của chân. Ví dụ: Nếu một ngắt được cấu hình là ngắt theo mức thấp thì nó sẽ gọi trình phục vụ ngắt khi chân ở trạng thái 0.

Một điều quan trọng cần chú ý là một ngắt trên GPIO. Trong TM4C123 thì mỗi GPIO có thể có duy nhất một trình phục vụ ngắt. Nghĩa là bạn không thể tạo một trình phục vụ ngắt cho riêng từng chân của GPIO. Tôi sẽ nói kỹ hơn về xử lý ngắt ở từng bit.

Vậy làm sao để cài đặt một ngắt?
Trình phục vụ ngắt là nơi được gọi và thực hiện khi một ngắt xảy ra. Tôi sẽ cho bạn thấy cách tôi sử dụng để cài đặt trình phục vụ ngắt nhưng có một cách để cài đặt nó trong file startup.c được yêu cầu bởi CCS và IAR. Cách để cài đặt nó là đầu tiên phải tạo một hàm void PortFIntHandler(). Đây là nơi mà code sẽ chạy khi một ngắt xảy ra.
Sau đó, bạn cần:
GPIOIntRegister(GPIO_PORTF_BASE,PortFIntHandler);
Bạn có thể thay đổi tên của trình phục vụ ngắt thành bất cứ tên nào bạn muốn nhưng nó cần là a void và không truyền vào tham số.

Tiếp theo, ta cần enable ngắt
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
Bạn có thể sử dụng bất cứ nguồn kích hoạt ngắt nào dưới đây
   
    + GPIO_INT_PIN_0 ­ interrupt due to activity on Pin 0.
    + GPIO_INT_PIN_1 ­ interrupt due to activity on Pin 1.
    + GPIO_INT_PIN_2 ­ interrupt due to activity on Pin 2.
    + GPIO_INT_PIN_3 ­ interrupt due to activity on Pin 3.
    + GPIO_INT_PIN_4 ­ interrupt due to activity on Pin 4.
    + GPIO_INT_PIN_5 ­ interrupt due to activity on Pin 5.
    + GPIO_INT_PIN_6 ­ interrupt due to activity on Pin 6.
    + GPIO_INT_PIN_7 ­ interrupt due to activity on Pin 7.
    + GPIO_INT_DMA ­ interrupt due to DMA activity on this GPIO module.

Bên trong trình phục vụ ngắt:
Đầu tiên và quan trọng nhất trong một trình phục vụ ngắt là
GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
Lệnh này sẽ xóa cờ ngắt. Nếu bạn không xóa nó, nó sẽ tạo một vòng lặp luôn đúng và trở lại trình phục vụ ngay khi vừa thoát khỏi. 
Chú ý rằng biến thứ 2 là cờ ngắt cần được xóa. Nhớ lại, tôi đã nói rằng mỗi GPIO chỉ có duy nhất một trình phục vụ ngắt. Nên nếu bạn muốn một ngắt trên chân 4 nhưng cũng muốn trên chân 5 thì phải làm thế nào? Bạn cần phải kiểm tra các cờ và xóa chúng.
Vậy làm sao để kiểm tra cờ nào đang được set và gọi trong trình phục ngắt? Dưới đây là ví dụ

status = GPIOIntStatus(GPIO_PORTF_BASE,true); 
GPIOIntClear(GPIO_PORTF_BASE,status); 
if( (status & GPIO_INT_PIN_4) == GPIO_INT_PIN_4){ 
  //Then there was a pin4 interrupt 
}  
if( (status & GPIO_INT_PIN_5) == GPIO_INT_PIN_5){ 
  //Then there was a pin5 interrupt 
}

Nói chung là bạn nên luôn làm điều này ngay cả khi bạn chỉ có duy nhất một ngắt được enable.

+ Bây giờ là đổi trạng thái LED
Bạn có thể sử dụng lại code của ví dụ trước nhưng với 1 khác biệt. Biến "state" cần trở thành biến toàn cục. Bởi vì giá trị của biến "state" cần được giữ lại giữ các lần ngắt và nếu nó là biến cục bộ thì điều đó sẽ không xảy ra.

volatile uint8_t value=0;
uint8_t value=0; 
value= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
if( value==0) 
   state^=GPIO_PIN_1; 
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, state); 
SysCtlDelay(7000000);

Thực sự thì hàm delay ở đây là không cần thiết. Trong trường hợp ngày chúng ta sẽ giữ nguyên trạng thái của led bởi vì vi xử lý chỉ thực hiện delay nhưng một ngắt có thể nhanh hơn. Nó giống như một thứ gì đó chạy ngầm. Ở đây có thể có rất nhiều ngắt, vì vậy cần phải xử lý nhanh. 

Tôi hi vọng bạn sẽ thích và hiểu cách sử dụng ngắt với GPIO sử dụng TivaWare GPIO API.

Dưới đây là code:

/* 
  This code was made using TivaWare 2.1.0.12573. TivaWare rights to it are all own by 
Texas Instruments 
  This code shows how to toggle the RED LED (PF1) of the TM4C123 Launchpad 
with the left button at PF4, using Tivaware. In this one a interrupt is 
used to sense the button being pressed 
  Luís Afonso 
*/ 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_types.h" 
#include "inc/hw_gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/sysctl.c" 
#include "driverlib/sysctl.h" 
#include "driverlib/gpio.c" 
#include "driverlib/gpio.h" 
/* 
  These defines help if you want to change the LED pin or the Button pin. 
  Remember if you change to a diferent GPIO you need to enable the system 
  clock on it

*/ 
#define LED_PERIPH SYSCTL_PERIPH_GPIOF 
#define LED_BASE GPIO_PORTF_BASE 
#define RED_LED GPIO_PIN_1 
#define Button_PERIPH SYSCTL_PERIPH_GPIOF 
#define ButtonBase GPIO_PORTF_BASE 
#define Button GPIO_PIN_4 
#define ButtonInt GPIO_INT_PIN_4 
volatile uint8_t value=0;  
void PortFIntHandler(){ 
  uint32_t status=0; 
  status = GPIOIntStatus(ButtonBase,true); 
  GPIOIntClear(ButtonBase,status); 
  if(status & ButtonInt == ButtonInt){ 
    //Then there was a Button pin interrupt 
    uint8_t value=0; 
     
    value= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
     
    if( value==0) 
      state^=RED_LED; 
    GPIOPinWrite(LED_BASE,RED_LED, state); 
     
    /* 
      This delay is for deboucing but since it's in a interrupt it 
      should be used a better method that is faster 
    */ 
    SysCtlDelay(7000000); 
  } 
}  
int main(void) 
  
 //Set the clock to 80Mhz 
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); 
  /* 
    No need to enable the button peripheral since it's the same as the LED 
    in this case 
  */ 
  SysCtlPeripheralEnable(LED_PERIPH); 
  SysCtlDelay(3); 
   
  /* 
    Configure the switch on the left of the launchpad, GPIO_PIN_4 to a input with 
    internal pull‐up. 
  */ 
  GPIOPinTypeGPIOInput(ButtonBase, Button); 
  GPIOPadConfigSet(ButtonBase ,Button,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); 
  GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE); 
  GPIOIntRegister(GPIO_PORTF_BASE,PortFIntHandler); 
  GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4); 
   
  /* 
    Configures the Red LED, GPIO_PIN_1, to output 
  */ 
  GPIOPinTypeGPIOOutput(LED_BASE, RED_LED); 
   
   
   
 /* 
  A variable is created to store the return value of GPIOPinRead and then checked  
 if it's 0 or not.The button when pressed, connected  the pin to the GND so it gives 0. 
  
 We use a variable "state" because in GPIOPinWrite we need to use GPIO_PIN_1 to set the pin HIGH.  
 So we XOR the state with GPIO_PIN_1 so it toggles the "state" every time the button is pressed. 
  
  The SysCtlDelay of about 0.25s is a rude way to avoid bouncing. The button being mechanical  
  doesn't give a perfect 1 and 0 signal, instead, to the "eyes" of the digital pin, it bounces 
  between 1 and 0 when you press it before stabilizing 
*/ 
  uint32_t value=0; 
  uint8_t state=0; 
  while(1){ 
    value= GPIOPinRead(ButtonBase,Button); 
    if( value==0) 
      state^=RED_LED; 
    GPIOPinWrite(LED_BASE,RED_LED, state); 
    SysCtlDelay(7000000); 
  }


Ví dụ về điều khiển màu sắc bóng đèn RGB

Trong phần này tôi chỉ nêu ra code chứ không giải thích bởi qua các ví dụ phía trên bạn đã hiểu rất rõ về GPIO. Nên ở ví dụ này, giải thích là không cần thiết nữa. Ở ví dụ này, chúng ta sẽ tìm hiểu cách kết hợp bật tắt các led có trên led RGB để thay đổi màu sắc.
Tham khảo user guide để thấy rõ hơn cách kết nối các chân.

Dưới đây là code:

/* 
   
  Example code made using IAR workbench with TivaWare for the Tiva TM4C123 launchpad 
  It's an example with simple digital output and inputs. When you press the left button 
on the launchpad it cycles the combinations of colors of a RGB LED. 
  
  red‐>purple‐>blue‐>light blue‐>green‐>yellow‐>red, and back to purple. 
  Luís Afonso 
*/ 
#include <stdint.h> 
#include <stdbool.h> 
#include "inc/hw_types.h" 
#include "inc/hw_gpio.h" 
#include "driverlib/pin_map.h" 
#include "driverlib/sysctl.c" 
#include "driverlib/sysctl.h" 
#include "driverlib/gpio.c" 
#include "driverlib/gpio.h" 
#define LEDbase GPIO_PORTF_BASE 
#define LEDred GPIO_PIN_1 
#define LEDblue GPIO_PIN_2 
#define LEDgreen GPIO_PIN_3 
int main(){ 
   
  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
  SysCtlDelay(3); 
   
  GPIOPinTypeGPIOOutput(LEDbase, LEDred|LEDblue|LEDgreen); 
  
  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); 
  GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); 
   
  uint32_t value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
   
   //================Turn on red=======================    
          GPIOPinWrite(LEDbase,LEDred, LEDred); 
           
          //Wait for a button press 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         //Wait for the button to be let go 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0); 
  //=======================================    
     
     
    while(1){ 
       
      //==================Get purple color======================= 
      //======================Turn on blue=================      
          GPIOPinWrite(LEDbase,LEDblue, LEDblue); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
     //====================================================  
          
             
     //=================Get blue color==========================        
     //======================Turn off red=================    
          GPIOPinWrite(LEDbase,LEDred, 0); 
          do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
     //=================================================== 
          
             
    //====================Get light blue color================== 
//========================Turn on green===============      
          GPIOPinWrite(LEDbase,LEDgreen, LEDgreen); 
          do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
     //====================================================  
             
      
     //=====================Get green color================ 
     //======================Turn off blue=================    
          GPIOPinWrite(LEDbase,LEDblue, 0); 
          do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
     //====================================================        
        
          
     //===============Get yellow color=================== 
     //================Turn on Red=======================    
            GPIOPinWrite(LEDbase,LEDred, LEDred); 
            do{ 
              value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
            } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
    //==================================================== 
          
          
      //====================Get red color===================       
      //======================Turn off green=================    
          GPIOPinWrite(LEDbase,LEDgreen, 0); 
          do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)!=0); 
         do{ 
            value =  GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); 
          } while ((value&GPIO_PIN_4)==0);  
     //======================================================           
      } 
   

The End: I hope you can understand what i want to show you throught this tutorial. And i also hope you can join me for the next tutorial. The next tutorial will talk about How to use ADC TM4C123 with TivaWare. Goodbye!!!