1 Reply Latest reply on May 21, 2020 10:27 PM by TakashiM_61

    CY8CKIT-044 RTC with 32kHz Crystal Sample

    MoTa_728816

      Hi,

      こんにちは、

       

      Well, this was my bad, but until yesterday I did not know/notice that CY8CKIT-044 has an onboard 32kHz crystal.

      When I saw a question about display time of some sensor measurements, at first I did not think that displaying precise time was possible.

       

      なんと、昨日まで、CY8CKIT-044 に 32KHz クリスタルが載っていることに気づいていませんでした。

      コミュニティの質問で、センサで測定した値をタイムスタンプ付きでプリントしたいというのがあって、

      外付けクリスタルがないと出来ないだろそれ?とか思っていました。

       

      But, just in case, I checked the Kit Guide of CY8CKIT-044, and found a 32kHz crystal loaded!

      でも、念のために、キットガイドをチラ見したら・・・あら、載っていた(笑)

       

      Well, then we should be able to implement a reasonably accurate clock with it.

      I set the source of Low Frequency Clock to WCO.

       

      それならそこそこの精度の時計作れるじゃないということで。

      まず低速クロックの原振を WCO に変えました。

      004-Low_Frequency_Clocks.JPG

       

      Then the schematic was simple.

      回路はシンプルですね。

      002-schematic.JPG

       

      The pins are even simpler.

      ピンに至ってはもっとシンプル。

      003-pins.JPG

       

      With a simple functions date and time could be printed OK.

      簡単な関数を書いて、日付と時間は難なく表示できました。

       

      print_time()

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

      void print_time(void)

      {

          char time_str[16] ;

          uint32_t time ;

         

          time = RTC_GetTime();

       

       

          /* Print Date and Time to UART */

          sprintf(time_str, "%02lu:%02lu:%02lu", RTC_GetHours(time), RTC_GetMinutes(time), RTC_GetSecond(time));

          print(time_str) ;

      }

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

       

      print_date()

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

      void print_date(void)

      {

          char date_str[16] ;

          uint32_t date ;

         

          date = RTC_GetDate();

       

       

          sprintf(date_str, "%02lu/%02lu/%02lu", RTC_GetYear(date), RTC_GetMonth(date), RTC_GetDay(date));    

          print(date_str) ;

      }

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

       

      But I was not expecting setting time will cost me another hour or two.

      I could read year, month, day, hour, min, sec from uart,

      but assigning them with RTC_SetDateAndTime() gave me a pretty interesting date ant time.

       

      しかし、この後時間の設定で数時間とられるとは期待していませんでした。

      UART から、日時のデータは問題なく取得できたのですが、

      RTC_SetDateAndTime() へ代入するとカオスな日時が表示されました。

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

      void setup_time(void)

      {

          uint32_t year, month, day ;

          uint32_t hour, min, sec ;

          uint32_t input_time, input_date ;

         

          print("Enter date (YYYY/MM/DD) > ") ;

          while(get_line() == 0) { }

          sscanf(str, "%ld/%ld/%ld", &year, &month, &day) ;

          input_date = ((uint32_t)(year  << RTC_YEAR_OFFSET)  | \

                        (uint32_t)(month << RTC_MONTH_OFFSET) | \

                        (uint32_t)(day   << RTC_DAY_OFFSET))  ;

         

          print("Enter time (hh:mm:ss) > ") ;

          while(get_line() == 0) { }

          sscanf(str, "%ld:%ld:%ld", &hour, &min, &sec) ;

          input_time = ((uint32_t)(hour << RTC_HOURS_OFFSET)    | \

                        (uint32_t)(min  << RTC_MINUTES_OFFSET)  | \

                        (uint32_t)(sec  << RTC_SECONDS_OFFSET)) ;

         

          RTC_Start() ;

         

          RTC_SetDateAndTime(input_time, input_date) ;

         

          print("Time Set to: ") ;

          print_date() ;

          print(" ") ;

          print_time() ;

          print("\n\r") ;

      }

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

       

      Finally it was the time for reading manual (datasheet).

      And found that the uint32_t input_date and uint32_t input_time must be in BCD format.

      So I modified above code to

       

      とうとう、こりゃマニュアル(データシート)見ないとだめだなと (最初にみろ!という話もありますが)

      どうやら、RTC_SetDateAndTime() の引数は BCD フォーマットじゃなくてはいけないという事らしいのですが、

      それどうやって変換するのよ?と途方に暮れていたら RTC_ConvertDecToBCD() という関数がありました。

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

      void setup_time(void)

      {

          uint32_t year, month, day ;

          uint32_t hour, min, sec ;

          uint32_t input_time, input_date ;

         

          print("Enter date (YYYY/MM/DD) > ") ;

          while(get_line() == 0) { }

          sscanf(str, "%ld/%ld/%ld", &year, &month, &day) ;

          year  = RTC_ConvertDecToBCD(year) ;

          month = RTC_ConvertDecToBCD(month) ;

          day   = RTC_ConvertDecToBCD(day) ;

          input_date = ((uint32_t)(year  << RTC_YEAR_OFFSET)  | \

                        (uint32_t)(month << RTC_MONTH_OFFSET) | \

                        (uint32_t)(day   << RTC_DAY_OFFSET))  ;

         

          print("Enter time (hh:mm:ss) > ") ;

          while(get_line() == 0) { }

          sscanf(str, "%ld:%ld:%ld", &hour, &min, &sec) ;

          hour = RTC_ConvertDecToBCD(hour) ;

          min  = RTC_ConvertDecToBCD(min) ;

          sec  = RTC_ConvertDecToBCD(sec) ;

          input_time = ((uint32_t)(hour << RTC_HOURS_OFFSET)    | \

                        (uint32_t)(min  << RTC_MINUTES_OFFSET)  | \

                        (uint32_t)(sec  << RTC_SECONDS_OFFSET)) ;

         

          RTC_Start() ;

         

          RTC_SetDateAndTime(input_time, input_date) ;

         

          print("Time Set to: ") ;

          print_date() ;

          print(" ") ;

          print_time() ;

          print("\n\r") ;

      }

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

      And finally I could return to current date.

       

      という訳で無事現代に帰ってこれました。

       

      For those who knew about this, this must be trivial.

      But for those who did, it must be a Notorious Monster.

       

      ご存じの方には、今さら何を?というお話でしたが、

      初見者には手ごわい中ボスでした。

       

      Now my program was working as I expected it to.

      ようやく、プログラムが期待通り動いてくれるようになりました。

      001-TeraTerm-log.JPG

       

      I would be very happy if I can save someone else's a couple of hours with this ;-)

      これで、どなたかの2時間を無駄にするのを避けられたらよいのですが (^ ^)

       

      moto