Lập trình chức năng GPIO INPUT – STM32F103C8T6

Lập trình GPIO nhấp nháy Led PC13 – STM32F103C8T6
Lập trình GPIO nhấp nháy Led PC13 – STM32F103C8T6

Bài trước chúng ta làm quen với GPIO Output mode của vi VĐK STM32F103C8T6, trong bài này mình sẽ hướng dẫn các bạn lập trình chức năng GPIO INPUT.

Xem bài trước tại đây

A, Giới thiệu

Cấu trúc 1 chân GPIO của Vi điều khiển STM32F103C8T6: 

Lập trình GPIO nhấp nháy Led PC13 – STM32F103C8T6

 

Có 2 khối điều khiển khác nhau (khung hình nét đứt):

Input

Output và các điều khiển đầu ra khác

Chức năng của GPIO bao gồm:

 Input floating: cấu hình chân I/O là ngõ vào và để nổi.

– Input pull-up: cấu hình chân I/O là ngõ vào, có trở kéo lên nguồn.

 Input pull-down: cấu hình chân I/O là ngõ vào, có trở kéo xuống GND.

– Output open-drain:  cấu hình chân I/O là ngõ ra, khi output control = 0 thì N-MOS sẽ dẫn, chân I/O sẽ nối VSS, còn khi output control = 1 thì P-MOS và N-MOS đều không dẫn, chân I/O được để nổi.

– Output push-pull: cấu hình chân I/O là ngõ ra, khi output control = 0 thì N-MOS sẽ dẫn, chân I/O sẽ nối VSS, còn khi output control = 1 thì P-MOS dẫn, chân I/O được nối VDD.

– Analog: cấu hình chân I/O là Analog, dùng cho các mode có sử dụng ADC hoặc DAC.

– Alternate function open-drain:  sử dụng chân I/O vừa là ngõ ra và vừa là ngõ vào, tuy nhiên sẽ không  có trở kéo lên và kéo xuống ở input, chức năng output giống Output open-drain. Ngoài ra nó còn để sử dụng cho chức năng remap.

– Alternate function push-pull:  sử dụng chân I/O vừa là ngõ ra và vừa là ngõ vào, tuy nhiên sẽ không có trở kéo lên và kéo xuống ở input, chức năng output giống Output push-pull. Ngoài ra nó còn để sử dụng cho chức năng remap

Bài viết này sẽ hướng dẫn về chức năng Input states: Input floating, input pull-up, input -pull down. Sau đây sẽ là sơ lược về cấu trúc phần cứng và khối điều khiển Input.

1/ GPIO Input:

Khi Pin I/O được lập trình trong chế độ INPUT MODE :

– Bộ đệm output được tắt và TTL Schmitt Trigger được kích hoạt. Lúc này Bạn có thể chọn cấu hình là trở kéo lên pull-up  hoặc trở kéo xuống pull-down và dữ liệu từ bên ngoài chân I/O sẽ được đưa vào thanh ghi GPIO_IDR mọi chu kỳ xung clock của APB2 bus. Việc chúng ta cần làm chỉ việc đọc thanh ghi GPIO_IDR để biết trạng thái của chân I/O là ở mức High hay mức Low.

Lập trình chức năng GPIO INPUT trên vi điều khiển STM32F103C8T6

 

2/ Các thanh ghi dữ liệu:

Input Data Register (IDR): Nhận mức tín hiệu tại chân IO, thông qua việc đọc thanh ghi GPIOx_IDR thì chúng ta có thể đọc được trạng thái mức “1” hay mức “0” của chân đó tại Port tương ứng.

Lập trình chức năng GPIO INPUT - STM32F103C8T6

Note : Khi cấu hình I/O pin là INPUT MODE thì thanh ghi GPIO_IDR không được phép ghi chỉ có thể đọc(Read only).

Lập trình chức năng GPIO INPUT - STM32F103C8T6

 

3/ TTL Schmitt Trigger:

Trigger Schmitt là một mạch logic input sử dụng hysteresis, Điều này cho phép đầu ra giữ lại giá trị của nó cho đến khi đầu vào thay đổi đủ để kích hoạt thay đổi.

Chức năng chính của Schmitt Trigger là loại bỏ nhiễu ở dạng sóng để ngăn dao động gây ra những thay đổi đầu ra không thể đoán trước. Schmitt triggers thường xuất hiện trong nhiều thiết bị cần giảm nhiễu đặc biệt là giữ mỗi trường tín hiệu analog với tín hiệu số.

Trigger Schmitt

Hình trên miêu tả một mạch input hoạt động bình thường(không sử dụng Trigger Schmitt ) với một ngưỡng duy nhất. Ta dễ dàng nhận thấy tại điểm số 1 và số 2, Lúc này tín hiệu bị nhiễu mức tín hiệu xuống dưới Ngưỡng tín hiệu của mức cao –> 1 xung được kéo xuống mức thấp đây là tín hiệu ta không muốn, nó làm cho vi điều khiển ta xử lý sai.

Trigger Schmitt

Hình trên miêu tả một mạch input hoạt động với bộ Trigger Schmitt với ngưỡng điện áp cao (upper Threshold) và ngưỡng điện áp thấp (lower threshold) tức là nó có 2 ngưỡng để so sánh. Ta thấy tại điểm số 1  Lúc này tín hiệu bị nhiễu mức tín hiệu xuống dưới Ngưỡng tín hiệu nằm ở giữa ngưỡng điện áp vào điện áp thấp (hysteresis) –> Xung vẫn được giữ ở mức tín hiệu ta mong muốn.

Như chúng ta đã biết việc đọc tín hiệu đưa vào chân I/O bị ảnh hưởng bởi :

  • Nhiễu thâm nhập
  • Sườn xung qua nhanh or quá chậm

Trong khi đó mạch nhận tiếp nhận tín hiệu Vin thực hiện phân biệt tín hiệu bằng ngưỡng điện áp VT nào đó để quyết định ngõ ra Vout là cao hay thấp. Sự bất định xảy ra khi nhiễu thâm nhập đúng vào lúc điện áp ở sườn xung xấp xỉ với ngưỡng phân biệt mức logic VT.

Trigger Schmitt

Vì vậy bộ Trigger Schmitt  được đặt tại đây giúp giải quyết các vấn đề trên. Chi tiết về TTL Schmitt Trigger các bạn đọc thêm tại đây.

 

Lập trình chức năng GPIO INPUT - STM32F103C8T6

4/ Điện trở  Pull-up(kéo lên) và Pull-down(kéo xuống)

Khi cấu hình chân I/O  ở chế độ INPUT MODE, thì tại chân đó chúng ta có thể chọn điện trở để định mức điện áp trước tại chân đó là mức HIGH hay mức LOW.

+ Pull-up : I/O pin sẽ được kéo lên nguồn qua trở, lúc này mức điệp áp trước đặt tại chân đó là mức HIGH.

+ Pull-down : I/O pin sẽ được kéo xuống đất qua trở, lúc này mức điện áp đặt tại chân là mức LOW.

+ No Pull-up, pull-down : I/O pin không được kéo lên nguồn hoặc được kéo xuống đất, lúc này chân I/O sẽ ở mức điện áp thả nổi nằm giữa mức HIGHLOW gọi là Input Floating

pull-up, pull - down

Pull-Down resistor

pull-up, pull down

Pull-up resistor

Lựa chọn chân trên kit STM32F103C8T6:

Lập trình GPIO nhấp nháy Led PC13 – STM32F103C8T6

Đặt Vấn đề và giải quyết : Đối với example này chúng ta sẽ chọn một chân I/O được cấu hình làm chân Input, ở đây chúng ta sẽ chọn chân PA0 được cấu hình INPUT MODE kết nối với một nút bấm để thực hiện test. Ngoài ra ở Port C chân thứ 13, trên kit đã thiết kế sẵn một đèn led, chúng ta sẽ sử dụng đèn led để hiển thị trạng thái.

Sơ đồ kết nối:

Lập trình chức năng GPIO INPUT - STM32F103C8T6

B, Dev Code

Việc đầu tiên chúng ta cần làm là cấp clock cho ngoại vi :

GPIOA, GPIOB, GPIOC… sử dụng clock cấp ở Bus APB2 có tần số xung nhịp 72Mhz ,nhưng các chân chức năng I/O sử dụng tốc độ clock tối đa 50Mhz
– Cấp clock cho GPIO, Trong bài này chúng ta sử dụng clock mặc định của hệ thống với tần số là 72Mhz.
SystemInit(); /*Initialize the Embedded Flash Interface*/
SystemCoreClockUpdate(); /*Update SystemCoreClock */

– Khởi tạo hàm cấu hình cấu hình GPIO cho PC13

GPIO_InitTypeDef GPIO_InitStructure;
/*kích hoạt clock của ngoại vi GPIOC*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); 
/*lựa chọn chế độ là ouput push-pull*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*lựa chọn chân Pin là PC13*/
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13;
/*lựa chọn tốc độ là 2Mhz*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	
GPIO_Init(GPIOC,&GPIO_InitStructure);
– Khởi tạo hàm cấu hình INPUT cho PA0
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC,&GPIO_InitStructure);
– Hàm kiểm tra nếu PA0 được kéo xuống thấp, hay nút bấm được nhấn thực hiện việc blink led PC13
while(1)
{
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)
	{
	        GPIO_SetBits(GPIOC, GPIO_Pin_13);
		Fn_Delay_ms(1000);
		GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	        Fn_Delay_ms(1000);
	}
			
}

–> Như vậy là các bạn đã tìm hiểu xong về INPUT MODE của ngoại vi GPIO

Link tải source tại đây

Chúc bạn thành công!