บทนำ

General Purpose Input/Output (GPIO) เป็นพินบนไมโครคอนโทรลเลอร์ CH32V003 ที่สามารถกำหนดค่าให้ทำงานเป็นอินพุตหรือเอาต์พุตดิจิทัล รวมถึงฟังก์ชันพิเศษอื่นๆ ได้ พอร์ต GPIO หลักๆ บน CH32V003 ได้แก่ Port A, Port C และ Port D

การใช้งาน GPIO จำเป็นต้องมีการกำหนดค่า (Configure) ให้กับพินที่ต้องการก่อน โดยใช้ไลบรารีมาตรฐาน (Standard Peripheral Library) หรือ HAL (Hardware Abstraction Layer) ที่ WCH จัดเตรียมให้

ขั้นตอนหลักในการกำหนดค่า GPIO

1. เปิดสัญญาณนาฬิกา (Enable Clock):

จำเป็นต้องเปิดสัญญาณนาฬิกาให้กับ GPIO Port ที่ต้องการใช้งานก่อนเสมอ ผ่าน RCC (Reset and Clock Control) มิฉะนั้น Port จะไม่ทำงาน

// ตัวอย่าง: เปิด Clock ให้ Port C และ Port D
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
// สำหรับ Port A: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2. กำหนดค่าพิน (Configure Pin):

ใช้ Structure GPIO_InitTypeDef เพื่อกำหนดโหมด, ความเร็ว (ถ้าจำเป็น), และพินที่ต้องการ จากนั้นเรียกฟังก์ชัน GPIO_Init()

GPIO_InitTypeDef GPIO_InitStruct = {0}; // ประกาศและเคลียร์ค่า Structure

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_x;      // เลือกพิน เช่น GPIO_Pin_0, GPIO_Pin_1, ...
                                             // สามารถใช้ | รวมหลายพินได้ เช่น GPIO_Pin_0 | GPIO_Pin_1
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_xxx;  // เลือกโหมดการทำงาน (ดูรายละเอียดด้านล่าง)
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_yyy; // เลือกความเร็ว (สำหรับ Output/AF)
                                             // เช่น GPIO_Speed_50MHz, GPIO_Speed_10MHz, GPIO_Speed_2MHz

// เรียกใช้ฟังก์ชัน Init สำหรับ Port ที่ต้องการ (ตัวอย่างคือ Port C)
GPIO_Init(GPIOC, &GPIO_InitStruct);

โหมด GPIO แต่ละแบบและการใช้งาน (GPIO_Mode_xxx)

CH32V003 รองรับโหมดการทำงานของ GPIO ดังนี้:

1. GPIO_Mode_IN_FLOATING (Input Floating – อินพุตแบบลอย)

  • ลักษณะ: โหมดอินพุตพื้นฐาน ไม่ต่อ Pull-up/Pull-down ภายใน สถานะพินขึ้นกับสัญญาณภายนอก (หากไม่ต่ออะไร สถานะจะไม่แน่นอน).
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStruct); // หรือ Port อื่น
  • การใช้งาน: อ่านค่าดิจิทัล (0 หรือ 1) จากพิน. uint8_t pin_state = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_x);

2. GPIO_Mode_IPU (Input Pull-up – อินพุตแบบมีพูลอัป)

  • ลักษณะ: โหมดอินพุตที่มีตัวต้านทาน Pull-up ภายในต่อกับ VCC หากไม่มีสัญญาณภายนอก จะอ่านได้ค่า High (1) เหมาะกับสวิตช์ที่ต่อลง Ground.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC, &GPIO_InitStruct);
  • การใช้งาน: อ่านค่าดิจิทัล (ไม่กด = 1, กดลง GND = 0). uint8_t pin_state = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_x);

3. GPIO_Mode_IPD (Input Pull-down – อินพุตแบบมีพูลดาวน์)

  • ลักษณะ: โหมดอินพุตที่มีตัวต้านทาน Pull-down ภายในต่อกับ GND หากไม่มีสัญญาณภายนอก จะอ่านได้ค่า Low (0) เหมาะกับสวิตช์ที่ต่อกับ VCC.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStruct);
  • การใช้งาน: อ่านค่าดิจิทัล (ไม่กด = 0, กดต่อ VCC = 1). uint8_t pin_state = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_x);
  • หมายเหตุ: การเลือก Pull-up/Pull-down บางครั้งอาจต้องกำหนดผ่าน Register OUTDR เพิ่มเติมใน CH32V003 แต่ไลบรารีมักจัดการส่วนนี้ให้เมื่อเลือกโหมด IPU หรือ IPD.

4. GPIO_Mode_AIN (Analog Input – อินพุตอะนาล็อก)

  • ลักษณะ: ใช้สำหรับรับสัญญาณแรงดันไฟฟ้าแบบต่อเนื่อง เพื่อป้อนเข้าสู่โมดูล ADC (Analog-to-Digital Converter) Digital Buffer ของพินจะถูกปิด.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // ไม่ต้องกำหนด Speed สำหรับโหมดนี้ GPIO_Init(GPIOC, &GPIO_InitStruct);
  • การใช้งาน: ต้องกำหนดค่าและอ่านค่าผ่านโมดูล ADC โดยตรง.

5. GPIO_Mode_Out_PP (Output Push-Pull – เอาต์พุตแบบพุชพูล)

  • ลักษณะ: โหมดเอาต์พุตมาตรฐาน ขับสัญญาณ High (VCC) และ Low (GND) ได้โดยตรง เหมาะสำหรับขับ LED, ส่งสัญญาณดิจิทัล.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // เลือกความเร็วที่เหมาะสม GPIO_Init(GPIOC, &GPIO_InitStruct);
  • การใช้งาน: เขียนค่าดิจิทัล (0 หรือ 1) ไปยังพิน. GPIO_WriteBit(GPIOC, GPIO_Pin_x, Bit_SET); // ทำให้พินเป็น High (1) GPIO_WriteBit(GPIOC, GPIO_Pin_x, Bit_RESET); // ทำให้พินเป็น Low (0) // หรือใช้ฟังก์ชัน Set/Reset โดยตรง // GPIO_SetBits(GPIOC, GPIO_Pin_x); // High // GPIO_ResetBits(GPIOC, GPIO_Pin_x); // Low

6. GPIO_Mode_Out_OD (Output Open-Drain – เอาต์พุตแบบโอเพนเดรน)

  • ลักษณะ: โหมดเอาต์พุตที่ขับได้เฉพาะ Low (GND) เมื่อต้องการให้เป็น High จะปล่อยพินเป็นสถานะ High-Impedance (Hi-Z) ต้องใช้ตัวต้านทาน Pull-up ภายนอกต่อกับ VCC เหมาะสำหรับบัสแบบหลายอุปกรณ์ เช่น I2C.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // เลือกความเร็ว GPIO_Init(GPIOC, &GPIO_InitStruct);
  • การใช้งาน: เขียนค่าดิจิทัล (ต้องมี Pull-up ภายนอก). GPIO_WriteBit(GPIOC, GPIO_Pin_x, Bit_RESET); // ขับ Low (GND) GPIO_WriteBit(GPIOC, GPIO_Pin_x, Bit_SET); // ปล่อย Hi-Z (จะเป็น High ถ้ามี Pull-up) // หรือใช้ // GPIO_ResetBits(GPIOC, GPIO_Pin_x); // ขับ Low // GPIO_SetBits(GPIOC, GPIO_Pin_x); // ปล่อย Hi-Z

7. GPIO_Mode_AF_PP (Alternate Function Push-Pull – ฟังก์ชันทางเลือกแบบพุชพูล)

  • ลักษณะ: มอบหมายการควบคุมพินให้กับ Peripheral ภายใน (เช่น UART TX, SPI MOSI/SCK, Timer PWM) โดย Peripheral นั้นจะขับสัญญาณแบบ Push-Pull.
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // เลือกความเร็ว GPIO_Init(GPIOC, &GPIO_InitStruct); // ต้องมีการกำหนดค่า Peripheral ที่เกี่ยวข้อง และอาจต้องตั้งค่า Pin Remapping เพิ่มเติม
  • การใช้งาน: ควบคุมผ่าน Peripheral ที่กำหนด (เช่น สั่ง UART ให้ส่งข้อมูล).

8. GPIO_Mode_AF_OD (Alternate Function Open-Drain – ฟังก์ชันทางเลือกแบบโอเพนเดรน)

  • ลักษณะ: มอบหมายการควบคุมพินให้กับ Peripheral ภายใน (เช่น I2C SDA/SCL) โดย Peripheral นั้นจะขับสัญญาณแบบ Open-Drain (ต้องใช้ Pull-up ภายนอก).
  • การกำหนดค่า: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // เลือกความเร็ว GPIO_Init(GPIOC, &GPIO_InitStruct); // ต้องมีการกำหนดค่า Peripheral (เช่น I2C) และอาจต้องตั้งค่า Pin Remapping
  • การใช้งาน: ควบคุมผ่าน Peripheral ที่กำหนด (เช่น การทำงานของ I2C).

ข้อควรจำเพิ่มเติม

  • การเลือกพิน (GPIO_Pin_x): ใช้ค่าคงที่ที่กำหนดไว้ เช่น GPIO_Pin_0, GPIO_Pin_1, … ตรวจสอบ Datasheet สำหรับพินสูงสุดของแต่ละพอร์ต.
  • ความเร็ว (GPIO_Speed_yyy): สำคัญสำหรับโหมด Output/AF มีผลต่อ Slew Rate และการใช้พลังงาน เลือกให้เหมาะสมกับความเร็วสัญญาณที่ต้องการ.
  • Alternate Function (AF) และ Remapping: การใช้ AF ต้องตรวจสอบจาก Datasheet ว่าพินใดรองรับฟังก์ชันใด และอาจต้องกำหนดค่า Pin Remapping ใน Register AFIO_PCFR1 เพื่อให้ Peripheral เชื่อมต่อกับพินที่ถูกต้อง.
  • Datasheet/Reference Manual: คือเอกสารอ้างอิงที่สำคัญที่สุด ควรศึกษาประกอบเสมอเพื่อความถูกต้องและรายละเอียดเชิงลึก.