gd32f470rtc_interrupt_enable中没有秒中断

时间: 2025-07-12 08:47:35 AIGC 浏览: 24
<think>好的,我现在需要帮助用户解决GD32F470 RTC秒中断未启用的问题。首先,我得回顾一下用户提供的引用内容。引用[1]提到了GD32常见的时钟配置问题,比如寄存器写入失败和代码修改后运行变慢,这可能和时钟配置或寄存器操作有关。引用[2]则建议下载官网的固件库,可能涉及到库函数的使用是否正确。 首先,RTC秒中断未启用可能有几个原因。我得检查用户是否在初始化过程中正确配置了RTC的中断使能位。GD32的RTC通常需要配置中断控制寄存器,比如RTC_CTL中的SCIE位。如果用户没有设置这个位,秒中断就不会被触发。 接下来,NVIC的配置也很重要。即使RTC模块的中断已经使能,如果NVIC中没有对应的中断通道使能,或者优先级设置不当,中断也无法正常工作。需要确认用户是否在代码中正确配置了NVIC,比如使用nvic_irq_enable函数。 然后,检查固件库版本是否支持秒中断功能。如果用户使用的库版本较旧,可能存在bug或不支持某些功能。建议用户到官网下载最新固件库,并参考最新的例程,如引用[2]提到的。 另外,RTC时钟源的配置是否正确也会影响中断。GD32的RTC通常需要外部低速时钟(LXTAL)或内部低速RC(IRC40K)。如果时钟源未正确使能或校准,RTC可能无法正常工作,导致中断不触发。需要确认用户是否正确初始化了RTC时钟源,并等待其稳定。 还有可能用户没有正确编写中断服务函数。RTC的秒中断服务函数需要正确命名,并在其中清除中断标志位,否则中断会一直被挂起,无法再次触发。例如,检查是否有RTC_IRQHandler函数,并调用rtc_interrupt_flag_clear来清除标志。 最后,硬件问题也不容忽视,比如外部晶振是否正常起振,电路连接是否良好。可以建议用户用示波器检查LXTAL的波形,或者尝试切换到内部时钟源测试。 总结可能的解决步骤:检查RTC中断使能位、NVIC配置、固件库版本、时钟源初始化、中断服务函数编写以及硬件连接。这些步骤应该能帮助用户定位问题所在。</think>关于GD32F470 RTC秒中断未启用的原因及解决方法,可按照以下步骤排查: ### 一、中断使能寄存器配置 1. 确认`RTC_CTL`寄存器中秒中断使能位(SCIE)是否置1 ```c rtc_interrupt_enable(RTC_INT_SECOND); //使用固件库函数启用秒中断[^2] ``` 2. 检查`RTC_PSCH`和`RTC_PSCL`分频寄存器配置是否正确,分频值需满足: $$f_{rtc} = \frac{f_{rtc\_clk}}{(PREDIV_A+1)(PREDIV_S+1)}$$ ### 二、NVIC中断控制器配置 1. 确认已使能RTC全局中断 ```c nvic_irq_enable(RTC_IRQn, 0, 0); //需在NVIC中启用中断通道[^1] ``` ### 三、固件库版本验证 1. 下载最新固件库(V3.0.4及以上)并检查`gd32f4xx_rtc.h`中是否存在`RTC_INT_SECOND`定义 ### 四、时钟源配置排查 1. 检查RTC时钟树配置是否正常: ```c rcu_osci_on(RCU_LXTAL); //必须启用外部低速时钟或内部低速时钟 while(rcu_osci_stab_wait(RCU_LXTAL) == ERROR){} ``` ### 五、中断服务函数实现 1. 必须正确定义中断服务函数并清除标志位 ```c void RTC_IRQHandler(void) { if(rtc_flag_get(RTC_FLAG_SECOND)){ rtc_flag_clear(RTC_FLAG_SECOND); //必须清除中断标志 //用户代码 } } ``` ### 六、硬件检查 1. 使用示波器测量LXTAL(32.768KHz)晶振起振情况 2. 检查VBAT引脚供电是否正常(需保持≥1.8V)
阅读全文

相关推荐

/**************************************************************************************************** * @file main.c * @version V2.0 * @brief ¹¤ÒµÇ¶Èëʽϵͳ - µçѹ¼à²âϵͳ **************************************************************************************************** * * ʵÑéÆ½Ì¨: GD32F470VET6 * ¹¦ÄÜ˵Ã÷: µçѹ²É¼¯¡¢´¦Àí¡¢ÏÔʾ¡¢´æ´¢ÏµÍ³ * Ö§³Ö×Լ졢ʱ¼äÉèÖá¢ÅäÖùÜÀí¡¢²ÉÑù¿ØÖÆ¡¢Êý¾Ý´¦ÀíºÍ´æ´¢¹¦ÄÜ **************************************************************************************************** */ #include <./SYSTEM/sys/sys.h> #include <./SYSTEM/usart/usart.h> #include <./SYSTEM/delay/delay.h> #include <./BSP/LED/led.h> #include <./BSP/OLED/oled.h> #include <./BSP/KEY/key.h> #include <./BSP/RTC/rtc.h> #include <./BSP/ADC/adc.h> #include <./BSP/SDIO/sd_conf.h> #include <./BSP/NORFLASH/norflash.h> #include <./FATFS/exfuns/exfuns.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <./BSP/TIMER/timer.h> /* È«¾Ö±äÁ¿¶¨Òå */ typedef struct { float ratio; // ±ä±ÈϵÊý float limit; // µçѹãÐÖµ uint8_t sample_cycle; // ²ÉÑùÖÜÆÚ(5/10/15) uint32_t log_file_id; // ÈÕÖ¾ÎļþID } SystemConfig; SystemConfig sys_config = {1.0, 100.0, 5, 0}; // ĬÈÏÅäÖà uint8_t sampling_enabled = 0; // ²ÉÑù״̬±êÖ¾ uint8_t sample_count = 0; // µ±Ç°Îļþ²ÉÑù¼ÆÊý uint8_t encrypt_mode = 0; // ¼ÓÃܴ洢ģʽ FIL sample_file, overlimit_file, log_file, hide_file; // Îļþ¶ÔÏó char current_filename[50]; // µ±Ç°ÎļþÃû»º´æ uint32_t seconds_counter = 0; // Ãë¼ÆÊýÆ÷ uint8_t led_blink_state = 0; // LEDÉÁ˸״̬ uint32_t last_sample_time = 0; // ÉϴβÉÑùʱ¼ä /* ÔÚÈ«¾Ö±äÁ¿¶¨Ò岿·ÖÌí¼Ó */ uint8_t hide_output_mode = 0; // Òþ²ØÊä³öģʽ±êÖ¾ /* Îļþ´ò¿ª×´Ì¬±êÖ¾ */ uint8_t sample_file_open = 0; uint8_t overlimit_file_open = 0; uint8_t log_file_open = 0; uint8_t hide_file_open = 0; /* ʱ¼ä½á¹¹Ìå */ typedef struct { uint8_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; uint8_t week; } rtc_time_t; /* º¯ÊýÉùÃ÷ */ void system_self_test(void); void set_rtc_time(char *datetime); void read_config_file(void); void set_ratio(void); void set_limit(void); void save_config_to_flash(void); void read_config_from_flash(void); void start_sampling(void); void stop_sampling(void); void adjust_sample_cycle(uint8_t cycle); void process_adc_sample(void); void store_sample_data(float voltage, uint8_t overlimit); void store_overlimit_data(float voltage); void store_log_entry(const char *action); void store_hide_data(uint32_t timestamp, float voltage); uint32_t datetime_to_unix(rtc_time_t *time); void encode_voltage(float voltage, uint8_t *buffer); void oled_display_status(void); void get_current_time(rtc_time_t *time); uint32_t get_system_time(void); /* Ìí¼ÓÒÔÏ´úÂëµ½timer.cÎļþĩβ */ volatile uint32_t timer6_counter = 0; // ¶¨Ê±Æ÷¼ÆÊýÆ÷ volatile uint8_t timer6_sample_flag = 0; // ²ÉÑù±êÖ¾ volatile uint8_t timer6_led_flag = 0; // LEDÉÁ˸±êÖ¾ /* ÔÚÈ«¾Ö±äÁ¿¶¨Ò岿·ÖÌí¼Ó */ volatile uint8_t timer6_time_update_flag = 0; // ʱ¼ä¸üбêÖ¾ /** * @brief TIMER6ÖжϷþÎñº¯Êý * @param ÎÞ * @retval ÎÞ */ void TIMER6_IRQHandler(void) { if(timer_interrupt_flag_get(TIMER6, TIMER_INT_FLAG_UP) != RESET) { timer_interrupt_flag_clear(TIMER6, TIMER_INT_FLAG_UP); timer6_counter++; /* 1ÃëLEDÉÁ˸¿ØÖÆ */ if(timer6_counter % 1000 == 0) { timer6_led_flag = 1; timer6_time_update_flag = 1; // ÐÂÔöʱ¼ä¸üбêÖ¾ } /* ²ÉÑùÖÜÆÚ¿ØÖÆ */ if(sampling_enabled && (timer6_counter % (sys_config.sample_cycle * 1000) == 0)) { timer6_sample_flag = 1; } } } float oled_voltage; /** * @brief ¸üÐÂOLEDʱ¼äÏÔʾ * @param ÎÞ * @retval ÎÞ */ void update_oled_time(void) { uint16_t adcx; float temp; rtc_time_t current_time; get_current_time(¤t_time); char time_str[12]; sprintf(time_str, "%02d:%02d:%02d", current_time.hour, current_time.minute, current_time.second); oled_show_string(0, 0, time_str, 12); adcx = adc_get_result_average(ADC_ADCX_CHY, 20); /* »ñȡͨµÀCHYµÄת»»Öµ£¬20´Îȡƽ¾ù */ oled_voltage = (float)adcx * (3.3 / 4096); /* ¼ÆËãʵ¼Êµçѹֵ */ char volt_str[16]; sprintf(volt_str, "%.2fV", oled_voltage); /* ¸ñʽ»¯Îª×Ö·û´®£¬±£ÁôÁ½Î»Ð¡Êý */ oled_show_string(0, 16, volt_str, 12); /* ÔÚÖ¸¶¨Î»ÖÃ(0,16)ÏÔʾ×Ö·û´®£¬×ÖÌå´óС12 */ oled_refresh_gram(); /* Ë¢ÐÂÏÔʾ */ oled_refresh_gram(); } /** * @brief »ñȡϵͳʱ¼ä£¨ºÁÃ룩 * @param ÎÞ * @retval µ±Ç°ÏµÍ³Ê±¼ä£¨ºÁÃ룩 */ uint32_t get_system_time(void) { static uint32_t counter = 0; static uint32_t last_tick = 0; uint32_t current_tick = sys_tick_get(); counter += (current_tick - last_tick); last_tick = current_tick; return counter; } /** * @brief »ñÈ¡µ±Ç°Ê±¼ä * @param time: ʱ¼ä½á¹¹ÌåÖ¸Õë * @retval ÎÞ */ void get_current_time(rtc_time_t *time) { uint8_t ampm; rtc_get_date(&time->year, &time->month, &time->day, &time->week); rtc_get_time(&time->hour, &time->minute, &time->second, &m); } /** * @brief ϵͳ×Ô¼ì * @param ÎÞ * @retval ÎÞ */ void system_self_test(void) { uint16_t flash_id = norflash_read_id(); uint8_t sd_status = (SD_OK == sdio_sd_init()) ? 1 : 0; rtc_time_t current_time; get_current_time(¤t_time); printf("=====system selftest=====\r\n"); printf("flash.............%s\r\n", (flash_id == GD25Q40) ? "ok" : "error"); printf("TF card............%s\r\n", sd_status ? "ok" : "error"); printf("flash ID:0x%04X\r\n", flash_id); if(sd_status) { uint32_t capacity = sd_card_capacity_get() >> 10; // KB printf("TF card memory:%lu KB\r\n", capacity); } else { printf("can not find TF card\r\n"); } printf("RTC:20%02d-%02d-%02d %02d:%02d:%02d\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); printf("=====system selftest=====\r\n"); } /** * @brief ÉèÖÃRTCʱ¼ä * @param datetime: ʱ¼ä×Ö·û´®(¸ñʽ:2025-01-01 12:00:30) * @retval ÎÞ */ void set_rtc_time(char *datetime) { int year, month, day, hour, min, sec; sscanf(datetime, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec); rtc_set_date(year, month, day, 0); // ÐÇÆÚÉèΪ0 rtc_set_time(hour, min, sec, 0); // AM/PMÉèΪ0 (24Ð¡Ê±ÖÆ) printf("RTC config success\r\n"); printf("Time:20%02d-%02d-%02d %02d:%02d:%02d\r\n", year, month, day, hour, min, sec); } /** * @brief ¶ÁÈ¡ÅäÖÃÎļþ * @param ÎÞ * @retval ÎÞ */ void read_config_file(void) { FIL file; FRESULT res; char line[64]; res = f_open(&file, "config.ini", FA_READ); if (res != FR_OK) { printf("config.ini file not found.\r\n"); return; } while (f_gets(line, sizeof(line), &file)) { if (strstr(line, "Ratio")) { sscanf(line, "Ch0 = %f", &sys_config.ratio); printf("Ratio = %.1f\r\n", sys_config.ratio); } else if (strstr(line, "Limit")) { sscanf(line, "ch0 = %f", &sys_config.limit); printf("Limit = %.1f\r\n", sys_config.limit); } } f_close(&file); printf("config read success\r\n"); } /** * @brief ÉèÖñä±È * @param ÎÞ * @retval ÎÞ */ void set_ratio(void) { printf("Ratio = %.1f\r\n", sys_config.ratio); printf("Input value(0-100):\r\n"); /* µÈ´ýÓû§ÊäÈë */ uint8_t key; char input[16] = {0}; uint8_t index = 0; while (1) { key = key_scan(0); if (key) { if (key == KEY1_PRES) { // »Ø³µ float new_ratio = atof(input); if (new_ratio >= 0 && new_ratio <= 100) { sys_config.ratio = new_ratio; printf("Ratio modified success\r\n"); printf("Ratio = %.1f\r\n", sys_config.ratio); store_log_entry("Ratio modified"); } else { printf("Ratio invalid\r\n"); printf("Ratio = %.1f\r\n", sys_config.ratio); } break; } else if (key == KEY2_PRES) { // Í˸ñ if (index > 0) input[--index] = '\0'; } else { // Êý×ÖÊäÈë if (index < 15) { input[index++] = '0' + (key - 1); input[index] = '\0'; } } } delay_ms(10); } } /** * @brief ÉèÖÃãÐÖµ * @param ÎÞ * @retval ÎÞ */ void set_limit(void) { printf("Limit = %.1f\r\n", sys_config.limit); printf("Input value(0-500):\r\n"); /* µÈ´ýÓû§ÊäÈë */ uint8_t key; char input[16] = {0}; uint8_t index = 0; while (1) { key = key_scan(0); if (key) { if (key == KEY1_PRES) { // »Ø³µ float new_limit = atof(input); if (new_limit >= 0 && new_limit <= 500) { sys_config.limit = new_limit; printf("Limit modified success\r\n"); printf("Limit = %.1f\r\n", sys_config.limit); store_log_entry("Limit modified"); } else { printf("Limit invalid\r\n"); printf("Limit = %.1f\r\n", sys_config.limit); } break; } else if (key == KEY2_PRES) { // Í˸ñ if (index > 0) input[--index] = '\0'; } else { // Êý×ÖÊäÈë if (index < 15) { input[index++] = '0' + (key - 1); input[index] = '\0'; } } } delay_ms(10); } } /** * @brief ±£´æÅäÖõ½Flash * @param ÎÞ * @retval ÎÞ */ void save_config_to_flash(void) { printf("ratio = %.1f\r\n", sys_config.ratio); printf("limit: %.2f\r\n", sys_config.limit); /* ²Á³ýFlashÉÈÇø²¢Ð´ÈëÅäÖà */ norflash_erase_sector(0); norflash_write((uint8_t*)&sys_config, 0, sizeof(sys_config)); printf("save parameters to flash\r\n"); store_log_entry("Config saved"); } /** * @brief ´ÓFlash¶ÁÈ¡ÅäÖà * @param ÎÞ * @retval ÎÞ */ void read_config_from_flash(void) { SystemConfig config; norflash_read((uint8_t*)&config, 0, sizeof(config)); /* ÑéÖ¤Êý¾ÝÓÐЧÐÔ */ if (config.ratio >= 0 && config.ratio <= 100 && config.limit >= 0 && config.limit <= 500) { sys_config = config; } printf("read parameters from flash\r\n"); printf("ratio:%.1f\r\n", sys_config.ratio); printf("limit:%.2f\r\n", sys_config.limit); } /** * @brief ¿ªÊ¼²ÉÑù * @param ÎÞ * @retval ÎÞ */ void start_sampling(void) { sampling_enabled = 1; led_blink_state = 1; LED1(1); // ³õʼµãÁÁ timer6_counter = 0; // ÖØÖö¨Ê±Æ÷¼ÆÊýÆ÷ timer6_sample_flag = 0; timer6_led_flag = 0; timer6_time_update_flag = 0; /* ³õʼ»¯OLEDÏÔʾ */ rtc_time_t current_time; get_current_time(¤t_time); char time_str[12], volt_str[16]; sprintf(time_str, "%02d:%02d:%02d", current_time.hour, current_time.minute, current_time.second); sprintf(volt_str, "0.00V"); // ³õʼµçѹֵ oled_clear(); oled_show_string(0, 0, time_str, 12); oled_show_string(0, 16, volt_str, 12); oled_refresh_gram(); /* ÆôÓö¨Ê±Æ÷ */ timer_enable(TIMER6); printf("Periodic Sampling\r\n"); printf("sample cycle: %ds\r\n", sys_config.sample_cycle); store_log_entry("Sampling started"); } /** * @brief Í£Ö¹²ÉÑù * @param ÎÞ * @retval ÎÞ */ void stop_sampling(void) { sampling_enabled = 0; LED1(0); LED2(0); /* ½ûÓö¨Ê±Æ÷ */ timer_disable(TIMER6); oled_clear(); oled_show_string(0, 0, "system idle", 12); oled_refresh_gram(); printf("Periodic Sampling STOP\r\n"); /* ¹Ø±ÕËùÓдò¿ªµÄÎļþ */ if (sample_file_open) { f_close(&sample_file); sample_file_open = 0; } if (overlimit_file_open) { f_close(&overlimit_file); overlimit_file_open = 0; } if (hide_file_open) { f_close(&hide_file); hide_file_open = 0; } store_log_entry("Sampling stopped"); } /** * @brief µ÷Õû²ÉÑùÖÜÆÚ * @param cycle: ²ÉÑùÖÜÆÚ(5/10/15) * @retval ÎÞ */ void adjust_sample_cycle(uint8_t cycle) { sys_config.sample_cycle = cycle; /* ÖØÐÂÅäÖö¨Ê±Æ÷ */ timer_disable(TIMERX_INT); timer_deinit(TIMERX_INT); /* ¸ù¾Ý²»Í¬ÖÜÆÚÉèÖö¨Ê±Æ÷ */ // switch(cycle) { // case 5: // timerx_int_init(2000-1, 120-1); // 240MHz/(239+1)=1MHz, (999+1)/1MHz=1ms // break; // case 10: // timerx_int_init(1500-1, 120-1); // 10ÃëÖÜÆÚ // break; // case 15: // timerx_int_init(1000-1, 120-1); // 15ÃëÖÜÆÚ // break; // } switch(cycle) { case 5: timer_disable(TIMERX_INT); timer_deinit(TIMERX_INT); timerx_int_init(1500-1, 120-1); // 5ÃëÖÜÆÚ break; case 10: timer_disable(TIMERX_INT); timer_deinit(TIMERX_INT); timerx_int_init(1000-1, 120-1); // 10ÃëÖÜÆÚ break; case 15: timer_disable(TIMERX_INT); timer_deinit(TIMERX_INT); timerx_int_init(1000-1, 120-1); // 15ÃëÖÜÆÚ break; } if(sampling_enabled) { timer_enable(TIMERX_INT); } printf("sample cycle adjust: %ds\r\n", cycle); store_log_entry("Sample cycle adjusted"); /* ±£´æÐÂÖÜÆÚµ½Flash */ save_config_to_flash(); } /** * @brief ´¦ÀíADC²ÉÑù * @param ÎÞ * @retval ÎÞ */ void process_adc_sample(void) { rtc_time_t current_time; get_current_time(¤t_time); /* ¶ÁÈ¡ADCÖµ²¢×ª»»Îªµçѹ */ // uint16_t adc_value = adc_get_result_average(ADC_ADCX_CHY, 20); // float voltage = (float)adc_value * (3.3 / 4096) * sys_config.ratio; // // /* OLEDÏÔʾ - Ö»¸üеçѹ²¿·Ö */ // char volt_str[16]; // sprintf(volt_str, "%.2fV", voltage); // // oled_show_string(0, 16, volt_str, 12); // oled_refresh_gram(); /* ´®¿ÚÊä³ö */ printf("20%02d-%02d-%02d %02d:%02d:%02d ch0 = %.2fV", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, oled_voltage); /* ³¬ÏÞ¼ì²â */ uint8_t overlimit = 0; if (oled_voltage > sys_config.limit/10) { LED2(1); overlimit = 1; printf(" OverLimit(%.2f)!", sys_config.limit); /* ´æ´¢³¬ÏÞÊý¾Ý */ store_overlimit_data(oled_voltage); } else if(oled_voltage <= sys_config.limit/10) { LED2(0); } printf("\r\n"); /* ´æ´¢²ÉÑùÊý¾Ý */ store_sample_data(oled_voltage, overlimit); /* ´æ´¢¼ÓÃÜÊý¾Ý */ if (encrypt_mode) { uint32_t unix_time = datetime_to_unix(¤t_time); store_hide_data(unix_time, oled_voltage); } /* Òþ²ØÄ£Ê½Êä³ö */ if (hide_output_mode) { /* ת»»ÎªUnixʱ¼ä´Á */ uint32_t unix_time = datetime_to_unix(¤t_time); /* µçѹֵ·Ö½â */ uint16_t integer_part = (uint16_t)oled_voltage; uint16_t fractional_part = (uint16_t)((oled_voltage - integer_part) * 65536); /* Éú³ÉÒþ²Ø¸ñʽ×Ö·û´® */ char hide_str[20]; sprintf(hide_str, "%08X%04X%04X", unix_time, integer_part, fractional_part); /* Ìí¼Ó³¬ÏÞ±ê¼Ç */ if (overlimit) { printf("%s*\r\n", hide_str); } else { printf("%s\r\n", hide_str); } } } /** * @brief ´æ´¢²ÉÑùÊý¾Ý * @param voltage: µçѹֵ * @param overlimit: ÊÇ·ñ³¬ÏÞ * @retval ÎÞ */ void store_sample_data(float voltage, uint8_t overlimit) { /* ÿ10ÌõÊý¾Ý´´½¨ÐÂÎļþ */ if (sample_count == 0 || sample_count >= 10) { if (sample_file_open) { f_close(&sample_file); sample_file_open = 0; } rtc_time_t current_time; get_current_time(¤t_time); sprintf(current_filename, "sample/sampleData20%02d%02d%02d%02d%02d%02d.txt", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); f_mkdir("sample"); if (f_open(&sample_file, current_filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { sample_file_open = 1; } sample_count = 0; } /* дÈëÊý¾Ý */ rtc_time_t current_time; get_current_time(¤t_time); char data_line[64]; sprintf(data_line, "20%02d-%02d-%02d %02d:%02d:%02d,%.2f,%d\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, voltage, overlimit); UINT bw; if (sample_file_open) { f_write(&sample_file, data_line, strlen(data_line), &bw); f_sync(&sample_file); } sample_count++; } /** * @brief ´æ´¢³¬ÏÞÊý¾Ý * @param voltage: µçѹֵ * @retval ÎÞ */ void store_overlimit_data(float voltage) { /* ÿ10ÌõÊý¾Ý´´½¨ÐÂÎļþ */ static uint8_t overlimit_count = 0; if (overlimit_count == 0 || overlimit_count >= 10) { if (overlimit_file_open) { f_close(&overlimit_file); overlimit_file_open = 0; } rtc_time_t current_time; get_current_time(¤t_time); sprintf(current_filename, "overLimit/overLimit%04d%02d%02d%02d%02d%02d.txt", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); f_mkdir("overLimit"); if (f_open(&overlimit_file, current_filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { overlimit_file_open = 1; } overlimit_count = 0; } /* дÈëÊý¾Ý */ rtc_time_t current_time; get_current_time(¤t_time); char data_line[64]; sprintf(data_line, "20%02d-%02d-%02d %02d:%02d:%02d,%.2f\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, voltage); UINT bw; if (overlimit_file_open) { f_write(&overlimit_file, data_line, strlen(data_line), &bw); f_sync(&overlimit_file); } overlimit_count++; } /** * @brief ´æ´¢ÈÕÖ¾ÌõÄ¿ * @param action: ²Ù×÷ÃèÊö * @retval ÎÞ */ void store_log_entry(const char *action) { static uint8_t log_initialized = 0; /* Éϵçʱ´´½¨ÐÂÈÕÖ¾Îļþ */ if (!log_initialized) { sprintf(current_filename, "log/log%lu.txt", sys_config.log_file_id); f_mkdir("log"); if (f_open(&log_file, current_filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { log_file_open = 1; log_initialized = 1; } /* дÈë³õʼÐÅÏ¢ */ if (log_file_open) { rtc_time_t current_time; get_current_time(¤t_time); char header[128]; sprintf(header, "System started at 20%02d-%02d-%02d %02d:%02d:%02d\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); UINT bw; f_write(&log_file, header, strlen(header), &bw); f_sync(&log_file); } } /* дÈëÈÕÖ¾ÌõÄ¿ */ if (log_file_open) { rtc_time_t current_time; get_current_time(¤t_time); char log_entry[128]; sprintf(log_entry, "[20%02d-%02d-%02d %02d:%02d:%02d] %s\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, action); UINT bw; f_write(&log_file, log_entry, strlen(log_entry), &bw); f_sync(&log_file); } } /** * @brief ´æ´¢¼ÓÃÜÊý¾Ý * @param timestamp: Unixʱ¼ä´Á * @param voltage: µçѹֵ * @retval ÎÞ */ void store_hide_data(uint32_t timestamp, float voltage) { /* ÿ10ÌõÊý¾Ý´´½¨ÐÂÎļþ */ static uint8_t hide_count = 0; if (hide_count == 0 || hide_count >= 10) { if (hide_file_open) { f_close(&hide_file); hide_file_open = 0; } rtc_time_t current_time; get_current_time(¤t_time); sprintf(current_filename, "hideData/hideData%04d%02d%02d%02d%02d%02d.txt", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); f_mkdir("hideData"); if (f_open(&hide_file, current_filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { hide_file_open = 1; } hide_count = 0; } /* ±àÂëµçѹֵ */ uint8_t voltage_buf[8]; encode_voltage(voltage, voltage_buf); /* дÈëÊý¾Ý */ char data_line[32]; sprintf(data_line, "%08X", timestamp); for (int i = 0; i < 8; i++) { sprintf(data_line + 8 + i*2, "%02X", voltage_buf[i]); } strcat(data_line, "\r\n"); UINT bw; if (hide_file_open) { f_write(&hide_file, data_line, strlen(data_line), &bw); f_sync(&hide_file); } hide_count++; } /** * @brief ÈÕÆÚʱ¼äתUnixʱ¼ä´Á * @param time: ÈÕÆÚʱ¼ä½á¹¹Ìå * @retval Unixʱ¼ä´Á */ uint32_t datetime_to_unix(rtc_time_t *time) { struct tm t; t.tm_year = 2000 + time->year - 1900; t.tm_mon = time->month - 1; t.tm_mday = time->day; t.tm_hour = time->hour; t.tm_min = time->minute; t.tm_sec = time->second; t.tm_isdst = -1; return mktime(&t); } /** * @brief ±àÂëµçѹֵ * @param voltage: µçѹֵ * @param buffer: Êä³ö»º³åÇø(8×Ö½Ú) * @retval ÎÞ */ void encode_voltage(float voltage, uint8_t *buffer) { uint16_t integer_part = (uint16_t)voltage; uint16_t fractional_part = (uint16_t)((voltage - integer_part) * 65536); buffer[0] = (integer_part >> 8) & 0xFF; buffer[1] = integer_part & 0xFF; buffer[2] = (fractional_part >> 8) & 0xFF; buffer[3] = fractional_part & 0xFF; /* ͬʱ´æ´¢Ô­Ê¼Êý¾ÝÓÃÓÚУÑé */ uint32_t raw = *(uint32_t*)&voltage; buffer[4] = (raw >> 24) & 0xFF; buffer[5] = (raw >> 16) & 0xFF; buffer[6] = (raw >> 8) & 0xFF; buffer[7] = raw & 0xFF; } /** * @brief OLED״̬ÏÔʾ * @param ÎÞ * @retval ÎÞ */ void oled_display_status(void) { if (sampling_enabled) { rtc_time_t current_time; get_current_time(¤t_time); char time_str[12], status[16]; sprintf(time_str, "%02d:%02d:%02d", current_time.hour, current_time.minute, current_time.second); sprintf(status, "CYC:%ds", sys_config.sample_cycle); oled_clear(); oled_show_string(0, 0, time_str, 12); oled_show_string(0, 16, status, 12); oled_refresh_gram(); } else { oled_clear(); oled_show_string(0, 0, "system idle", 12); oled_refresh_gram(); } } /* Ìí¼ÓÈ«¾Ö±äÁ¿ */ extern volatile uint8_t timer6_sample_flag; extern volatile uint8_t timer6_led_flag; int main(void) { /* Ó²¼þ³õʼ»¯ */ delay_init(240); usart_init(115200); led_init(); key_init(); oled_init(); adc_init(); norflash_init(); rtc_config(); // ÐÞ¸ÄΪµ÷ÓÃrtc_config /* ³õʼ»¯¶¨Ê±Æ÷6 - 1msÖÐ¶Ï */ timerx_int_init(1000-1, 120-1); // 240MHz/(239+1)=1MHz, (999+1)/1MHz=1ms /* ¹ÒÔØÎļþϵͳ */ FATFS fs; f_mount(&fs, "0:", 1); /* ´ÓFlash¼ÓÔØÅäÖà */ read_config_from_flash(); printf("=====system init=====\r\n"); printf("Device_ID:2025-CIMC\r\n"); printf("=====system ready=====\r\n"); /* ³õʼ»¯ÈÕÖ¾ */ sys_config.log_file_id++; // ÿ´ÎÉϵçµÝÔö save_config_to_flash(); // ±£´æÐµÄÎļþID store_log_entry("System started"); /* ³õʼOLEDÏÔʾ */ oled_display_status(); float last_voltage = 0.0; // ±£´æÉÏÒ»´Î²ÉÑùµÄµçѹֵ /* Ö÷Ñ­»· */ uint8_t key; while (1) { /* °´¼ü´¦Àí */ key = key_scan(0); switch (key) { case KEY1_PRES: // ²ÉÑùÆôÍ£ if (sampling_enabled) stop_sampling(); else start_sampling(); break; case KEY2_PRES: // ÖÜÆÚ5s adjust_sample_cycle(5); break; case KEY3_PRES: // ÖÜÆÚ10s adjust_sample_cycle(10); break; case KEY4_PRES: // ÖÜÆÚ15s adjust_sample_cycle(15); break; case WKUP_PRES: // ¼ÓÃÜģʽÇл» encrypt_mode = !encrypt_mode; store_log_entry(encrypt_mode ? "Encrypt enabled" : "Encrypt disabled"); break; } /* ´®¿ÚÃüÁî´¦Àí */ if (g_usart_rx_sta & 0x8000) { uint16_t len = g_usart_rx_sta & 0x3fff; g_usart_rx_buf[len] = '\0'; g_usart_rx_sta = 0; char *cmd = (char*)g_usart_rx_buf; if (strcmp(cmd, "test") == 0) { system_self_test(); } else if (strncmp(cmd, "RTC Config", 10) == 0) { set_rtc_time(cmd + 11); } else if (strcmp(cmd, "RTC now") == 0) { rtc_time_t current_time; get_current_time(¤t_time); printf("Current Time:20%02d-%02d-%02d %02d:%02d:%02d\r\n", current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second); } else if (strcmp(cmd, "conf") == 0) { read_config_file(); } else if (strcmp(cmd, "ratio") == 0) { set_ratio(); } else if (strcmp(cmd, "limit") == 0) { set_limit(); } else if (strcmp(cmd, "config save") == 0) { save_config_to_flash(); } else if (strcmp(cmd, "config read") == 0) { read_config_from_flash(); } else if (strcmp(cmd, "start") == 0) { start_sampling(); } else if (strcmp(cmd, "stop") == 0) { stop_sampling(); } else if (strcmp(cmd, "hide") == 0) { hide_output_mode = 1; printf("Hide output mode enabled\r\n"); } else if (strcmp(cmd, "unhide") == 0) { hide_output_mode = 0; printf("Hide output mode disabled\r\n"); } else if (strcmp(cmd, "encrypt") == 0) { // ÐÞ¸ÄÃüÁîÃû±ÜÃâ³åÍ» encrypt_mode = !encrypt_mode; printf("Encrypt mode %s\r\n", encrypt_mode ? "enabled" : "disabled"); store_log_entry(encrypt_mode ? "Encrypt enabled" : "Encrypt disabled"); } } /* LEDÉÁ˸´¦Àí */ if (timer6_led_flag && sampling_enabled) { timer6_led_flag = 0; led_blink_state = !led_blink_state; LED1(led_blink_state); } /* ʱ¼ä¸üд¦Àí */ if (timer6_time_update_flag) { timer6_time_update_flag = 0; if (sampling_enabled) { update_oled_time(); // ÿÃë¸üÐÂʱ¼äÏÔʾ } } /* ²ÉÑù´¦Àí */ if (timer6_sample_flag && sampling_enabled) { timer6_sample_flag = 0; process_adc_sample(); } // /* ²ÉÑù¶¨Ê± */ // if (sampling_enabled) { // uint32_t current_time = get_system_time(); // if (current_time - last_sample_time >= sys_config.sample_cycle * 1000) { // last_sample_time = current_time; // process_adc_sample(); // // /* LEDÉÁ˸¿ØÖÆ */ // led_blink_state = !led_blink_state; // LED1(led_blink_state); // } // } delay_ms(1); } }修改代码

大家在看

recommend-type

JESD204C协议-中英协议(无水印带书签).zip

JESD204C协议中英合集,JESD204C (Revision of JESD204B.01 January 2012) ,无水印带书签及目录,中文版为Deepl企业翻译版,可以和英文版对照学习。密码解压123。 JESD204C协议是集成电路(IC)行业中的一个关键标准,由JEDEC固态技术协会制定,用于高速串行数据传输。这个协议在通信、数字信号处理和半导体领域有着广泛的应用,特别是在高性能ADC(模拟数字转换器)和DAC(数字模拟转换器)之间进行数据交换时。JESD204C是在JESD204B基础上的升级,增加了更多的功能和改进,以适应不断发展的高速系统需求。 JESD204C标准是数字接口标准,用于高速串行数据通信,主要用于模数转换器(ADC)和数模转换器(DAC)之间的数据传输。该标准的推出旨在提供比其前身JESD204B更高的传输速率、更低的延迟以及更好的电源效率。JESD204C的接口设计可以满足现代数据转换器的需求,包括在通信、测试测量、医疗成像和航空航天等应用领域的高性能数据采集系统。
recommend-type

DevArt MyDAC 7.1.6 and dbExpress for MySQL 5.1.3 Full Source.7z

DevArt MyDAC 7.1.6 and dbExpress for MySQL 5.1.3 Full Source.7z
recommend-type

T+13.0到17.0授权测试使用

只提供测试,勿商用,版本13.0到17.0,根据说明操作
recommend-type

SentenceParseNew : Parts Of Speech tagger:将一个句子作为输入并返回每个单词的词性标签-matlab开发

要求 : 1) 函数 checker_first :用户编写2) 函数 checker_rest : 用户编写3) 函数 most_prob : 用户编写4) TrainingDataSPNew 所有这些文件也都可用。 该程序将一个字符串作为用户的输入,并为句子中的每个单词返回词性标记。 它依赖于 TrainingDataSPNew 中的训练数据,每次对句子进行标记时都会更新该数据(在用户确认标记后,以防止错误标记)。 它使用 Bigram 模型,其中根据该单词的训练数据中存在的标签以及输入句子中相关单词之前的单词的标签计算单词最可能的标签。 例如,正如我们所知,名词前面通常是冠词,因此如果给定一个新名词(不在训练数据中),程序会看到它前面的词是冠词,因此将该词标记为名词。 如果有任何疑问、错误或建议,请通过 samyuktaramnath[at]gmail[dot]com 或 hal
recommend-type

无刷电机source PCB schematic.

无刷电机source PCB schematic.无刷电机source PCB schematic.

最新推荐

recommend-type

【scratch2.0少儿编程-游戏原型-动画-项目源码】火柴人激情格斗.zip

资源说明: 1:本资料仅用作交流学习参考,请切勿用于商业用途。更多精品资源请访问 https://blog.csdn.net/ashyyyy/article/details/146464041 2:一套精品实用scratch2.0少儿编程游戏、动画源码资源,无论是入门练手还是项目复用都超实用,省去重复开发时间,让开发少走弯路!
recommend-type

【scratch2.0少儿编程-游戏原型-动画-项目源码】环保种树,人人有责.zip

资源说明: 1:本资料仅用作交流学习参考,请切勿用于商业用途。更多精品资源请访问 https://blog.csdn.net/ashyyyy/article/details/146464041 2:一套精品实用scratch2.0少儿编程游戏、动画源码资源,无论是入门练手还是项目复用都超实用,省去重复开发时间,让开发少走弯路!
recommend-type

sparkling-water-extensions_2.12-3.46.0.6-1-3.2.jar

sparkling-water-extensions_2.12-3.46.0.6-1-3.2.jar
recommend-type

bcmpricingcalculator-jvm-1.4.34.jar

bcmpricingcalculator-jvm-1.4.34.jar
recommend-type

鹅肉第六课阿斯蒂芬估计

俄日局管理科对讲机
recommend-type

Node.js构建的运动咖啡馆RESTful API介绍

标题《sportscafeold:体育咖啡馆》指出了项目名称为“体育咖啡馆”,这个名字暗示了该项目可能是一个结合了运动和休闲主题的咖啡馆相关的网络服务平台。该项目运用了多种技术栈,核心的开发语言为JavaScript,这从标签中可以得到明确的信息。 从描述中可以提取以下知识点: 1. **Node.js**:体育咖啡馆项目使用了Node.js作为服务器端运行环境。Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它能够使得JavaScript应用于服务器端开发。Node.js的事件驱动、非阻塞I/O模型使其适合处理大量并发连接,这对于RESTFUL API的构建尤为重要。 2. **Express Framework**:项目中使用了Express框架来创建RESTFUL API。Express是基于Node.js平台,快速、灵活且极简的Web应用开发框架。它提供了构建Web和移动应用的强大功能,是目前最流行的Node.js Web应用框架之一。RESTFUL API是一组遵循REST原则的应用架构,其设计宗旨是让Web服务通过HTTP协议进行通信,并且可以使用各种语言和技术实现。 3. **Mongoose ORM**:这个项目利用了Mongoose作为操作MongoDB数据库的接口。Mongoose是一个对象文档映射器(ODM),它为Node.js提供了MongoDB数据库的驱动。通过Mongoose可以定义数据模型,进行数据库操作和查询,从而简化了对MongoDB数据库的操作。 4. **Passport.js**:项目中采用了Passport.js库来实现身份验证系统。Passport是一个灵活的Node.js身份验证中间件,它支持多种验证策略,例如用户名和密码、OAuth等。它提供了标准化的方法来为用户登录提供认证,是用户认证功能的常用解决方案。 5. **版权信息**:项目的版权声明表明了Sportscafe 2015是版权所有者,这表明项目或其相关内容最早发布于2015年或之前。这可能表明该API背后有商业实体的支持或授权使用。 从【压缩包子文件的文件名称列表】中我们可以了解到,该文件的版本控制仓库使用的是“master”分支。在Git版本控制系统中,“master”分支通常用于存放当前可部署的稳定版本代码。在“master”分支上进行的更改通常都是经过测试且准备发布到生产环境的。 综上所述,我们可以知道体育咖啡馆项目是一个利用现代JavaScript技术栈搭建的后端服务。它包含了处理HTTP请求的Express框架、连接MongoDB数据库的Mongoose库和实现用户身份验证的Passport.js中间件。该项目可用于构建提供体育信息、咖啡馆菜单信息、预约服务等的Web应用或API服务,这为体育咖啡馆的营销、用户体验和数据管理提供了可能。 考虑到文档资料的提及,该项目的安装和API文档应该包含在项目资料中,可能在项目的README文件或其他说明文档中。对于项目的使用者或者开发者而言,这部分文档非常重要,因为它们可以提供详细的信息和指导,帮助用户快速部署和使用该API。 总结来说,这是一套针对体育咖啡馆相关业务的后端解决方案,它使用了流行的开源技术栈,可以灵活地应用于体育咖啡馆的网络服务中,如信息发布、在线预约、会员管理等。
recommend-type

【LNR优化与用户体验】:一文看透互操作优化如何提升用户感知

# 摘要 LNR(邻区关系优化)是提升移动通信网络性能与用户体验的关键技术。本文系统阐述了LNR优化的基本概念、理论基础与技术实现路径,构建了包括信道质量评估、干扰建模及关键性能指标分析在内的数学模型,并探讨了参数配置、邻区管理及AI与大数据在LNR优化中的应用。通过量化用户感知指标,分析了LNR优化对视频流畅度、页面加载速度及切换性能的实际改善效果,并结合典型场景验证了其优化成效。本文进一步展望了LNR技术在5G及未来网络中的发展趋势与技术挑战。
recommend-type

Java1.8 的编程语言、使用场景、版本号、厂商、是否开源、发行日期、终止日期、可替代产品、推荐产品是什么

以下是关于 **Java 1.8** 的全面信息汇总,涵盖其编程语言特性、使用场景、版本号、厂商、是否开源、发行日期、终止支持日期、可替代产品和推荐产品。 --- ## ✅ Java 1.8 综合信息表 | 项目 | 内容 | |------|------| | **编程语言** | Java | | **版本号** | Java 1.8(也称为 Java 8) | | **厂商** | Oracle、Adoptium、Amazon(Corretto)、Azul(Zulu)、Red Hat、IBM 等 | | **是否开源** | ✅ 是(OpenJDK 1.8 是开源的,Oracle
recommend-type

Java开发的教区牧民支持系统介绍

根据给定文件信息,下面将详细阐述相关知识点: ### 标题知识点 #### catecumenus-java: 教区牧民支持系统 - **Java技术栈应用**:标题提到的“catecumenus-java”表明这是一个使用Java语言开发的系统。Java是目前最流行的编程语言之一,广泛应用于企业级应用、Web开发、移动应用等,尤其是在需要跨平台运行的应用中。Java被设计为具有尽可能少的实现依赖,所以它可以在多种处理器上运行。 - **教区牧民支持系统**:从标题来看,这个系统可能面向的是教会管理或教区管理,用来支持牧民(教会领导者或牧师)的日常管理工作。具体功能可能包括教友信息管理、教区活动安排、宗教教育资料库、财务管理、教堂资源调配等。 ### 描述知识点 #### 儿茶类 - **儿茶素(Catechin)**:描述中提到的“儿茶类”可能与“catecumenus”(新信徒、教徒)有关联,暗示这个系统可能与教会或宗教教育相关。儿茶素是一类天然的多酚类化合物,常见于茶、巧克力等植物中,具有抗氧化、抗炎等多种生物活性,但在系统标题中可能并无直接关联。 - **系统版本号**:“0.0.1”表示这是一个非常初期的版本,意味着该系统可能刚刚开始开发,功能尚不完善。 ### 标签知识点 #### Java - **Java语言特点**:标签中明确提到了“Java”,这暗示了整个系统都是用Java编程语言开发的。Java的特点包括面向对象、跨平台(即一次编写,到处运行)、安全性、多线程处理能力等。系统使用Java进行开发,可能看重了这些特点,尤其是在构建可扩展、稳定的后台服务。 - **Java应用领域**:Java广泛应用于企业级应用开发中,包括Web应用程序、大型系统后台、桌面应用以及移动应用(Android)。所以,此系统可能也会涉及这些技术层面。 ### 压缩包子文件的文件名称列表知识点 #### catecumenus-java-master - **Git项目结构**:文件名称中的“master”表明了这是Git版本控制系统中的一个主分支。在Git中,“master”分支通常被用作项目的主干,是默认的开发分支,所有开发工作都是基于此分支进行的。 - **项目目录结构**:在Git项目中,“catecumenus-java”文件夹应该包含了系统的源代码、资源文件、构建脚本、文档等。文件夹可能包含各种子文件夹和文件,比如src目录存放Java源代码,lib目录存放相关依赖库,以及可能的build.xml文件用于构建过程(如Ant或Maven构建脚本)。 ### 结合以上信息的知识点整合 综合以上信息,我们可以推断“catecumenus-java: 教区牧民支持系统”是一个使用Java语言开发的系统,可能正处于初级开发阶段。这个系统可能是为了支持教会内部管理,提供信息管理、资源调度等功能。其使用Java语言的目的可能是希望利用Java的多线程处理能力、跨平台特性和强大的企业级应用支持能力,以实现一个稳定和可扩展的系统。项目结构遵循了Git版本控制的规范,并且可能采用了模块化的开发方式,各个功能模块的代码和资源文件都有序地组织在不同的子文件夹内。 该系统可能采取敏捷开发模式,随着版本号的增加,系统功能将逐步完善和丰富。由于是面向教会的内部支持系统,对系统的用户界面友好性、安全性和数据保护可能会有较高的要求。此外,考虑到宗教性质的敏感性,系统的开发和使用可能还需要遵守特定的隐私和法律法规。
recommend-type

LNR切换成功率提升秘籍:参数配置到网络策略的全面指南

# 摘要 LNR(LTE to NR)切换技术是5G网络部署中的关键环节,直接影