Midterm Big Home#1

04 - 63050025 - นายปฏิภาณ ยะคะเรศ

19 - 63050360 - นายอนพัทย์ จีรพัฒน์ดิษกุล 

#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


/*******************************************************************************
* Macros
*******************************************************************************/
/* LED blink timer clock value in Hz  */
#define LED_BLINK_TIMER_CLOCK_HZ          (10000)

/* LED blink timer period value */
#define LED_BLINK_TIMER_PERIOD            (9999)


/*******************************************************************************
* Global Variables
*******************************************************************************/
bool timer_interrupt_flag = false;
bool led_blink_active_flag = true;

/* Variable for storing character read from terminal */
uint8_t uart_read_value;

/* Timer object used for blinking the LED */
cyhal_timer_t led_blink_timer;


/*******************************************************************************
* Function Prototypes
*******************************************************************************/
void timer_init(void);
static void isr_timer(void *callback_arg, cyhal_timer_event_t event);

/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function. It sets up a timer to trigger a periodic interrupt.
* The main while loop checks for the status of a flag set by the interrupt and
* toggles an LED at 1Hz to create an LED blinky. Will be achieving the 1Hz Blink
* rate based on the The LED_BLINK_TIMER_CLOCK_HZ and LED_BLINK_TIMER_PERIOD
* Macros,i.e. (LED_BLINK_TIMER_PERIOD + 1) / LED_BLINK_TIMER_CLOCK_HZ = X ,Here,
* X denotes the desired blink rate. The while loop also checks whether the
* 'Enter' key was pressed and stops/restarts LED blinking.
*
* Parameters:
*  none
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

#if defined (CY_DEVICE_SECURE)
    cyhal_wdt_t wdt_obj;

    /* Clear watchdog timer so that it doesn't trigger a reset */
    result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
    CY_ASSERT(CY_RSLT_SUCCESS == result);
    cyhal_wdt_free(&wdt_obj);
#endif /* #if defined (CY_DEVICE_SECURE) */

    /* Initialize the device and board peripherals */
    result = cybsp_init();

    /* Board init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    /* Initialize retarget-io to use the debug UART port */
    result = cy_retarget_io_init_fc(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
                                        CYBSP_DEBUG_UART_CTS,CYBSP_DEBUG_UART_RTS,
                                        CY_RETARGET_IO_BAUDRATE);

    /* retarget-io init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Initialize the User LED */
    result = cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT,
                             CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);

    /* GPIO init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
    printf("\x1b[2J\x1b[;H");

    printf("****************** "
           "HAL: Hello World! Example "
           "****************** \r\n\n");

    printf("Hello World!!!\r\n\n");
    printf("For more projects, "
           "visit our code examples repositories:\r\n\n");

    printf("https://github.com/Infineon/"
           "Code-Examples-for-ModusToolbox-Software\r\n\n");

    /* Initialize timer to toggle the LED */
    timer_init();

    printf("Press 'Enter' key to pause or "
           "resume blinking the user LED \r\n\r\n");

    for (;;)
    {
        /* Check if 'Enter' key was pressed */
        if (cyhal_uart_getc(&cy_retarget_io_uart_obj, &uart_read_value, 1)
             == CY_RSLT_SUCCESS)
        {
            if (uart_read_value == '\r')
            {
                /* Pause LED blinking by stopping the timer */
                if (led_blink_active_flag)
                {
                    cyhal_timer_stop(&led_blink_timer);

                    printf("LED blinking paused \r\n");
                }
                else /* Resume LED blinking by starting the timer */
                {
                    cyhal_timer_start(&led_blink_timer);

                    printf("LED blinking resumed\r\n");
                }

                /* Move cursor to previous line */
                printf("\x1b[1F");

                led_blink_active_flag ^= 1;
            }
        }
        /* Check if timer elapsed (interrupt fired) and toggle the LED */
        if (timer_interrupt_flag)
        {
            /* Clear the flag */
            timer_interrupt_flag = false;

            /* Invert the USER LED state */
            cyhal_gpio_toggle(CYBSP_USER_LED);
        }
    }
}


/*******************************************************************************
* Function Name: timer_init
********************************************************************************
* Summary:
* This function creates and configures a Timer object. The timer ticks
* continuously and produces a periodic interrupt on every terminal count
* event. The period is defined by the 'period' and 'compare_value' of the
* timer configuration structure 'led_blink_timer_cfg'. Without any changes,
* this application is designed to produce an interrupt every 1 second.
*
* Parameters:
*  none
*
* Return :
*  void
*
*******************************************************************************/
 void timer_init(void)
 {
    cy_rslt_t result;

    const cyhal_timer_cfg_t led_blink_timer_cfg =
    {
        .compare_value = 0,                 /* Timer compare value, not used */
        .period = LED_BLINK_TIMER_PERIOD,   /* Defines the timer period */
        .direction = CYHAL_TIMER_DIR_UP,    /* Timer counts up */
        .is_compare = false,                /* Don't use compare mode */
        .is_continuous = true,              /* Run timer indefinitely */
        .value = 0                          /* Initial value of counter */
    };

    /* Initialize the timer object. Does not use input pin ('pin' is NC) and
     * does not use a pre-configured clock source ('clk' is NULL). */
    result = cyhal_timer_init(&led_blink_timer, NC, NULL);

    /* timer init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Configure timer period and operation mode such as count direction,
       duration */
    cyhal_timer_configure(&led_blink_timer, &led_blink_timer_cfg);

    /* Set the frequency of timer's clock source */
    cyhal_timer_set_frequency(&led_blink_timer, LED_BLINK_TIMER_CLOCK_HZ);

    /* Assign the ISR to execute on timer interrupt */
    cyhal_timer_register_callback(&led_blink_timer, isr_timer, NULL);

    /* Set the event on which timer interrupt occurs and enable it */
    cyhal_timer_enable_event(&led_blink_timer, CYHAL_TIMER_IRQ_TERMINAL_COUNT,
                              7, true);

    /* Start the timer with the configured settings */
    cyhal_timer_start(&led_blink_timer);
 }


/*******************************************************************************
* Function Name: isr_timer
********************************************************************************
* Summary:
* This is the interrupt handler function for the timer interrupt.
*
* Parameters:
*    callback_arg    Arguments passed to the interrupt callback
*    event            Timer/counter interrupt triggers
*
* Return:
*  void
*******************************************************************************/
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
{
    (void) callback_arg;
    (void) event;

    /* Set the interrupt flag and process it from the main while(1) loop */
    timer_interrupt_flag = true;
}
# PRESENTING CODE

LAB hello world

Descriptions:

โปรแกรมนี้เป็นตัวอย่างการใช้งาน Timer บนไมโครคอนโทรลเลอร์ Cypress PSoC 6 เพื่อสร้างการกระพริบ LED ที่มีความถี่ 1Hz โดยให้ LED กระพริบเปิด-ปิดทุกวินาที โดยผู้ใช้สามารถหยุดหรือเริ่มการกระพริบได้โดยการกดปุ่ม Enter จากคีบอร์ด. โปรแกรมจะเริ่มต้นด้วยการกำหนดค่าต่าง ๆ เช่นตั้งค่า Timer ให้ทำงานในโหมดต่าง ๆ เพื่อให้ได้ความถี่และโปรแกรมรองรับการควบคุม LED ผ่านการกระพริบ และรับข้อมูลจาก UART สำหรับการหยุดหรือเริ่มการกระพริบ LED

Important Variables:

timer_interrupt_flag: ตัวแปรสถานะที่ใช้ระบุว่า Timer ได้สร้าง interrupt หรือไม่ led_blink_active_flag: ตัวแปรสถานะที่ใช้ระบุว่า LED กำลังกระพริบหรือไม่

uart_read_value: ตัวแปรที่ใช้อ่านค่าจาก UART สำหรับตรวจสอบการกดปุ่ม Enter led_blink_timer: ตัวแปรที่ใช้เก็บ Timer object สำหรับการควบคุมการกระพริบ LED

Applications:

ใช้เป็นตัวอย่างการใช้งาน Timer บนไมโครคอนโทรลเลอร์ Cypress PSoC 6 ใช้เป็นตัวอย่างการใช้งานการระบบกระพริบ LED และรับข้อมูลจาก UART สำหรับควบคุมการหยุดหรือเริ่มการกระพริบ LED ผ่านทางคีย์บอร์ด ตัวอย่างการใช้งานตัวกระพริบ LED เพื่อแสดงถึงการใช้งาน Timer ในลักษณะของการกระพริบ LED ที่มีความถี่แน่นอน 1Hz


#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


int main(void)
{
    cy_rslt_t result;
    result = cybsp_init();
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    result = cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    __enable_irq();

    printf("\x1b[2J\x1b[;H");

    for (;;)
    {
        cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_ON);
        printf("LED ON \r\n");
        cyhal_system_delay_ms(5000);
        cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_OFF);
        printf("LED OFF \r\n");
        cyhal_system_delay_ms(5000);
    }
}

/* [] END OF FILE */
# PRESENTING CODE

LAB101 GPIO-HAL_LED_Blink_Template

Descriptions:

โปรแกรมนี้มีวัตถุประสงค์เพื่อควบคุมการเปิด-ปิดของ LED บนบอร์ด Cypress PSoC 6 ผ่าน GPIO (General Purpose Input/Output) ซึ่งเป็นขาของไมโครคอนโทรลเลอร์ โดยโปรแกรมจะทำการเริ่มต้นการทำงานด้วยการตั้งค่าและเริ่มต้นการทำงานของบอร์ดผ่านฟังก์ชัน cybsp_init() และตั้งค่าส่วนต่าง ๆ ที่เกี่ยวข้อง รวมถึงการกำหนดค่าขา GPIO ที่เชื่อมต่อกับ LED (CYBSP_USER_LED) โดยให้เป็นตัวอย่างการใช้งาน GPIO ในโปรแกรมนี้ โปรแกรมจะทำการเปิด LED และพิมพ์ข้อความ "LED ON" ทางคอนโซล จากนั้นจะรอเวลา 5 วินาที และทำการปิด LED พร้อมพิมพ์ข้อความ "LED OFF" ทางคอนโซล นับรอบไปเรื่อย ๆ โดยมีการรอเวลา 5 วินาทีระหว่างการเปิด-ปิด LED

Important Variables:

result: เก็บผลลัพธ์จากการเรียกใช้ฟังก์ชันต่าง ๆ เพื่อตรวจสอบว่าทำงานสำเร็จหรือไม่ CYBSP_USER_LED: ค่าที่ระบุขา GPIO ที่เชื่อมต่อกับ LED CYBSP_LED_STATE_ON, CYBSP_LED_STATE_OFF: ค่าสถานะของ LED เมื่อทำการเปิดและปิด

__enable_irq(): เปิดใช้งานการสั่งการไปยังหน่วยควบคุมการขาดการเข้ารหัส (interrupt) cyhal_gpio_write(): เปลี่ยนสถานะของ GPIO เพื่อควบคุมการเปิด-ปิดของ LED cyhal_system_delay_ms(): ทำการรอเวลาในหน่วยมิลลิวินาที

Applications:

การทำทดสอบการทำงานของ GPIO และการควบคุม LED บนบอร์ด Cypress PSoC 6 การทดสอบการใช้งานฟังก์ชันของ Cyhal GPIO และการสั่งการแบบ Polling โดยการรอเวลาระหว่างการเปิด-ปิด LED บนบอร์ด

#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


/*******************************************************************************
* Macros
*******************************************************************************/
/* LED blink timer clock value in Hz  */
#define LED_BLINK_TIMER_CLOCK_HZ          (10000)

/* LED blink timer period value */
#define LED_BLINK_TIMER_PERIOD            (9999)


/*******************************************************************************
* Global Variables
*******************************************************************************/
bool timer_interrupt_flag = false;
bool led_blink_active_flag = true;

/* Variable for storing character read from terminal */
uint8_t uart_read_value;

/* Timer object used for blinking the LED */
cyhal_timer_t led_blink_timer;


/*******************************************************************************
* Function Prototypes
*******************************************************************************/
void timer_init(void);
static void isr_timer(void *callback_arg, cyhal_timer_event_t event);

/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function. It sets up a timer to trigger a periodic interrupt.
* The main while loop checks for the status of a flag set by the interrupt and
* toggles an LED at 1Hz to create an LED blinky. Will be achieving the 1Hz Blink
* rate based on the The LED_BLINK_TIMER_CLOCK_HZ and LED_BLINK_TIMER_PERIOD
* Macros,i.e. (LED_BLINK_TIMER_PERIOD + 1) / LED_BLINK_TIMER_CLOCK_HZ = X ,Here,
* X denotes the desired blink rate. The while loop also checks whether the
* 'Enter' key was pressed and stops/restarts LED blinking.
*
* Parameters:
*  none
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

#if defined (CY_DEVICE_SECURE)
    cyhal_wdt_t wdt_obj;

    /* Clear watchdog timer so that it doesn't trigger a reset */
    result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
    CY_ASSERT(CY_RSLT_SUCCESS == result);
    cyhal_wdt_free(&wdt_obj);
#endif /* #if defined (CY_DEVICE_SECURE) */

    /* Initialize the device and board peripherals */
    result = cybsp_init();

    /* Board init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    /* Initialize retarget-io to use the debug UART port */
    result = cy_retarget_io_init_fc(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
                                        CYBSP_DEBUG_UART_CTS,CYBSP_DEBUG_UART_RTS,
                                        CY_RETARGET_IO_BAUDRATE);

    /* retarget-io init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Initialize the User LED */
    result = cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT,
                             CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);

    /* GPIO init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
    printf("\x1b[2J\x1b[;H");

    printf("****************** "
           "HAL: Hello World! Example "
           "****************** \r\n\n");

    printf("Hello World!!!\r\n\n");
    printf("For more projects, "
           "visit our code examples repositories:\r\n\n");

    printf("https://github.com/Infineon/"
           "Code-Examples-for-ModusToolbox-Software\r\n\n");

    /* Initialize timer to toggle the LED */
    timer_init();

    printf("Press 'Enter' key to pause or "
           "resume blinking the user LED \r\n\r\n");

    for (;;)
    {
        /* Check if 'Enter' key was pressed */
        if (cyhal_uart_getc(&cy_retarget_io_uart_obj, &uart_read_value, 1)
             == CY_RSLT_SUCCESS)
        {
            if (uart_read_value == '\r')
            {
                /* Pause LED blinking by stopping the timer */
                if (led_blink_active_flag)
                {
                    cyhal_timer_stop(&led_blink_timer);

                    printf("LED blinking paused \r\n");
                }
                else /* Resume LED blinking by starting the timer */
                {
                    cyhal_timer_start(&led_blink_timer);

                    printf("LED blinking resumed\r\n");
                }

                /* Move cursor to previous line */
                printf("\x1b[1F");

                led_blink_active_flag ^= 1;
            }
        }
        /* Check if timer elapsed (interrupt fired) and toggle the LED */
        if (timer_interrupt_flag)
        {
            /* Clear the flag */
            timer_interrupt_flag = false;

            /* Invert the USER LED state */
            cyhal_gpio_toggle(CYBSP_USER_LED);
        }
    }
}


/*******************************************************************************
* Function Name: timer_init
********************************************************************************
* Summary:
* This function creates and configures a Timer object. The timer ticks
* continuously and produces a periodic interrupt on every terminal count
* event. The period is defined by the 'period' and 'compare_value' of the
* timer configuration structure 'led_blink_timer_cfg'. Without any changes,
* this application is designed to produce an interrupt every 1 second.
*
* Parameters:
*  none
*
* Return :
*  void
*
*******************************************************************************/
 void timer_init(void)
 {
    cy_rslt_t result;

    const cyhal_timer_cfg_t led_blink_timer_cfg =
    {
        .compare_value = 0,                 /* Timer compare value, not used */
        .period = LED_BLINK_TIMER_PERIOD,   /* Defines the timer period */
        .direction = CYHAL_TIMER_DIR_UP,    /* Timer counts up */
        .is_compare = false,                /* Don't use compare mode */
        .is_continuous = true,              /* Run timer indefinitely */
        .value = 0                          /* Initial value of counter */
    };

    /* Initialize the timer object. Does not use input pin ('pin' is NC) and
     * does not use a pre-configured clock source ('clk' is NULL). */
    result = cyhal_timer_init(&led_blink_timer, NC, NULL);

    /* timer init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Configure timer period and operation mode such as count direction,
       duration */
    cyhal_timer_configure(&led_blink_timer, &led_blink_timer_cfg);

    /* Set the frequency of timer's clock source */
    cyhal_timer_set_frequency(&led_blink_timer, LED_BLINK_TIMER_CLOCK_HZ);

    /* Assign the ISR to execute on timer interrupt */
    cyhal_timer_register_callback(&led_blink_timer, isr_timer, NULL);

    /* Set the event on which timer interrupt occurs and enable it */
    cyhal_timer_enable_event(&led_blink_timer, CYHAL_TIMER_IRQ_TERMINAL_COUNT,
                              7, true);

    /* Start the timer with the configured settings */
    cyhal_timer_start(&led_blink_timer);
 }


/*******************************************************************************
* Function Name: isr_timer
********************************************************************************
* Summary:
* This is the interrupt handler function for the timer interrupt.
*
* Parameters:
*    callback_arg    Arguments passed to the interrupt callback
*    event            Timer/counter interrupt triggers
*
* Return:
*  void
*******************************************************************************/
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
{
    (void) callback_arg;
    (void) event;

    /* Set the interrupt flag and process it from the main while(1) loop */
    timer_interrupt_flag = true;
}
# PRESENTING CODE

LAB102 GPIO-PDL_LED_Blink_Template

Descriptions:

โค้ดนี้เป็นตัวอย่างการใช้งานบอร์ด Cypress PSoC 6 ในการควบคุม LED และสื่อสารผ่าน UART โดยใช้ไลบรารี Cypress Peripheral Driver Library (PDL).

Important Variables:

cybsp_init(): ทำการเริ่มต้นการใช้งานบอร์ดและอุปกรณ์ต่าง ๆ บนบอร์ด.

__enable_irq(): เปิดใช้งานระบบการขัดจังหวะ (interrupts).

Cy_SCB_UART_Init() และ Cy_SCB_UART_Enable(): กำหนดค่าและเปิดใช้งาน UART. Cy_GPIO_Set() และ Cy_GPIO_Clr(): ควบคุมการเปิด/ปิด LED โดยตรง. Cy_SCB_UART_PutString(): ส่งข้อความผ่าน UART.

result: ใช้เก็บผลลัพธ์จากการเริ่มต้นบอร์ดและอุปกรณ์. UART_context: ตัวแปรเก็บข้อมูลสถานะของ UART. CYBSP_USER_LED_PORT และ CYBSP_USER_LED_NUM: คือตำแหน่งของ LED บนบอร์ด.

Applications:

โปรแกรมนี้สามารถนำไปประยุกต์ใช้เพื่อทดสอบการทำงานของ LED และการสื่อสารผ่าน UART ในแอปพลิเคชันที่ต้องการควบคุมและตรวจสอบสถานะของอุปกรณ์. สามารถนำไปพัฒนาเป็นโปรแกรมควบคุมการทำงานของระบบได้ เช่น การเปิด/ปิด LED ตามต้องการ, การส่งข้อมูลผ่าน UART เพื่อติดตามสถานะ, หรือใช้เป็นบทเรียนในการใช้งาน GPIO และ UART ในบอร์ด Cypress PSoC 6.

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    /*BSP init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
    __enable_irq();


    /* Initialize the User LED */
    cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_ON);

    /* Initialize the user button */
    cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLDOWN, CYBSP_BTN_OFF);

    /* Initialize retarget-io to use the debug UART port. It sets up the standard input/output functions (such as printf)*/
    cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

    printf("\x1b[2J\x1b[;H");

    for (;;)
    {
    	//Button is active low
    	if(!cyhal_gpio_read(CYBSP_USER_BTN)){
            // Button is pressed
            cyhal_gpio_write(CYBSP_USER_LED3, CYBSP_LED_STATE_ON);
            printf("Button Pressed --> LED ON \r\n");
            cyhal_system_delay_ms(250);
        }

        else {
            // Button is not pressed
            cyhal_gpio_write(CYBSP_USER_LED3, CYBSP_LED_STATE_OFF);
            printf("Button not Pressed --> LED OFF \r\n");
            cyhal_system_delay_ms(250);
        }
    }
}
# PRESENTING CODE

LAB103 GPIO-HAL_Button_with_LED_Template

Descriptions:

โค้ดนี้เป็นตัวอย่างการใช้งานบอร์ด Cypress PSoC 6 ในการอ่านสถานะของปุ่ม (button) และควบคุมการเปิด/ปิด LED บนบอร์ด โดยใช้ไลบรารี Cypress Peripheral Driver Library (PDL) และ Cypress Hardware Abstraction Layer (HAL) สำหรับการสื่อสารผ่าน UART และ GPIO.

Important Variables:

cybsp_init(): ทำการเริ่มต้นการใช้งานบอร์ดและอุปกรณ์ต่างๆบนบอร์ด.

__enable_irq(): เปิดใช้งานระบบการขัดจังหวะ (interrupts).

cy_retarget_io_init(): ทำการกำหนดให้ I/O มีการเข้ารหัส/ถอดรหัสผ่าน UART ที่กำหนดไว้. Cy_GPIO_Read(): อ่านสถานะของปุ่ม ถ้าปุ่มถูกกด (active low) จะคืนค่า 0.

Cy_GPIO_Clr() และ Cy_GPIO_Set(): ควบคุมการเปิด/ปิด LED โดยตรง.

result: ใช้เก็บผลลัพธ์จากการเริ่มต้นบอร์ดและอุปกรณ์. CYBSP_USER_BTN_PORT และ CYBSP_USER_BTN_NUM: คือตำแหน่งของปุ่มบนบอร์ด. CYBSP_USER_LED1_PORT และ CYBSP_USER_LED1_NUM: คือตำแหน่งของ LED บนบอร์ด.

Applications:

โปรแกรมนี้สามารถนำไปประยุกต์ใช้ในการควบคุมการทำงานของระบบเมื่อมีการกดปุ่ม เช่น การสั่งงานหนึ่งอย่างในระบบควบคุม.

สามารถใช้เป็นตัวอย่างในการเรียนรู้การใช้งาน GPIO, UART และการตรวจจับการกดปุ่ม.

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
    /* Enable global interrupts */
    __enable_irq();

    // Embedded systems to redirect the standard input/output (I/O) functions like printf() and scanf()
    cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
    printf("\x1b[2J\x1b[;H");

    for (;;)
    {
    	//Button is active low -> 0 is pressed and 1 is not pressed.
    	if(!Cy_GPIO_Read(CYBSP_USER_BTN_PORT, CYBSP_USER_BTN_NUM)){
    		Cy_GPIO_Clr(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_NUM); // Turn On LED
    		printf("Button Pressed --> LED ON \r\n");
    		Cy_SysLib_Delay(500U);
    	}
    	else{
    		Cy_GPIO_Set(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_NUM);
    		printf("Button not Pressed --> LED OFF \r\n"); // Turn Off LED
    		Cy_SysLib_Delay(500U);
    	}
    }
}
/* [] END OF FILE */
# PRESENTING CODE

LAB104 GPIO-PDL_Button_with_LED_Template

Descriptions:

ในโปรแกรมนี้, โดยใช้ไลบรารีและไฟล์หัวข้อที่เกี่ยวข้อง (cy_pdl.h, cyhal.h, cybsp.h, cy_retarget_io.h), โปรแกรมจะเริ่มต้นด้วยการเรียกใช้ cybsp_init() เพื่อเริ่มต้นการใช้งานบอร์ดและอุปกรณ์. หากการเริ่มต้นไม่สำเร็จ, โปรแกรมจะใช้ CY_ASSERT(0) เพื่อหยุดการทำงาน. ต่อมา, โปรแกรมทำการเปิดใช้งาน global interrupts ด้วย __enable_irq() เพื่อให้โปรแกรมสามารถตอบสนองต่อการกระทำต่าง ๆ ได้. หลังจากนั้น, โปรแกรมใช้ cy_retarget_io_init() เพื่อทำการ redirect standard input/output (I/O) functions เช่น printf() และ scanf() ไปยัง embedded systems, ทำให้สามารถใช้คำสั่ง printf เพื่อพิมพ์ข้อความลงในคอนโซล. ในลูปหลัก, โปรแกรมตรวจสอบสถานะของปุ่ม (CYBSP_USER_BTN). หากปุ่มถูกกด (สถานะ active low), โปรแกรมจะเปิด LED (CYBSP_USER_LED0) และพิมพ์ข้อความ "Button Pressed --> LED ON" ในคอนโซล. หากปุ่มไม่ถูกกด, โปรแกรมจะปิด LED และพิมพ์ "Button not Pressed --> LED OFF". จากนั้น, โปรแกรมจะรอเป็นเวลา 500 milliseconds ก่อนที่จะทำงานในรอบต่อไป.

Important Variables:

result: ผลลัพธ์ของการเริ่มต้นบอร์ดหรืออุปกรณ์, ถ้าไม่สำเร็จจะทำให้โปรแกรมหยุดทำงาน.

Applications:

การใช้ cy_retarget_io_init() เพื่อ redirect standard I/O functions และการใช้ printf() เพื่อทำ debugging หรือการแสดงข้อมูลในระหว่างการทำงาน.

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"

#define GPIO_INTERRUPT_PRIORITY (7u)

//Interrupt handler
//static void button_isr(void *handler_arg, cyhal_gpio_event_t event)
//{
	//cyhal_gpio_toggle(CYBSP_USER_LED);
//}

// GPIO callback initialization structure
cyhal_gpio_callback_data_t cb_data =
{
	.callback     = button_isr,
	.callback_arg = NULL
};

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    /*BSP init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Initialize the User LED */
    result = cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
	/* GPIO init failed. Stop program execution */
	if (result != CY_RSLT_SUCCESS)
	{
		CY_ASSERT(0);
	}

	/* Initialize the user button */
	result = cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
	/* GPIO init failed. Stop program execution */
	if (result != CY_RSLT_SUCCESS)
	{
		CY_ASSERT(0);
	}

	/* Configure GPIO interrupt */
	//cyhal_gpio_register_callback(CYBSP_USER_BTN, &cb_data);
	//cyhal_gpio_enable_event(CYBSP_USER_BTN, CYHAL_GPIO_IRQ_FALL, GPIO_INTERRUPT_PRIORITY, true);

	cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_ON);
	cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLDOWN, CYBSP_BTN_OFF);


	/* Enable global interrupts */
    __enable_irq();


    for (;;)
    {
        	//Button is active low -> 0 is pressed and 1 is not pressed.
        	if(!Cy_GPIO_Read(CYBSP_USER_BTN_PORT, CYBSP_USER_BTN_NUM)){
        		Cy_GPIO_Clr(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_NUM); // Turn On LED
        		printf("Button Pressed --> LED ON \r\n");
        		Cy_SysLib_Delay(500U);
        	}
        	else{
        		Cy_GPIO_Set(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_NUM);
        		printf("Button not Pressed --> LED OFF \r\n"); // Turn Off LED
        		Cy_SysLib_Delay(500U);
        	}
}
# PRESENTING CODE

LAB105 GPIO_Interrupt_via_HAL_Template

Descriptions:

ในโปรแกรมนี้, โดยการใช้ไลบรารีและไฟล์หัวข้อที่เกี่ยวข้อง (cy_pdl.h, cyhal.h, cybsp.h, cy_retarget_io.h), โปรแกรมจะเริ่มต้นด้วยการเรียกใช้ cybsp_init() เพื่อเริ่มต้นการใช้งานบอร์ดและอุปกรณ์. หากการเริ่มต้นไม่สำเร็จ, โปรแกรมจะใช้ CY_ASSERT(0) เพื่อหยุดการทำงาน. ต่อมา, โปรแกรมทำการกำหนดค่าและเปิดใช้งาน GPIO สำหรับ LED (CYBSP_USER_LED) และปุ่ม (CYBSP_USER_BTN) โดยให้ LED เป็น OUTPUT และปุ่มเป็น INPUT. หากไม่สามารถกำหนดค่า GPIO สำเร็จ, โปรแกรมจะใช้ CY_ASSERT(0) เพื่อหยุดการทำงาน. ต่อมา, โปรแกรมทำการเปิดใช้งาน global interrupts ด้วย __enable_irq(). หลังจากนั้น, ในลูปหลัก, โปรแกรมตรวจสอบสถานะของปุ่ม (CYBSP_USER_BTN). หากปุ่มถูกกด (สถานะ active low), โปรแกรมจะเปิด LED (CYBSP_USER_LED1) และพิมพ์ข้อความบนคอนโซล "Button Pressed --> LED ON". หากปุ่มไม่ถูกกด, โปรแกรมจะปิด LED และพิมพ์ "Button not Pressed --> LED OFF". จากนั้น, โปรแกรมจะรอเป็นเวลา 500 milliseconds ก่อนที่จะทำงานในรอบต่อไป.

Important Variables:

GPIO_INTERRUPT_PRIORITY: ลำดับความสำคัญของ GPIO interrupt.

cb_data: โครงสร้างข้อมูลสำหรับการกำหนดค่า callback ของ GPIO.

ตัวแปรสำหรับ GPIO initialization และสถานะ LED/ปุ่ม ต่าง ๆ เช่น CYBSP_USER_LED, CYBSP_USER_BTN, CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_NUM.

result: ผลลัพธ์ของการเริ่มต้นบอร์ดหรืออุปกรณ์,

Applications:

การใช้งาน GPIO เพื่อควบคุม LED และตรวจสอบสถานะปุ่ม, ซึ่งสามารถนำไปใช้ในการสร้างตัวควบคุมหรือการตรวจสอบการกดปุ่มบนบอร์ดหรืออุปกรณ์อื่น ๆ.


#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


#define PORT_INTR_MASK  (0x00000001UL << CYBSP_USER_BTN_PORT_NUM)

void Interrupt_Handler(void){
	// Get interrupt cause
	uint32_t intrSrc = Cy_GPIO_GetInterruptCause0();
	/* Check if the interrupt was from the button's port */
	if(PORT_INTR_MASK == (intrSrc & PORT_INTR_MASK)){
		/* Clear the interrupt */
		Cy_GPIO_ClearInterrupt(CYBSP_USER_BTN_PORT, CYBSP_USER_BTN_NUM);
		// Toggle LED
		Cy_GPIO_Inv(CYBSP_USER_LED4_PORT, CYBSP_LED_RGB_GREEN_NUM);
	}
}

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    // Interrupt config structure
     cy_stc_sysint_t intrCfg =
 	{
 		/*.intrSrc =*/ CYBSP_USER_BTN_IRQ,
 		/*.intrPriority =*/ 3UL
 	};

     /* Initialize the interrupt with vector for Interrupt_Handler */
 	Cy_SysInt_Init(&intrCfg, &Interrupt_Handler);
 	/* Send the button through the glitch filter */
 	Cy_GPIO_SetFilter(CYBSP_USER_BTN_PORT, CYBSP_USER_BTN_NUM);

	
 	/* Enable the interrupt*/
 	NVIC_EnableIRQ(intrCfg.intrSrc);


    for (;;)
    {
    	/* Do nothing */
    }
}
/* [] END OF FILE */
# PRESENTING CODE

LAB106 GPIO_Interrupt_via_PDL_Template

Descriptions:

ในโปรแกรมนี้เริ่มต้นด้วยการเรียกใช้ไลบรารีและไฟล์หัวข้อของ Cypress (cy_pdl.h, cyhal.h, cybsp.h, cy_retarget_io.h) เพื่อให้โปรแกรมสามารถเข้าถึงฟังก์ชันและค่าคงที่ที่เกี่ยวข้องกับพีระมิด Cypress PSoC ได้. ในฟังก์ชันหลัก (main), โปรแกรมจะเรียกใช้ฟังก์ชัน cybsp_init() เพื่อเริ่มต้นการใช้งานบอร์ดและอุปกรณ์. หากไม่สามารถเริ่มต้นสำเร็จ, โปรแกรมจะใช้ CY_ASSERT(0) เพื่อหยุดการทำงาน.

หลังจากนั้น, โปรแกรมเปิดใช้งานการสั่งปัจจุบันของglobal interrupts ด้วย __enable_irq(). ต่อมา, โปรแกรมตั้งค่าและเปิดใช้งานการตรวจจับกดปุ่มด้วยการใช้ Cy_SysInt_Init() เพื่อกำหนดค่าทาง interrupt และกำหนด vector ของ interrupt ไปยังฟังก์ชัน Interrupt_Handler. ในฟังก์ชัน Interrupt_Handler, โปรแกรมตรวจสอบว่า interrupt มีที่มาจาก port ของปุ่มหรือไม่ และถ้าใช้, จะทำการเปิด/ปิด LED ที่เชื่อมต่อกับ port นั้น.

Important Variables:

PORT_INTR_MASK: คือค่ามาร์คของ interrupt ที่กำหนดให้กับปุ่ม, ในที่นี้เป็นปุ่มที่ CYBSP_USER_BTN_PORT_NUM (ในตัวอย่างคือ port ของปุ่ม).
 intrCfg: คือโครงสร้างที่ใช้กำหนดค่าและการตั้งค่า interrupt.
 Interrupt_Handler(): คือฟังก์ชันที่จะถูกเรียกเมื่อมีการเกิด interrupt จากปุ่ม, ทำหน้าที่ตรวจสอบและปรับสถานะของ LED และปิด interrupt.

Applications:

การใช้งาน interrupt เพื่อตรวจจับการกดปุ่มและทำการปรับสถานะของ LED ตามนั้น.


#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"


int main(void)
{
    cy_rslt_t result;
	cyhal_adc_t adc_obj;
	cyhal_adc_channel_t adc_chan_0_obj;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    __enable_irq();

    /* Initialize retarget-io to use the debug UART port */
	result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
	CY_ASSERT(result == CY_RSLT_SUCCESS);

	/* ADC conversion result. */
	int adc_out;

	/* Initialize ADC. The ADC block which can connect to pin 10[6] is selected */
	result = cyhal_adc_init(&adc_obj, P10_6, NULL);

	// ADC configuration structure
	const cyhal_adc_config_t ADCconfig ={
		.continuous_scanning = false,
		.resolution = 12,
		.average_count = 1,
		.average_mode_flags = 0,
		.ext_vref_mv = 0,
		.vneg = CYHAL_ADC_VNEG_VREF,
		.vref = CYHAL_ADC_REF_VDDA,
		.ext_vref = NC,
		.is_bypassed = false,
		.bypass_pin = NC
	};

	// Configure to use VDD as Vref
	result = cyhal_adc_configure(&adc_obj, &ADCconfig);

	/* Initialize ADC channel, allocate channel number 0 to pin 10[6] as this is the first channel initialized */
	const cyhal_adc_channel_config_t channel_config = { .enable_averaging = false, .min_acquisition_ns = 220, .enabled = true };
	result = cyhal_adc_channel_init_diff(&adc_chan_0_obj, &adc_obj, P10_6, CYHAL_ADC_VNEG, &channel_config);

    for (;;)
    {
    	/* Read the ADC conversion result for corresponding ADC channel. Repeat as necessary. */
		adc_out = cyhal_adc_read_uv(&adc_chan_0_obj);
		printf("ADC = %d\r\n", adc_out);
		adc_out = adc_out*24/3304866;
		printf("ADC2 = %d\r\n", adc_out);
		cyhal_system_delay_ms(100);
    }
}

/* [] END OF FILE */
# PRESENTING CODE

LAB107 Read_potentiometer_value_via_ADC_HAL

Descriptions:

โปรแกรมนี้ใช้สำหรับการทำแปลง Analog-to-Digital Converter (ADC) และส่งข้อมูลผลลัพธ์ผ่าน UART บนไมโครคอนโทรลเลอร์ Cypress. เริ่มต้นด้วยการเรียกใช้ฟังก์ชัน cybsp_init() เพื่อเริ่มต้น Board Support Package (BSP) และตั้งค่าต่างๆ ในการเชื่อมต่อกับ peripheral บนบอร์ด. หากเกิดข้อผิดพลาดในการเริ่มต้น, โปรแกรมจะหยุดทำงาน. โปรแกรมทำการเปิดใช้งาน interrupt ทั่วไปและ retarget I/O library สำหรับการสื่อสารผ่าน UART. จากนั้น, โปรแกรมทำการเริ่มต้นการใช้งาน ADC บน pin 10[6] และกำหนดค่าและกำหนดค่าการทำงานของ ADC ด้วยโครงสร้าง ADCconfig. ในลูปหลัก, โปรแกรมทำการอ่านผลลัพธ์จากการแปลง ADC ที่เป็นแรงดันไฟฟ้าและนำไปแสดงผลผ่าน UART.

Important Variables:

result: เก็บผลลัพธ์จากการเรียกใช้ฟังก์ชันและตรวจสอบความสำเร็จในการเริ่มต้น.

adc_obj: เก็บข้อมูลเกี่ยวกับการใช้งาน ADC.

ADCconfig: เก็บข้อมูลความต้องการการกำหนดค่าของ ADC ที่มีการกำหนดค่าเอาไว้ในโครงสร้าง. adc_chan_0_obj: เก็บข้อมูลเกี่ยวกับการใช้งานช่อง ADC ที่เป็นแรงดันต่างกัน.

channel_config: เก็บข้อมูลการกำหนดค่าของ ADC channel.

adc_out: เก็บค่าผลลัพธ์จากการอ่านข้อมูล ADC.

UART_context: เก็บข้อมูล context ของ UART ที่ใช้ในการสื่อสาร.

Applications:

การตรวจวัดเซ็นเซอร์: รหัสนี้สามารถใช้ในการอ่านข้อมูลจากเซ็นเซอร์แบบอนาล็อก เช่น เซ็นเซอร์อุณหภูมิหรือโพเทนติอมิเตอร์ และส่งค่าผลลัพธ์ผ่าน UART ซึ่งเป็นประโยชน์ในแอปพลิเคชันที่ต้องการตรวจวัดสัญญาณแบบอนาล็อกในเวลาจริง

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include <stdio.h>

int main(void)
{
    cy_rslt_t result;

    // UART context variable
	cy_stc_scb_uart_context_t UART_context;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    __enable_irq();

    /* Configure and enable the UART peripheral */
	Cy_SCB_UART_Init(UART_HW, &UART_config, &UART_context);
	Cy_SCB_UART_Enable(UART_HW);

	// Initialize the AREF - block needed by ADC_HW ADC
	Cy_SysAnalog_Init(&AREF_config);
	// Initialize AREF
	Cy_SysAnalog_Enable();

	// Initialize the ADC
	Cy_SAR_Init(ADC_HW, &ADC_config);
	// Enable the ADC
	Cy_SAR_Enable(ADC_HW);

	int32_t ADCresult = 0; // ADC conversion result
	int32_t mVolts = 0; // Var to store voltage conversion of ADC result

    for (;;){
    	// Start a single conversion
		Cy_SAR_StartConvert(ADC_HW, CY_SAR_START_CONVERT_SINGLE_SHOT);
		if(Cy_SAR_IsEndConversion(ADC_HW, CY_SAR_WAIT_FOR_RESULT) == CY_SAR_SUCCESS){
			ADCresult = Cy_SAR_GetResult32(ADC_HW, 0);
			mVolts = Cy_SAR_CountsTo_mVolts(ADC_HW, 0, ADCresult);
		}
		char stringBuffer[20];
		sprintf(stringBuffer, "ADC = %ld\r\n", mVolts);
		Cy_SCB_UART_PutString(UART_HW, stringBuffer);
		Cy_SysLib_Delay(100);
    }
}
# PRESENTING CODE

LAB108Read_potentiometer_value_via_ADC_PDL

Descriptions:

โปรแกรมนี้ใช้สำหรับการวัดและส่งข้อมูลค่าแรงดันที่ได้จากการแปลง ADC (Analog-to-Digital Converter) ผ่าน UART บนไมโครคอนโทรลเลอร์ Cypress. เริ่มต้นโดยการเรียกใช้ฟังก์ชัน cybsp_init() เพื่อเริ่มต้น Board Support Package (BSP) และตั้งค่าต่างๆ ในการเชื่อมต่อกับ peripheral ต่างๆ บนบอร์ด. หากเกิดข้อผิดพลาดในการเริ่มต้น, โปรแกรมจะหยุดทำงาน. โปรแกรมทำการเปิดใช้งาน interrupt ทั่วไปและทำการเริ่มต้นการใช้งาน UART สำหรับการสื่อสาร. จากนั้น, โปรแกรมทำการเริ่มต้นการใช้งาน AREF (Analog Reference) และ ADC สำหรับการวัดค่าแรงดัน. ในลูปหลัก, โปรแกรมทำการเริ่มต้นการแปลง ADC แบบ single-shot, และหากการแปลงเสร็จสมบูรณ์, จะดึงค่าผลลัพธ์และแปลงเป็นแรงดันไฟฟ้าในหน่วย mVolts แล้วนำไปส่งผ่าน UART ในรูปแบบข้อความ.

Important Variables:

result: เก็บผลลัพธ์จากการเรียกใช้ฟังก์ชันและตรวจสอบความสำเร็จในการเริ่มต้น.
 UART_context: เก็บข้อมูล context ของ UART ที่ใช้ในการสื่อสาร.
 ADCresult: เก็บค่าผลลัพธ์จากการแปลง ADC.
 mVolts: เก็บค่าแรงดันไฟฟ้าที่ถูกคำนวณจากค่า ADC ในหน่วย mVolts.
 stringBuffer: เก็บข้อความที่จะถูกส่งผ่าน UART ในรูปแบบ "ADC = [ค่าแรงดัน] mVolts".

Applications:

ควบคุมความสว่างของ LED: โปรแกรมนี้สามารถนำไปใช้ในการควบคุมความสว่างของ LED โดยปรับค่า duty cycle ของ PWM ตามต้องการ.

การทดสอบความทนทาน: สามารถใช้ PWM เพื่อทดสอบความทนทานของอุปกรณ์หรือวงจรในโปรเจคทดลอง.

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"

int main(void)
{
    cy_rslt_t result;
    cyhal_pwm_t pwm_obj;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS){
        CY_ASSERT(0);
    }

    __enable_irq();

	/* Initialize PWM on the supplied pin and assign a new clock */
    result = cyhal_pwm_init(&pwm_obj, CYBSP_USER_LED4, NULL);

	/* Start the PWM output */
	result = cyhal_pwm_start(&pwm_obj);

	while(true){
		for (int i = 0; i <= 100; i++){
			result = cyhal_pwm_set_duty_cycle(&pwm_obj, i, 10000);//LED low
			cyhal_system_delay_ms(25);
		}
	}
}
# PRESENTING CODE

LAB109 LED_Brightness_using_PWM_via_HAL

Descriptions:

โปรแกรมนี้ใช้สำหรับควบคุม PWM (Pulse Width Modulation) บนไมโครคอนโทรลเลอร์ Cypress ผ่าน HAL (Hardware Abstraction Layer). เริ่มต้นโดยการเรียกใช้ฟังก์ชัน cybsp_init() เพื่อเริ่มต้น Board Support Package (BSP) และตั้งค่าต่างๆ ในการเชื่อมต่อกับ peripheral ต่างๆ บนบอร์ด. หากเกิดข้อผิดพลาดในการเริ่มต้น, โปรแกรมจะหยุดทำงาน. ต่อมา, โปรแกรมเปิดใช้งาน interrupt ทั่วไปและทำการเริ่มต้นการใช้งาน PWM บน pin ที่กำหนด. ในลูปหลัก, โปรแกรมทำการเปลี่ยนค่า duty cycle ของ PWM จาก 0 ถึง 100 และหน่วงเวลา 25 มิลลิวินาทีในแต่ละระยะ.

Important Variables:

result: เก็บผลลัพธ์จากการเรียกใช้ฟังก์ชันและตรวจสอบความสำเร็จในการเริ่มต้น.

pwm_obj: ตัวแปรที่ใช้ในการเข้าถึงและควบคุม PWM ผ่าน HAL. CYBSP_USER_LED5: ระบุ pin ที่ต่อกับ PWM.

i: ตัวแปรที่ใช้ในการสร้างลูปที่ทำการเปลี่ยนแปลงค่า duty cycle ของ PWM.

Applications:

ควบคุมความสว่างของ LED: โปรแกรมนี้สามารถนำไปใช้ในการควบคุมความสว่างของ LED โดยปรับค่า duty cycle ของ PWM ตามต้องการ.

การทดสอบความทนทาน: สามารถใช้ PWM เพื่อทดสอบความทนทานของอุปกรณ์หรือวงจรในโปรเจคทดลอง.

#include "cy_pdl.h"
#include "cybsp.h"

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    // Initialize the TCPWM block
	Cy_TCPWM_PWM_Init(PWM_HW, PWM_NUM, &PWM_config);
	// Enable the TCPWM block
	Cy_TCPWM_PWM_Enable(PWM_HW, PWM_NUM);
	// Start the PWM
	Cy_TCPWM_TriggerReloadOrIndex(PWM_HW, PWM_MASK);

    for (;;)
    {
    	for(int i = 0; i < 50000; i+=5){
    		Cy_TCPWM_PWM_SetCompare0(PWM_HW, PWM_NUM, i);
    		Cy_SysLib_Delay(10); // Delay 10 ms
    	}
    }
}
# PRESENTING CODE

LAB110 LED_Brightness_using_PWM_via_PDL

Descriptions:

โปรแกรมนี้ใช้สำหรับควบคุมการทำงานของ Pulse Width Modulation (PWM) บนไมโครคอนโทรลเลอร์ Cypress ผ่านทาง TCPWM (Timer/Counter PWM) block. โดยเริ่มต้นด้วยการเรียกใช้ฟังก์ชัน cybsp_init() เพื่อเริ่มต้น Board Support Package (BSP) และตั้งค่าต่างๆ ในการเชื่อมต่อกับ peripheral ต่างๆ บนบอร์ด. หากเกิดข้อผิดพลาดในการเริ่มต้น, โปรแกรมจะหยุดทำงาน. ต่อมา, โปรแกรมเปิดใช้งาน interrupt ทั่วไปและทำการเริ่มต้นการใช้งาน TCPWM block สำหรับ PWM. ในลูปหลัก, โปรแกรมทำการเปลี่ยนค่าของ PWM duty cycle ในระหว่าง 0 ถึง 50000 และหน่วงเวลา 10 มิลลิวินาทีในแต่ละระยะ.

Important Variables:

result: เก็บผลลัพธ์จากการเรียกใช้ฟังก์ชันและตรวจสอบความสำเร็จในการเริ่มต้น.

PWM_HW, PWM_NUM, PWM_config: ตัวแปรที่ใช้ในการกำหนดค่าและควบคุม TCPWM block สำหรับ PWM.

i: ตัวแปรที่ใช้ในการสร้างลูปที่ทำการเปลี่ยนแปลงค่า duty cycle ของ PWM.

Applications:

การควบคุมความสว่างของ LED: โปรแกรมนี้สามารถนำไปใช้ในการควบคุมความสว่างของ LED โดยการปรับค่า duty cycle ของ PWM ตามต้องการ.

การควบคุมความเร็วของมอเตอร์: โปรแกรมนี้สามารถปรับความเร็วของมอเตอร์โดยการควบคุม PWM duty cycle, ทำให้เหมาะสำหรับการปรับความเร็วในโปรเจคที่ใช้มอเตอร์.

#include "cybsp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "capsense_task.h"
#include "led_task.h"

#define TASK_CAPSENSE_PRIORITY (configMAX_PRIORITIES - 1)
#define TASK_LED_PRIORITY (configMAX_PRIORITIES - 2)

#define TASK_CAPSENSE_STACK_SIZE (256u)
#define TASK_LED_STACK_SIZE (configMINIMAL_STACK_SIZE)

#define SINGLE_ELEMENT_QUEUE (1u)


int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init();

    /* Board init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    /* Create the queues. See the respective data-types for details of queue
     * contents
     */
    led_command_data_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
                                      sizeof(led_command_data_t));
    capsense_command_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
                                      sizeof(capsense_command_t));

    /* Create the user tasks. See the respective task definition for more
     * details of these tasks.
     */
    xTaskCreate(task_capsense, "CapSense Task", TASK_CAPSENSE_STACK_SIZE,
                NULL, TASK_CAPSENSE_PRIORITY, NULL);
    xTaskCreate(task_led, "Led Task", TASK_LED_STACK_SIZE,
                NULL, TASK_LED_PRIORITY, NULL);

    /* Start the RTOS scheduler. This function should never return */
    vTaskStartScheduler();

    CY_ASSERT(0);

    for (;;)
    {
    }

}
# PRESENTING CODE

LAB202 CAPSENSE_Buttons_and_Slider_Template

Descriptions:

ใช้ในการควบคุมการทำงานของ CapSense (เทคโนโลยีการตรวจจับการสัมผัส) บน PSoC 6 MCU ซึ่งเป็นไมโครคอนโทรลเลอร์ที่พัฒนาโดย Cypress (ตอนนี้เป็นบริษัทที่รวมกับ Infineon Technologies แล้ว) โค้ดนี้มีหน้าที่ตรวจจับการสัมผัสบนปุ่มและสไลเดอร์ที่ติดตั้งบนบอร์ด และปรับปรุงสถานะของ LED ตามผลลัพธ์ของการสัมผัสนั้น ๆ

Important Variables:

CAPSENSE_INTR_PRIORITY: ลำดับความสำคัญของการสัมผัส CapSense. EZI2C_INTR_PRIORITY: ลำดับความสำคัญของการสัมผัส EZI2C ซึ่งต้องมีค่าสูงกว่า CapSense เพื่อให้ทำงานได้ถูกต้อง.

initialize_capsense(): ฟังก์ชั่นนี้ใช้ในการเริ่มต้น CapSense และกำหนดค่า interrupt ของ CapSense. process_touch(): ฟังก์ชั่นนี้ใช้ในการประมวลผลข้อมูลการสัมผัสและอัปเดตสถานะของ LED ตามผลลัพธ์. initialize_capsense_tuner(): ฟังก์ชั่นนี้ใช้ในการกำหนดค่าสำหรับการเชื่อมต่อระหว่าง Tuner GUI และ PSoC 6 MCU.

Applications:

การควบคุม LED ตามการสัมผัสบนปุ่มและสไลเดอร์. การสื่อสารระหว่าง PSoC 6 MCU และ Tuner GUI เพื่อตรวจสอบและปรับแต่งการทำงานของ CapSense.

#include "cybsp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "capsense_task.h"
#include "led_task.h"


/*******************************************************************************
 * Global constants
 ******************************************************************************/
/* Priorities of user tasks in this project. configMAX_PRIORITIES is defined in
 * the FreeRTOSConfig.h and higher priority numbers denote high priority tasks.
 */
#define TASK_CAPSENSE_PRIORITY (configMAX_PRIORITIES - 1)
#define TASK_LED_PRIORITY (configMAX_PRIORITIES - 2)

/* Stack sizes of user tasks in this project */
#define TASK_CAPSENSE_STACK_SIZE (256u)
#define TASK_LED_STACK_SIZE (configMINIMAL_STACK_SIZE)

/* Queue lengths of message queues used in this project */
#define SINGLE_ELEMENT_QUEUE (1u)


/*******************************************************************************
* Function Name: main()
********************************************************************************
* Summary:
*  System entrance point. This function sets up user tasks and then starts
*  the RTOS scheduler.
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init();

    /* Board init failed. Stop program execution */
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    /* Create the queues. See the respective data-types for details of queue
     * contents
     */
    led_command_data_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
                                      sizeof(led_command_data_t));
    capsense_command_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
                                      sizeof(capsense_command_t));

    /* Create the user tasks. See the respective task definition for more
     * details of these tasks.
     */
    xTaskCreate(task_capsense, "CapSense Task", TASK_CAPSENSE_STACK_SIZE,
                NULL, TASK_CAPSENSE_PRIORITY, NULL);
    xTaskCreate(task_led, "Led Task", TASK_LED_STACK_SIZE,
                NULL, TASK_LED_PRIORITY, NULL);

    /* Start the RTOS scheduler. This function should never return */
    vTaskStartScheduler();

    /********************** Should never get here ***************************/
    /* RTOS scheduler exited */
    /* Halt the CPU if scheduler exits */
    CY_ASSERT(0);

    for (;;)
    {
    }

}
# PRESENTING CODE

LAB203 CAPSENSE_Buttons_and_Slider_FreeRTOS

Descriptions:

โค้ดตัวอย่างนี้เป็นตัวอย่างการใช้งาน CapSense slider 5 ส่วนและปุ่ม CapSense 2 ปุ่มบนบอร์ดเพื่อควบคุมการเปิด-ปิด LED และควบคุมความสว่างของ LED โดยมีการใช้ FreeRTOS เป็นระบบปฏิบัติงานแบบ Real-Time Operating System (RTOS) และมีการเชื่อมต่อกับ Tuner GUI ผ่าน I2C interface เพื่อให้สามารถปรับแต่งและติดตามการทำงานของระบบได้ผ่านตัว GUI นั้น ๆ

Important Variables:

led_command_data_q: คิวที่ใช้สำหรับส่งข้อมูลคำสั่งไปยัง Task ที่ควบคุม LED

capsense_command_q: คิวที่ใช้สำหรับส่งข้อมูลคำสั่งไปยัง Task ที่ควบคุม CapSense

TASK_CAPSENSE_PRIORITY และ TASK_LED_PRIORITY: ลำดับความสำคัญของ Task ที่ควบคุม CapSense และ LED ตามลำดับ

TASK_CAPSENSE_STACK_SIZE และ TASK_LED_STACK_SIZE: ขนาดของ Stack สำหรับ Task ที่ควบคุม CapSense และ LED ตามลำดับ

SINGLE_ELEMENT_QUEUE: ขนาดของคิวที่ใช้สำหรับการสื่อสารระหว่าง Task

Applications:

การควบคุม LED และ CapSense ในโปรเจคนี้

การใช้ FreeRTOS เพื่อจัดการ Task แบบ Real-Time

การใช้ I2C interface เพื่อเชื่อมต่อกับ Tuner GUI สำหรับการปรับแต่งระบบ CapSense และ LED

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"

#define LED1_PIN CYBSP_LED_RGB_RED
#define LED2_PIN CYBSP_LED_RGB_GREEN
#define LED3_PIN CYBSP_LED_RGB_BLUE

int main(void)
{
    cy_rslt_t result;
    cyhal_adc_t adc_obj;
    cyhal_adc_channel_t adc_chan_0_obj;

    /* Initialize the device and board peripherals */
    result = cybsp_init();
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    __enable_irq();

    /* Initialize retarget-io to use the debug UART port */
    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT(result == CY_RSLT_SUCCESS);

    /* Initialize LED pins */
    cyhal_gpio_init(LED1_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
    cyhal_gpio_init(LED2_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
    cyhal_gpio_init(LED3_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);

    /* ADC conversion result. */
    int adc_out;
	int adc_out1;

    /* Initialize ADC. The ADC block which can connect to pin 10[6] is selected */
    result = cyhal_adc_init(&adc_obj, P10_6, NULL);

    // ADC configuration structure
    const cyhal_adc_config_t ADCconfig ={
        .continuous_scanning = false,
        .resolution = 12,
        .average_count = 1,
        .average_mode_flags = 0,
        .ext_vref_mv = 0,
        .vneg = CYHAL_ADC_VNEG_VREF,
        .vref = CYHAL_ADC_REF_VDDA,
        .ext_vref = NC,
        .is_bypassed = false,
        .bypass_pin = NC
    };

    // Configure to use VDD as Vref
    result = cyhal_adc_configure(&adc_obj, &ADCconfig);

    /* Initialize ADC channel, allocate channel number 0 to pin 10[6] as this is the first channel initialized */
    const cyhal_adc_channel_config_t channel_config = { .enable_averaging = false, .min_acquisition_ns = 220, .enabled = true };
    result = cyhal_adc_channel_init_diff(&adc_chan_0_obj, &adc_obj, P10_6, CYHAL_ADC_VNEG, &channel_config);

    for (;;)
    {
        /* Read the ADC conversion result for corresponding ADC channel. Repeat as necessary. */
        adc_out = cyhal_adc_read_uv(&adc_chan_0_obj);
      	adc_out1 = (adc_out*30)/3304866;
        printf("ADC = %d\r\n", adc_out);

        if (adc_out1 >= 1 && adc_out1 <= 10)
        {
            cyhal_gpio_write(LED1_PIN, CYBSP_LED_STATE_ON);
            cyhal_gpio_write(LED2_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED3_PIN, CYBSP_LED_STATE_OFF);
        }
        else if (adc_out1 >= 11 && adc_out1 <= 20)
        {
            cyhal_gpio_write(LED1_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED2_PIN, CYBSP_LED_STATE_ON);
            cyhal_gpio_write(LED3_PIN, CYBSP_LED_STATE_OFF);
        }
        else if (adc_out1 >= 21 && adc_out1 <= 30)
        {
            cyhal_gpio_write(LED1_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED2_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED3_PIN, CYBSP_LED_STATE_ON);
        }
        else
        {
            cyhal_gpio_write(LED1_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED2_PIN, CYBSP_LED_STATE_OFF);
            cyhal_gpio_write(LED3_PIN, CYBSP_LED_STATE_OFF);
        }

        cyhal_system_delay_ms(100);
    }
}
# PRESENTING CODE

Modify Code LAB107

โค้ดนี้ใช้ PSoC 6 (Platform System on Chip) เพื่อวัดและควบคุมไฟ LED จากสัญญาณแรงดันแอนะล็อกที่มีที่ขา P10_6 โดยใช้ ADC (Analog-to-Digital Converter) บนชิป PSoC 6 นี้

  1. การอ่านแรงดันแอนะล็อก (ADC Reading Output): โค้ดนี้จะอ่านค่าแรงดันแอนะล็อกที่ป้อนเข้าที่ขา P10_6 และแปลงเป็นค่าดิจิตอลที่สามารถนำไปใช้ได้ โค้ดจะแสดงค่านี้ในรูปแบบ raw ที่ถูกอ่านจาก ADC ทางคอนโซลของระบบหรืออินเทอร์เฟซใดๆที่ใช้ในการดีบักข้อมูล

  2. ควบคุมไฟ LED (LED Control): จากนั้นโค้ดจะทำการคำนวณ adc_out1 ซึ่งเป็นรูปแบบที่ scaled ของ adc_out โค้ดจะแมปค่าที่ได้จาก ADC ไปยังช่วงค่า 0 ถึง 30 จากนั้นจะควบคุมไฟ LED ตามเงื่อนไขต่อไปนี้:

    • ถ้า adc_out1 อยู่ในช่วง 1-10, จะเปิด LED1 และปิด LED2 และ LED3
    • ถ้า adc_out1 อยู่ในช่วง 11-20, จะเปิด LED2 และปิด LED1 และ LED3
    • ถ้า adc_out1 อยู่ในช่วง 21-30, จะเปิด LED3 และปิด LED1 และ LED2
    • ถ้า adc_out1 ไม่อยู่ในช่วงเหล่านี้, ทุก LED จะถูกปิด

Copy of Code

By daisy053

Copy of Code

  • 160