จากบทความก่อนหน้านี้ได้ทดลองควบคุมการนำออกสัญญาณดิจิทัลด้วยการขับวงจรแอลอีดีที่เชื่อมต่อกับบอร์ดไมโครคอนโทรลเลอร์ STM32 ทั้งแบบ Cortex-M0, Cortex-M3 และ Cortex-M4 ในบทความนี้กล่าวถึงการใช้งานขาเพื่อนำเข้าสัญญาณดิจิทัล และใช้ตัวอย่างการต่อวงจรสวิตช์เพื่อควบคุมการติดหรือดับของหลอดแอลอีดีดังภาพที่ 1
คำสั่งตั้งค่า
ตั้งแต่บทความก่อนหน้านี้เราได้ใช้งาน GPIO กันไปแล้วเพื่อทำการสั่งให้หลอดแอลอีดีอีสว่างและดับซึ่งต้องไปตั้งค่าเปิดการใช้งานขาในฟังก์ชัน MX_GPIO_Init() อันเป็นฟังก์ชันที่โปรแกรม STM32CubeIDE/STM32CubeMX สร้างให้ใช้งานเพื่อใส่ชุดคำสั่งสำหรับจัดการกับ GPIO ตามที่ตั้งค่าไว้ หรือเขียนโค้ดเพิ่มเติม ซึ่งคำสั่งสำหรับเปิดการทำงานของ GPIO คือ
HAL_GPIO_Init( กลุ่มของพอร์ต, &ตัวแปรตั้งค่า )
ส่วนคำสั่งสำหรับเปิดการเชื่อมสัญญาณนาฬิกาเข้ากับพอร์ตเป็นดังนี้
__HAL_RCC_GPIOF_CLK_ENABLE()
__HAL_RCC_GPIOA_CLK_ENABLE()
กำหนดหน้าที่ของ GPIO
ขั้นตอนของการกำหนดหน้าที่ขา คือ
- เปิดการใช้กลุ่มของ GPIO
- กำหนดให้ขาที่ต้องการใช้มีสถานะเริ่มต้น
- สร้างตัวแปรประเภท GPIO_InitTypeDef เพื่อใช้สำหรับเก็บการตั้งค่า
- กำหนดการตั้งค่าในคุณสมบัติ Pin, Mide และ Pull หรือ Speed ให้แก่ตัวแปรในข้อ 1
- เรียกใช้คำสั่งตั้งค่าด้วยตัวแปรที่ผ่านการกำหนดค่าแล้วในข้อ 2
ซึ่งรหัสคำสั่งที่ได้จะออกมาเป็นดังนี้
__HAL_RCC_ชื่อกลุ่มGPIO_CLK_ENABLE();
HAL_GPIO_WritePin( ชื่อกลุ่มGPIO, ชื่อขา, GPIO_PIN_RESET );
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = ชื่อขา;
GPIO_InitStruct.Mode = โหมดของขา;
GPIO_InitStruct.Pull = สถานะการมีวงจรพูลอัพ;
GPIO.InitStruct.Spedd = ความเร็วของการทำงาน;
HAL_GPIO_Init( ชื่อกลุ่มGPIO, &GPIO_InitStruct );
คำสั่งอ่านข้อมูลดิจิทัล
การอ่านค่าข้อมูลดิจิทัลจากขานำเข้าสัญญาณจะต้องกำหนดให้ขานั้นมีการทำงานเป็น GPIO_Input ในขั้นตอนของการตั้งค่าขา และใช้คำสั่งสำหรับนำเข้าสัญญาณดิจิทัลดังนี้
ค่าที่ได้รับ = HAL_GPIO_ReadPin( ชื่อกลุ่มGPIO, ชื่อขาที่ต้องการอ่านค่า )
ตัวอย่างโปรแกรม
การต่อวงจรทดสอบ
ตัวอย่างโปรแกรมสำหรับทดสอบการนำเข้าสัญญาณดิจิทัลจากขาของบอร์ดไมโครคอนโทรลเลอร์ STM32 เป็นดังภาพที่ 2 และ 3 โดยต่อขานำเข้าสัญญาณ (สายเส้นเหลืองจากภาพที่ 2) เข้ากับขา PA3 ของ STM32F030F4P6 (ดังภาพที่ 3)
STM32F030F4P6
หลังจากการต่อวงจรในภาพที่ 2 และ 3 เสร็จ ขั้นตอนต่อไปคือการเขียนโปรแกรม โดยเริ่มต้นจากการสร้างโครงงานแบบ STM32 Project ดังภาพที่ 4 และให้ดำเนินการตั้งค่าขาการทำงานโดยให้ PA4 เป็น GPIO_Output และ PA3 เป็น GPIO_Input ดังภาพที่ 5
เมื่อจัดการเรื่องการตั้งค่าขาและสัญญาณนาฬิกาจะได้ไฟล์ต่าง ๆ ที่โปรแกรม STM32CubeMX สร้างให้ และให้แก้ไข main.c ในฟังก์ชัน main ดังต่อไปนี้
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
int pa3Value=0;
while (1)
{
pa3Value = HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_3 );
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, pa3Value);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
/*Configure GPIO pin : PA3 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
หลังจากนั้นให้ตั้งค่าการคอมไพล์เป็นแบบ Release (อธิบายในบทความก่อนหน้านี้) และคอมไพล์จะได้ผลลัพธ์ดังภาพที่ 6 และ 7
ผลลัพธ์การทำงาน
สุดท้ายอัพโหลดโปรแกรมเข้าบอร์ดไมโครคอนโทรลเลอร์ และเมื่อเปลี่ยนโหมดเป็นโหมดทำงาน ผลการทำงานจะเป็นดังภาพที่ 8 คือ ถ้าไม่กดสวิตช์หลอดแอลอีดีที่ต่อกับ PA4 จะดับ และเมื่อกดสวิตช์จะทำให้หลอดสว่างดังภาพที่ 9
สำหรับบอร์ดคอนโทรลเลอร์ Cortex-M3 และ Cortex-M4 ให้เลือกขาที่เป็นขา GPIO_Output และ GPIO_Input หลังจากนั้นเปลี่ยนแปลงชื่อขาและกลุ่มของขาให้ถูกต้องการทำงานจะเหมือนกันกับการใช้ Cortex-M0
สรุป
จากบทความนี้จะได้ว่า การเขียนโปรแกรมเพื่อใช้งานกับ Cortex-M0/M3 หรือ M4 นั้นมีหลักการสั่งงานที่เหมือนกัน แต่ในไมโครคอนโทรลเลอร์แต่ละรุ่นมีวงจรภายในที่แจกจ่างเพิ่มเติมหรือตัดออกไม่เท่ากัน โดยสรุปแล้ว ขั้นตอนการพัฒนาโปรแกรมประกอบด้วย
- สร้างโครงงานสำหรับไมโครคอนโทรลเลอร์ที่ต้องการใช้งาน
- กำหนดบทบาทหน้าที่ของขาใช้งาน ดังนี้
- ขาสำหรับเชื่อมต่อกับวงจรสร้างสัญญาณนาฬิกา
- กำหนดขานำออกสัญญาณ
- กำหนดขานำเข้าสัญญาณ
- นำเข้าสัญญาณดิจิทัล
- นำเข้าสัญญาณแอนาล็อก
- ตั้งค่าสัญญาณนาฬิกา
- ให้โปรแกรมสร้างรหัสคำสั่งต้นแบบ
- แก้ไขโปรแกรมเพื่อให้ทำงานที่ต้องการ
- คอมไพล์
- อัพโหลดเข้าบอร์ด
- ทดสอบการทำงาน ถ้าผิดพลาดให้ทบทวนการตั้งค่าในขั้นตอน 2 และ 3 หรือตรวจสอบแก้ไขโปรแกรมและคอมไพล์ อัพโหลดและทดสอบซ้ำ
ดังนั้น ในบทความชุดนี้จะกล่าวถึงส่วนของการเขียนโปรแกรมร่วมกัน และจะแยกการใช้งานพิเศษออกเป็นบทความเป็นกรณีศึกษา สุดท้ายนี้ขอให้สนุกกับการเขียนโปรแกรมครับ
(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-07-24, 2021-07-26, 2021-10-29