store DDM100TC pulse count in backups registers

This commit is contained in:
King Kévin 2017-01-20 15:54:52 +01:00
parent d3ed57fd0d
commit 0c2d13bbe5
1 changed files with 17 additions and 9 deletions

26
main.c
View File

@ -38,6 +38,7 @@
#include <libopencm3/stm32/dbgmcu.h> // debug utilities
#include <libopencm3/stm32/flash.h> // flash utilities
#include <libopencm3/stm32/timer.h> // timer utilities
#include <libopencm3/stm32/f1/bkp.h> // 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)
}
}