3 Replies Latest reply on Feb 13, 2020 12:09 AM by MoTa_728816

    多執行緒

    YuCh_3947976

      嗨,我想在一個for迴圈內同時執行兩個子程式,但其中一個子程式內有call dalay time,所以run的時候都還是會被延遲時間所影響

      請問該如何讓兩個子程式同時進行而不被影響呢,謝謝

        • 1. Re: 多執行緒
          MoTa_728816

          Hi,

           

          There must be many strategies for this question.

          Following is my idea using SysTick.

           

          (google translation)

          ================

          这个问题必须有许多策略。

          以下是我使用SysTick的想法。

          ================

           

          Tera Term log

          000-TeraTerm-log.JPG

          main.c

          ===================

          #include "project.h"

          #include "stdio.h"

           

          volatile uint32_t sub1_tick_count = 0 ;

          volatile int      sub1_timer_flag = 1 ;

          int               sub1_tick_running = 0 ;

          uint32_t          sub1_tick_period = 1000 ; /* default 1 sec */

           

          CY_ISR(sub1_tick_isr)

          {

              if (sub1_tick_running) {

                  sub1_tick_count++ ;

                  if (sub1_tick_count >= sub1_tick_period) {

                      sub1_timer_flag = 1 ;

                      sub1_tick_running = 0 ; /* stop my tick but not systick */

                  }

              }

          }

           

          void sub1_start_timer(uint32_t period_ms)

          {

              sub1_tick_period = period_ms ;

              sub1_tick_count = 0 ;

              sub1_tick_running = 1 ;

          }

           

          #define STR_LEN 64

          char str[STR_LEN+1] ;

          void print(char *str)

          {

              UART_UartPutString(str) ;

          }

           

          void cls(void)

          {

              print("\033c") ; /*reset */

              CyDelay(20) ;

              print("\033[2J") ; /* clear screen */

              CyDelay(20) ;

          }

           

          void splash(void)

          {

              cls() ;

              print("PSoC4 Tick Timer Test") ;

              snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;

              print(str) ;

          }

           

          void init_hardware(void)

          {

              CyGlobalIntEnable; /* Enable global interrupts. */

              UART_Start() ;

              splash() ;

              CySysTickStart() ;

              CySysTickSetCallback(0, sub1_tick_isr) ;

          }

           

           

          void sub1(void)

          {

              if (sub1_timer_flag) {

                  sub1_timer_flag = 0 ;

                  print("Sub1\n\r") ;

                  sub1_start_timer(3000) ;

              }

          }

           

          void sub2(void)

          {

              print("\tSub2\n\r") ;

          }

           

          int main(void)

          {

              init_hardware() ;

           

              for(;;)

              {

                  sub1() ;

                  sub2() ;

                  CyDelay(1000) ;

              }

          }

          ===================

           

          Attached is a sample using CY8CKIT-044

           

          moto

          • 2. Re: 多執行緒
            YuCh_3947976

              Hi,thanks for your help,I can understand what you mean

            but can you help me to modify my code directly,the part of code is down below

            I want to run LED_Dimming all the time and send messages(DMSG) every second

             

              for(;;)

                {  

            CyDelay(300);

                    ad_result = g_ambientLight;

                  

                    /* Place your application code here. */

                    if (ad_result < 0)

                    {

                        ad_result = 0;

                    }

                    LED_Dimming(ad_result);

                }

             

             

            void LED_Dimming(int16 ad_value)

            {

                int32 duty = MIN_PWM_DUTY;

              

                if (ad_value <= 100)

                {

                    duty = MIN_PWM_DUTY;

                }

                else if (ad_value > 2000)

                {

                    duty = MAX_PWM_DUTY;

                }

                else

                {

                    duty = MIN_PWM_DUTY + ad_value* 6;

                }

                DMSG("Duty %d, ad %d\r\n",duty,ad_value);

                PWM_WriteCompare(duty);

            • Add to Phrasebook
              • No word lists for English -> Traditional Chinese...
              • Create a new word list...
            • Copy
            • Add to Phrasebook
              • No word lists for English -> Traditional Chinese...
              • Create a new word list...
            • Copy
            • 3. Re: 多執行緒
              MoTa_728816

              Hi,

               

              I modified my sample project close to your source code.

               

              Tera Term log

              010-TeraTerm-log.JPG

              main.c

              ==================

              #include "project.h"

              #include "stdio.h"

               

              #define MIN_PWM_DUTY    80

              #define MAX_PWM_DUTY 20000

               

              uint32_t            measure_period = 300 ;

              uint32_t            display_period = 1000 ;

               

              volatile int        measure_flag = 0 ;

              volatile int        display_flag = 0 ;

              volatile uint32_t   measure_count = 0 ;

              volatile uint32_t   display_count = 0 ;

               

              int16_t             g_ambientLight = 0  ;

              int16_t             ad_value ;

               

              CY_ISR(my_tick_isr)

              {

                  measure_count++ ;

                  if (measure_count > measure_period) {

                      measure_count = 0 ;

                      measure_flag = 1 ;

                  }

                  display_count++ ;

                  if (display_count > display_period) {

                      display_count = 0 ;

                      display_flag = 1 ;

                  }

              }

               

              #define STR_LEN 64

              char str[STR_LEN+1] ;

              void print(char *str)

              {

                  UART_UartPutString(str) ;

              }

               

              void cls(void)

              {

                  print("\033c") ; /*reset */

                  CyDelay(20) ;

                  print("\033[2J") ; /* clear screen */

                  CyDelay(20) ;

              }

               

              void splash(void)

              {

                  cls() ;

                  print("PSoC4 Tick Timer Test") ;

                  snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;

                  print(str) ;

              }

               

              void init_hardware(void)

              {

                  CyGlobalIntEnable; /* Enable global interrupts. */

                  UART_Start() ;

                  splash() ;

                  CySysTickStart() ;

                  CySysTickSetCallback(0, my_tick_isr) ;

                  PWM_Start() ;

              }

               

               

              int32_t LED_Dimming(int32_t ad_value)

              {

                  int32_t duty ;

                 

                  if (ad_value <= 100) {

                      duty = MIN_PWM_DUTY ;

                  } else if (ad_value > 2000) {

                      duty = MAX_PWM_DUTY ;

                  } else {

                      duty = MIN_PWM_DUTY + ad_value * 6 ;

                  }

                  PWM_WriteCompare(duty) ;

                  return( duty ) ;

              }

               

              void get_ambientLight(void)

              {

                  g_ambientLight += 100 ;

                  if (g_ambientLight > 2100) {

                      g_ambientLight = 0 ;

                  }

              }

               

              int32_t measure(void)

              {

                  int32_t duty ;

                 

                  get_ambientLight() ; /* test function */

                 

                  ad_value = g_ambientLight ;

                  if (ad_value < 0) {

                      ad_value = 0 ;

                  }

                  duty = LED_Dimming(ad_value) ;

                  return( duty ) ;

              }

               

              void display_message(int32_t duty, int16_t ad_value)

              {

                  snprintf(str, STR_LEN, "Duty %d, ad %d\n\r", duty, ad_value) ;

                  print(str) ;

              }

               

              int main(void)

              {

                  int32_t duty = MIN_PWM_DUTY ;

                 

                  init_hardware() ;

               

                  for(;;) {

                      if (measure_flag) {

                          measure_flag = 0 ;

                          duty = measure() ;

                      }

                      if (display_flag) {

                          display_flag = 0 ;

                          display_message(duty, ad_value) ;

                      }

                  }

              }

              ==================

               

              moto