diff --git a/main.c b/main.c index b118b4a..981b44c 100644 --- a/main.c +++ b/main.c @@ -38,6 +38,7 @@ #include // debug utilities #include // flash utilities #include // timer utilities +#include // backup utilities /* own libraries */ #include "global.h" // board definitions @@ -75,7 +76,6 @@ volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ti #define DDM100TC_PORT B /**< timer ipnut capture port (TIM4_CH1=PB6) **/ #define DDM100TC_CAPTURE TIM4_CH1 /**< time input capture used to detect pulse **/ volatile uint32_t ddm100tc_interval = 0; /**< last time interval between pulses **/ -volatile uint32_t ddm100tc_pulses = 0; /**< total number of pulses captured **/ /** @} */ int _write(int file, char *ptr, int len) @@ -289,8 +289,11 @@ void main(void) printf("uptime: %02lu:%02lu:%02lu\n", ticks_time/(60*60), (ticks_time%(60*60))/60, (ticks_time%60)); // display time // setup DDM100TC electricity meter + printf("setup DDM100TC electricity meter: "); + rcc_periph_clock_enable(RCC_PWR); // enable clock for the power domain + rcc_periph_clock_enable(RCC_BKP); // enable clock for the backup domain to access backups register, where the number of pulses is stored rcc_periph_clock_enable(RCC_GPIO(DDM100TC_PORT)); // enable clock for GPIO block - gpio_set_mode(GPIO_BANK_(DDM100TC_CAPTURE), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_(DDM100TC_CAPTURE)); // setup GPIO pin as input + gpio_set_mode(GPIO_BANK_(DDM100TC_CAPTURE), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_(DDM100TC_CAPTURE)); // setup GPIO pin as input gpio_clear(GPIO_BANK_(DDM100TC_CAPTURE), GPIO_(DDM100TC_CAPTURE)); // pull down since the meter will set VCC when pulsing rcc_periph_clock_enable(RCC_AFIO); // enable pin alternate function (timer capture) rcc_periph_clock_enable(RCC_TIM(DDM100TC_TIMER)); // enable clock for timer block @@ -314,6 +317,7 @@ void main(void) timer_ic_enable(TIM(DDM100TC_TIMER), TIM_IC1); // enable capture timer_set_counter(TIM(DDM100TC_TIMER), 0); // reset timer counter timer_enable_counter(TIM(DDM100TC_TIMER)); // enable timer + printf("OK\n"); // setup PZEM electricity meter printf("setup PZEM-004 electricity meter: "); @@ -540,13 +544,12 @@ void main(void) sensor_sdm120_measurement_request(1+sdm120_meter, sdm120_measurement); // request first measurement // calculate and show DDM100TC measurements (base on number of pulses and interval) - if (ddm100tc_pulses==0) { // no measurements received yet - ddm100tc_value_energy = 0; - ddm100tc_value_power = 0; + ddm100tc_value_energy = (uint32_t)((((BKP_DR1<<16)+BKP_DR2)*(uint64_t)1000)/1600); // the meter has 1600 impulses/kWh (use 64-bit calculation to not overflow after 2684354 Wh) + if (ddm100tc_interval==0) { // no measurements received yet + ddm100tc_value_power = 0; } else { - ddm100tc_value_energy = (uint32_t)((ddm100tc_pulses*(uint64_t)1000)/1600); // the meter has 1600 impulses/kWh (use 64-bit calculation to not overflow after 2684354 Wh) ddm100tc_value_power = (uint32_t)(((rcc_ahb_frequency*(double)1.0)/((uint32_t)TIM_PSC(TIM(DDM100TC_TIMER))+1))*(3600*1000/1600)/ddm100tc_interval); // calculate with floating point for precision - } + } printf("DDM100TC meter energy: %lu Wh\n", ddm100tc_value_energy); printf("DDM100TC meter power: %lu W\n", ddm100tc_value_power); } @@ -702,8 +705,13 @@ void TIM_ISR(DDM100TC_TIMER)(void) } else if (timer_get_flag(TIM(DDM100TC_TIMER), TIM_SR_CC1IF)) { // pulse detected long_time += TIM_CCR1(TIM(DDM100TC_TIMER)); // get time (reading also clears the flag) if (long_time>90) { // pulse is 90ms long, thus a new pulse before this time is probably just noise) - ddm100tc_interval = long_time; - ddm100tc_pulses++; // increment the number of pulses detected + ddm100tc_interval = long_time; // save new time + pwr_disable_backup_domain_write_protect(); // enable backup register write + BKP_DR2++; // increment number of pulses detected + if (BKP_DR2==0) { // 16-bit register overflow + BKP_DR1++; // same 16-bit bit is second register + } + pwr_enable_backup_domain_write_protect(); // protect backup register from write long_time = 0; // reset time (slave mode should also have reset the counter) } }