[Atmel] 用SAM-BA或JLINK跑ATSAM4E16的程序(17)ASF RTC

[复制链接]
931|0
 楼主| ddllxxrr 发表于 2015-11-24 21:43 | 显示全部楼层 |阅读模式
本帖最后由 ddllxxrr 于 2015-11-24 21:54 编辑

RTC可选内部或外部32.768kHz晶振驱动。可定时,报警,更新时间/日历,还可以通过RTCOUT0和RTCOUT1输出波形。


以下程序就是同串**互,可以设日期,设时间,设报警时间,设日期报警,清除报警,和产生波形:

程序如下:

  1. #include "asf.h"
  2. #include "stdio_serial.h"
  3. #include "conf_clock.h"
  4. #include "conf_board.h"

  5. /// [url=home.php?mod=space&uid=1302964]@cond[/url] 0
  6. /**INDENT-OFF**/
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. /**INDENT-ON**/
  11. /// @endcond

  12. /* Main menu is being displayed. */
  13. #define STATE_MENU             0
  14. /* Time is being edited. */
  15. #define STATE_SET_TIME         1
  16. /* Date is being edited. */
  17. #define STATE_SET_DATE         2
  18. /* Time alarm is being edited. */
  19. #define STATE_SET_TIME_ALARM   3
  20. /* Date alarm is being edited. */
  21. #define STATE_SET_DATE_ALARM   4
  22. /* Wave generating is being edited. */
  23. #define STATE_WAVEFORM         5

  24. /* Maximum size of edited string. */
  25. #define MAX_EDIT_SIZE          10

  26. /* Macro for converting char to digit. */
  27. #define char_to_digit(c) ((c) - '0')

  28. #define STRING_EOL    "\r"
  29. #define STRING_HEADER "-- RTC Example --\r\n" \
  30.                 "-- "BOARD_NAME" --\r\n" \
  31.                 "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL

  32. /* Current state of application. */
  33. static uint32_t gs_ul_state = STATE_MENU;

  34. /* Edited hour. */
  35. static uint32_t gs_ul_new_hour;
  36. /* Edited minute. */
  37. static uint32_t gs_ul_new_minute;
  38. /* Edited second. */
  39. static uint32_t gs_ul_new_second;

  40. /* Edited year. */
  41. static uint32_t gs_ul_new_year;
  42. /* Edited month. */
  43. static uint32_t gs_ul_new_month;
  44. /* Edited day. */
  45. static uint32_t gs_ul_new_day;
  46. /* Edited day-of-the-week. */
  47. static uint32_t gs_ul_new_week;

  48. /* Indicate if alarm has been triggered and not yet cleared */
  49. static uint32_t gs_ul_alarm_triggered = 0;

  50. /* Time string */
  51. static uint8_t gs_uc_rtc_time[8 + 1] =
  52.                 { '0', '0', ':', '0', '0', ':', '0', '0', '\0' };
  53. /* Date string */
  54. static uint8_t gs_uc_date[10 + 1] =
  55.                 { '0', '0', '/', '0', '0', '/', '0', '0', '0', '0', '\0' };
  56. /* Week string */
  57. static uint8_t gs_uc_day_names[7][4] =
  58.                 { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };

  59. /* Flag for refreshing menu */
  60. static uint32_t gs_ul_menu_shown = 0;

  61. /**
  62. *  Configure UART console.
  63. */
  64. static void configure_console(void)
  65. {
  66.         const usart_serial_options_t uart_serial_options = {
  67.                 .baudrate = CONF_UART_BAUDRATE,
  68. #ifdef CONF_UART_CHAR_LENGTH
  69.                 .charlength = CONF_UART_CHAR_LENGTH,
  70. #endif
  71.                 .paritytype = CONF_UART_PARITY,
  72. #ifdef CONF_UART_STOP_BITS
  73.                 .stopbits = CONF_UART_STOP_BITS,
  74. #endif
  75.         };

  76.         /* Configure console UART. */
  77.         sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
  78.         stdio_serial_init(CONF_UART, &uart_serial_options);
  79. }

  80. /**
  81. * \brief Get new time. Successful value is put in gs_ul_new_hour,
  82. * gs_ul_new_minute, gs_ul_new_second.
  83. */
  84. static uint32_t get_new_time(void)
  85. {
  86.         uint8_t uc_key;
  87.         uint32_t i = 0;

  88.         /* Clear setting variable. */
  89.         gs_ul_new_hour = 0xFFFFFFFF;
  90.         gs_ul_new_minute = 0xFFFFFFFF;
  91.         gs_ul_new_second = 0xFFFFFFFF;

  92.         /* Use gs_uc_rtc_time[] as a format template. */
  93.         while (1) {

  94.                 scanf("%c", (char *)&uc_key);

  95.                 /* End input */
  96.                 if (uc_key == 0x0d || uc_key == 0x0a) {
  97.                         puts("\r");
  98.                         break;
  99.                 }

  100.                 /* DEL or BACKSPACE */
  101.                 if (uc_key == 0x7f || uc_key == 0x08) {
  102.                         if (i > 0) {
  103.                                 /* End of gs_uc_rtc_time[], then one more back of index */
  104.                                 if (!gs_uc_rtc_time[i]) {
  105.                                         --i;
  106.                                 }

  107.                                 puts("\b \b");
  108.                                 --i;

  109.                                 /* Delimiter ':' for time is uneditable */
  110.                                 if (!((gs_uc_rtc_time[i]) >= '0' && (gs_uc_rtc_time[i]) <= '9')
  111.                                                 && i > 0) {
  112.                                         puts("\b \b");
  113.                                         --i;
  114.                                 }
  115.                         }
  116.                 }

  117.                 /*
  118.                  * End of gs_uc_rtc_time[], no more input except the above DEL/BS,
  119.                  * or enter to end.
  120.                  */
  121.                 if (!gs_uc_rtc_time[i]) {
  122.                         continue;
  123.                 }

  124.                 printf("%c", uc_key);
  125.                 gs_uc_rtc_time[i++] = uc_key;

  126.         }

  127.         if (i == 0) {
  128.                 return 0;
  129.         }

  130.         if (i != 0 && gs_uc_rtc_time[i] != '\0') {
  131.                 /* Failure input */
  132.                 return 1;
  133.         }

  134.         gs_ul_new_hour = char_to_digit(gs_uc_rtc_time[0]) * 10 +
  135.                         char_to_digit(gs_uc_rtc_time[1]);
  136.         gs_ul_new_minute = char_to_digit(gs_uc_rtc_time[3]) * 10 +
  137.                         char_to_digit(gs_uc_rtc_time[4]);
  138.         gs_ul_new_second = char_to_digit(gs_uc_rtc_time[6]) * 10 +
  139.                         char_to_digit(gs_uc_rtc_time[7]);

  140.         /* Success input. Verification of data is left to RTC internal Error Checking. */
  141.         return 0;
  142. }

  143. /**
  144. * \brief Calculate week from year, month, day.
  145. */
  146. static uint32_t calculate_week(uint32_t ul_year, uint32_t ul_month,
  147.                 uint32_t ul_day)
  148. {
  149.         uint32_t ul_week;

  150.         if (ul_month == 1 || ul_month == 2) {
  151.                 ul_month += 12;
  152.                 --ul_year;
  153.         }

  154.         ul_week = (ul_day + 2 * ul_month + 3 * (ul_month + 1) / 5 + ul_year +
  155.                         ul_year / 4 - ul_year / 100 + ul_year / 400) % 7;

  156.         ++ul_week;

  157.         return ul_week;
  158. }

  159. /**
  160. * \brief Get new time. Successful value is put in gs_ul_new_year,
  161. * gs_ul_new_month, gs_ul_new_day, gs_ul_new_week.
  162. */
  163. static uint32_t get_new_date(void)
  164. {
  165.         uint8_t uc_key;
  166.         uint32_t i = 0;

  167.         /* Clear setting variable */
  168.         gs_ul_new_year = 0xFFFFFFFF;
  169.         gs_ul_new_month = 0xFFFFFFFF;
  170.         gs_ul_new_day = 0xFFFFFFFF;
  171.         gs_ul_new_week = 0xFFFFFFFF;

  172.         /* Use gs_uc_rtc_time[] as a format template */
  173.         while (1) {

  174.                 scanf("%c", (char *)&uc_key);

  175.                 /* End input */
  176.                 if (uc_key == 0x0d || uc_key == 0x0a) {
  177.                         puts("\r");
  178.                         break;
  179.                 }

  180.                 /* DEL or BACKSPACE */
  181.                 if (uc_key == 0x7f || uc_key == 0x08) {
  182.                         if (i > 0) {
  183.                                 /* End of date[], then one more back of index */
  184.                                 if (!gs_uc_date[i]) {
  185.                                         --i;
  186.                                 }

  187.                                 puts("\b \b");
  188.                                 --i;

  189.                                 /* Delimiter '/' for date is uneditable */
  190.                                 if (!((gs_uc_date[i]) >= '0' && (gs_uc_date[i]) <='9')
  191.                                                 && i > 0) {
  192.                                         puts("\b \b");
  193.                                         --i;
  194.                                 }
  195.                         }
  196.                 }

  197.                 /*
  198.                  * End of gs_uc_rtc_time[], no more input except the above DEL/BS,
  199.                  * or enter to end.
  200.                  */
  201.                 if (!gs_uc_date[i]) {
  202.                         continue;
  203.                 }

  204.                 printf("%c", uc_key);
  205.                 gs_uc_date[i++] = uc_key;

  206.         }

  207.         if (i == 0) {
  208.                 return 0;
  209.         }

  210.         if (i != 0 && gs_uc_date[i] != '\0' && i != 6) {
  211.                 /* Failure input */
  212.                 return 1;
  213.         }

  214.         /* MM-DD-YY */
  215.         gs_ul_new_month = char_to_digit(gs_uc_date[0]) * 10
  216.                         + char_to_digit(gs_uc_date[1]);
  217.         gs_ul_new_day = char_to_digit(gs_uc_date[3]) * 10
  218.                         + char_to_digit(gs_uc_date[4]);
  219.         if (i != 6) {
  220.                 /* For 'Set Date' option, get the input new year and new week. */
  221.                 gs_ul_new_year = char_to_digit(gs_uc_date[6]) * 1000 +
  222.                                 char_to_digit(gs_uc_date[7]) * 100 +
  223.                                 char_to_digit(gs_uc_date[8]) * 10 +
  224.                                 char_to_digit(gs_uc_date[9]);
  225.                 gs_ul_new_week = calculate_week(gs_ul_new_year, gs_ul_new_month,
  226.                                 gs_ul_new_day);
  227.         }

  228.         /*
  229.          * Success input. Verification of data is left to RTC internal Error
  230.          * Checking.
  231.          */
  232.         return 0;
  233. }


  234. /**
  235. * \brief Display the user interface on the terminal.
  236. */
  237. static void refresh_display(void)
  238. {
  239.         uint32_t ul_hour, ul_minute, ul_second;
  240.         uint32_t ul_year, ul_month, ul_day, ul_week;

  241.         if (gs_ul_state != STATE_MENU) {
  242.                 /* Not in menu display mode, in set mode. */
  243.         } else {
  244.                 /* Retrieve date and time */
  245.                 rtc_get_time(RTC, &ul_hour, &ul_minute, &ul_second);
  246.                 rtc_get_date(RTC, &ul_year, &ul_month, &ul_day, &ul_week);

  247.                 /* Display */
  248.                 if (!gs_ul_menu_shown) {
  249.                         puts("\n\rMenu:\n\r"
  250.                                         "  t - Set time\n\r"
  251.                                         "  d - Set date\n\r"
  252.                                         "  i - Set time alarm\n\r"
  253.                                         "  m - Set date alarm\r");
  254. #if ((SAM3S8) || (SAM3SD8) || (SAM4S) || (SAM4C) || (SAM4CP) || (SAM4CM) || (SAMV71)|| (SAMV70) || (SAME70) || (SAMS70))
  255.                         puts("  w - Generate Waveform\r");
  256. #endif
  257.                         if (gs_ul_alarm_triggered) {
  258.                                 puts("  c - Clear alarm notification\r");
  259.                         }

  260.                         printf("\n\r");

  261.                         gs_ul_menu_shown = 1;
  262.                 }

  263.                 /* Update current date and time */
  264.                 puts("\r");
  265.                 printf(" [Time/Date: %02u:%02u:%02u, %02u/%02u/%04u %s ][Alarm status:%s]",
  266.                         (unsigned int)ul_hour, (unsigned int)ul_minute, (unsigned int)ul_second,
  267.                         (unsigned int)ul_month, (unsigned int)ul_day, (unsigned int)ul_year,
  268.                         gs_uc_day_names[ul_week-1], gs_ul_alarm_triggered?"Triggered!":"");
  269.         }
  270. }

  271. /**
  272. * \brief Interrupt handler for the RTC. Refresh the display.
  273. */
  274. void RTC_Handler(void)
  275. {
  276.         uint32_t ul_status = rtc_get_status(RTC);

  277.         /* Second increment interrupt */
  278.         if ((ul_status & RTC_SR_SEC) == RTC_SR_SEC) {
  279.                 /* Disable RTC interrupt */
  280.                 rtc_disable_interrupt(RTC, RTC_IDR_SECDIS);

  281.                 refresh_display();

  282.                 rtc_clear_status(RTC, RTC_SCCR_SECCLR);

  283.                 rtc_enable_interrupt(RTC, RTC_IER_SECEN);
  284.         } else {
  285.                 /* Time or date alarm */
  286.                 if ((ul_status & RTC_SR_ALARM) == RTC_SR_ALARM) {
  287.                         /* Disable RTC interrupt */
  288.                         rtc_disable_interrupt(RTC, RTC_IDR_ALRDIS);

  289.                         gs_ul_alarm_triggered = 1;
  290.                         refresh_display();
  291.                         /* Show additional menu item for clear notification */
  292.                         gs_ul_menu_shown = 0;
  293.                         rtc_clear_status(RTC, RTC_SCCR_ALRCLR);
  294.                         rtc_enable_interrupt(RTC, RTC_IER_ALREN);
  295.                 }
  296.         }
  297. }


  298. /**
  299. * \brief Application entry point for RTC example.
  300. *
  301. * \return Unused (ANSI-C compatibility).
  302. */
  303. int main(void)
  304. {
  305.         uint8_t uc_key;

  306.         /* Initialize the SAM system */
  307.         sysclk_init();
  308.         board_init();

  309.         /* Initialize the console uart */
  310.         configure_console();

  311.         /* Output example information */
  312.         puts(STRING_HEADER);

  313.         /* Default RTC configuration, 24-hour mode */
  314.         rtc_set_hour_mode(RTC, 0);

  315.         /* Configure RTC interrupts */
  316.         NVIC_DisableIRQ(RTC_IRQn);
  317.         NVIC_ClearPendingIRQ(RTC_IRQn);
  318.         NVIC_SetPriority(RTC_IRQn, 0);
  319.         NVIC_EnableIRQ(RTC_IRQn);
  320.         rtc_enable_interrupt(RTC, RTC_IER_SECEN | RTC_IER_ALREN);

  321.         /* Refresh display once */
  322.         refresh_display();

  323.         /* Handle keypresses */
  324.         while (1) {

  325.                 scanf("%c", (char *)&uc_key);

  326.                 /* Set time */
  327.                 if (uc_key == 't') {
  328.                         gs_ul_state = STATE_SET_TIME;

  329.                         do {
  330.                                 puts("\n\r\n\r Set time(hh:mm:ss): ");
  331.                         } while (get_new_time());

  332.                         /* If valid input, none of the variables for time is 0xff. */
  333.                         if (gs_ul_new_hour != 0xFFFFFFFF && (gs_uc_rtc_time[2] == ':')
  334.                                         && (gs_uc_rtc_time[5] == ':')) {
  335.                                 if (rtc_set_time(RTC, gs_ul_new_hour, gs_ul_new_minute,
  336.                                                 gs_ul_new_second)) {
  337.                                         puts("\n\r Time not set, invalid input!\r");
  338.                                 }
  339.                         } else {
  340.                                 gs_uc_rtc_time[2] = ':';
  341.                                 gs_uc_rtc_time[5] = ':';
  342.                                 puts("\n\r Time not set, invalid input!\r");
  343.                         }

  344.                         gs_ul_state = STATE_MENU;
  345.                         gs_ul_menu_shown = 0;
  346.                         refresh_display();
  347.                 }

  348.                 /* Set date */
  349.                 if (uc_key == 'd') {
  350.                         gs_ul_state = STATE_SET_DATE;

  351.                         do {
  352.                                 puts("\n\r\n\r Set date(mm/dd/yyyy): ");
  353.                         } while (get_new_date());

  354.                         /* If valid input, none of the variables for date is 0xff(ff). */
  355.                         if (gs_ul_new_year != 0xFFFFFFFF && (gs_uc_date[2] == '/')
  356.                                         && (gs_uc_date[5] == '/')) {
  357.                                 if (rtc_set_date(RTC, gs_ul_new_year, gs_ul_new_month,
  358.                                                 gs_ul_new_day, gs_ul_new_week)) {
  359.                                         puts("\n\r Date not set, invalid input!\r");
  360.                                 }
  361.                         } else {
  362.                                 gs_uc_date[2] = '/';
  363.                                 gs_uc_date[5] = '/';
  364.                                 puts("\n\r Time not set, invalid input!\r");
  365.                         }

  366.                         /* Only 'mm/dd' is input. */
  367.                         if (gs_ul_new_month != 0xFFFFFFFF &&
  368.                                                 gs_ul_new_year == 0xFFFFFFFF) {
  369.                                 puts("\n\r Not Set for no year field!\r");
  370.                         }

  371.                         gs_ul_state = STATE_MENU;
  372.                         gs_ul_menu_shown = 0;
  373.                         refresh_display();
  374.                 }

  375.                 /* Set time alarm */
  376.                 if (uc_key == 'i') {
  377.                         gs_ul_state = STATE_SET_TIME_ALARM;

  378.                         rtc_clear_date_alarm(RTC);

  379.                         do {
  380.                                 puts("\n\r\n\r Set time alarm(hh:mm:ss): ");
  381.                         } while (get_new_time());

  382.                         if (gs_ul_new_hour != 0xFFFFFFFF && (gs_uc_rtc_time[2] == ':')
  383.                                         && (gs_uc_rtc_time[5] == ':')) {
  384.                                 if (rtc_set_time_alarm(RTC, 1, gs_ul_new_hour,
  385.                                                 1, gs_ul_new_minute, 1, gs_ul_new_second)) {
  386.                                         puts("\n\r Time alarm not set, invalid input!\r");
  387.                                 } else {
  388.                                         printf("\n\r Time alarm is set at %02u:%02u:%02u!",
  389.                                                 (unsigned int)gs_ul_new_hour, (unsigned int)gs_ul_new_minute,
  390.                                                 (unsigned int)gs_ul_new_second);
  391.                                 }
  392.                         } else {
  393.                                 gs_uc_rtc_time[2] = ':';
  394.                                 gs_uc_rtc_time[5] = ':';
  395.                                 puts("\n\r Time not set, invalid input!\r");
  396.                         }
  397.                         gs_ul_state = STATE_MENU;
  398.                         gs_ul_menu_shown = 0;
  399.                         gs_ul_alarm_triggered = 0;
  400.                         refresh_display();
  401.                 }

  402.                 /* Set date alarm */
  403.                 if (uc_key == 'm') {
  404.                         gs_ul_state = STATE_SET_DATE_ALARM;

  405.                         rtc_clear_time_alarm(RTC);

  406.                         do {
  407.                                 puts("\n\r\n\r Set date alarm(mm/dd/yyyy): ");
  408.                         } while (get_new_date());

  409.                         if (gs_ul_new_year != 0xFFFFFFFF && (gs_uc_date[2] == '/')
  410.                                         && (gs_uc_date[5] == '/')) {
  411.                                 if (rtc_set_date_alarm(RTC, 1, gs_ul_new_month, 1,
  412.                                                 gs_ul_new_day)) {
  413.                                         puts("\n\r Date alarm not set, invalid input!\r");
  414.                                 } else {
  415.                                         printf("\n\r Date alarm is set on %02u/%02u/%4u!",
  416.                                                         (unsigned int)gs_ul_new_month, (unsigned int)gs_ul_new_day,
  417.                                                         (unsigned int)gs_ul_new_year);
  418.                                 }
  419.                         } else {
  420.                                 gs_uc_date[2] = '/';
  421.                                 gs_uc_date[5] = '/';
  422.                                 puts("\n\r Date alarm not set, invalid input!\r");
  423.                         }
  424.                         gs_ul_state = STATE_MENU;
  425.                         gs_ul_menu_shown = 0;
  426.                         gs_ul_alarm_triggered = 0;
  427.                         refresh_display();
  428.                 }

  429. #if ((SAM3S8) || (SAM3SD8) || (SAM4S) || (SAM4C) || (SAM4CP) || (SAM4CM) || (SAMV71)|| (SAMV70) || (SAME70) || (SAMS70))
  430.                 /* Generate Waveform */
  431.                 if (uc_key == 'w') {
  432.                         gs_ul_state = STATE_WAVEFORM;
  433.                         puts("\n\rMenu:\n\r"
  434.                                         "  0 - No Waveform\n\r"
  435.                                         "  1 - 1 Hz square wave\n\r"
  436.                                         "  2 - 32 Hz square wave\n\r"
  437.                                         "  3 - 64 Hz square wave\n\r"
  438.                                         "  4 - 512 Hz square wave\n\r"
  439.                                         "  5 - Toggles when alarm flag rise\n\r"
  440.                                         "  6 - Copy of the alarm flag\n\r"
  441.                                         "  7 - Duty cycle programmable pulse\n\r"
  442.                                         "  8 - Quit\r");

  443.                         while (1) {
  444.                                 scanf("%c", (char *)&uc_key);

  445.                                 if ((uc_key >= '0') && (uc_key <= '7')) {
  446.                                         rtc_set_waveform(RTC, 0, char_to_digit(uc_key));
  447.                                 }

  448.                                 if (uc_key == '8') {
  449.                                         gs_ul_state = STATE_MENU;
  450.                                         gs_ul_menu_shown = 0;
  451.                                         refresh_display();
  452.                                         break;
  453.                                 }
  454.                         }
  455.                 }
  456. #endif
  457.                 /* Clear trigger flag */
  458.                 if (uc_key == 'c') {
  459.                         gs_ul_alarm_triggered = 0;
  460.                         gs_ul_menu_shown = 0;
  461.                         refresh_display();
  462.                 }

  463.         }

  464. }

  465. /// [url=home.php?mod=space&uid=1302964]@cond[/url] 0
  466. /**INDENT-OFF**/
  467. #ifdef __cplusplus
  468. }
  469. #endif
  470. /**INDENT-ON**/
  471. /// @endcond


运行结果:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2404

主题

7001

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部