add flowsensor & something more

This commit is contained in:
eddyem 2018-12-29 21:03:26 +03:00
parent 7a470da982
commit 6409272876
8 changed files with 213 additions and 69 deletions

View File

@ -9,13 +9,24 @@ Protocol: [ command line ]
All messages are asynchroneous!
Commands:
d - (only when EBUG defined) go into debug commands
R - reset MCU
Ax - turn on(x=1)/off(x=0) external alarm or check its value
Cx - set cooler PWM to x
d - (only when EBUG defined) go into debug commands
F - get flow sensor rate for 5s period
Hx - set heater PWM to x
L - check water level sensor value
Px - set pump PWM to x
R - reset MCU
Tx - get NTC temperature for channel x
t - get MCU temperature
V - get Vdd value *100V
Debugging commands:
w - test watchdog
A - show raw ADC value (next letter is index, 0..5)
F - get flow_cntr value & PB state
T - show raw T values
w - test watchdog
Messages:
MCUTEMP10=x - mcu temperature * 10 (degrC)

View File

@ -40,7 +40,6 @@ static inline void iwdg_setup(){
IWDG->KR = IWDG_REFRESH; /* (6) */
}
static inline void adc_setup(){
uint16_t ctr = 0; // 0xfff0 - more than 1.3ms
// Enable clocking
@ -106,6 +105,7 @@ static inline void adc_setup(){
* PF0 - floating input - water level alert
* PF1 - push-pull - external alarm
* PA0..PA3 - ADC_IN0..3
* PA4, PA6, PA7 - PWM outputs
* Registers
* MODER - input/output/alternate/analog (2 bit)
* OTYPER - 0 pushpull, 1 opendrain
@ -119,20 +119,70 @@ static inline void adc_setup(){
*/
static inline void gpio_setup(){
// Enable clocks to the GPIO subsystems
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOFEN;
GPIOA->MODER = GPIO_MODER_MODER13_O | GPIO_MODER_MODER14_O |
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOFEN;
GPIOA->MODER =
GPIO_MODER_MODER13_O | GPIO_MODER_MODER14_O |
GPIO_MODER_MODER4_AF | GPIO_MODER_MODER6_AF |
GPIO_MODER_MODER7_AF |
GPIO_MODER_MODER0_AI | GPIO_MODER_MODER1_AI |
GPIO_MODER_MODER2_AI | GPIO_MODER_MODER3_AI;
GPIOA->OTYPER = 3 << 13; // both opendrain
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable syscfg clock for EXTI
GPIOA->OTYPER = 3 << 13; // 13/14 opendrain
GPIOF->MODER = GPIO_MODER_MODER1_O;
// PB1 - interrupt input
/* (2) Select Port B for pin 1 external interrupt by writing 0001 in EXTI1*/
/* (3) Configure the corresponding mask bit in the EXTI_IMR register */
/* (4) Configure the Trigger Selection bits of the Interrupt line on rising edge*/
/* (5) Configure the Trigger Selection bits of the Interrupt line on falling edge*/
SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI1_PB; /* (2) */
EXTI->IMR = EXTI_IMR_MR1; /* (3) */
//EXTI->RTSR = 0x0000; /* (4) */
EXTI->FTSR = EXTI_FTSR_TR1; /* (5) */
/* (6) Enable Interrupt on EXTI0_1 */
/* (7) Set priority for EXTI0_1 */
NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
NVIC_SetPriority(EXTI0_1_IRQn, 3); /* (7) */
// alternate functions:
// PA4 - TIM14_CH1 (AF4)
// PA6 - TIM16_CH1 (AF5), PA7 - TIM17_CH1 (AF5)
GPIOA->AFR[0] = (GPIOA->AFR[0] &~ (GPIO_AFRL_AFRL4 | GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)) \
| (4 << (4 * 4)) | (5 << (6 * 4)) | (5 << (7 * 4));
}
static inline void timers_setup(){
;
// timer 14 ch1 - cooler PWM
// timer 16 ch1 - heater PWM
// timer 17 ch1 - pump PWM
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM14EN; // enable clocking for timers 3 and 14
RCC->APB2ENR |= RCC_APB2ENR_TIM16EN | RCC_APB2ENR_TIM17EN; // & timers 16/17
// PWM mode 1 (active -> inactive)
TIM14->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
TIM16->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
TIM17->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
// frequency
TIM14->PSC = 59; // 0.8MHz for 3kHz PWM
TIM16->PSC = 18749; // 2.56kHz for 10Hz PWM
TIM17->PSC = 5; // 8MHz for 31kHz PWM
// ARR for 8-bit PWM
TIM14->ARR = 254;
TIM16->ARR = 254;
TIM17->ARR = 254;
// start in OFF state
// TIM14->CCR1 = 0; and so on
// enable main output
TIM14->BDTR |= TIM_BDTR_MOE;
TIM16->BDTR |= TIM_BDTR_MOE;
TIM17->BDTR |= TIM_BDTR_MOE;
// enable PWM output
TIM14->CCER = TIM_CCER_CC1E;
TIM16->CCER = TIM_CCER_CC1E;
TIM17->CCER = TIM_CCER_CC1E;
// enable timers
TIM14->CR1 |= TIM_CR1_CEN;
TIM16->CR1 |= TIM_CR1_CEN;
TIM17->CR1 |= TIM_CR1_CEN;
}
void hw_setup(){
sysreset();
gpio_setup();
@ -141,3 +191,13 @@ void hw_setup(){
USART1_config();
iwdg_setup();
}
/*
* Flow sensor counter
*/
void exti0_1_isr(){
if (EXTI->PR & EXTI_PR_PR1){
EXTI->PR |= EXTI_PR_PR1; /* Clear the pending bit */
++flow_cntr;
}
}

View File

@ -20,6 +20,12 @@
#define HARDWARE_H
#include "stm32f0.h"
// measure flow sensor data each 5 seconds
#define FLOW_RATE_MS 4999
extern uint16_t flow_rate, flow_cntr;
extern volatile uint32_t Tms;
void hw_setup(void);
#endif // HARDWARE_H

View File

@ -1,4 +1,4 @@
update=Сб 17 ноя 2018 18:50:24
update=Чт 20 дек 2018 22:32:48
version=1
last_client=kicad
[pcbnew]
@ -25,43 +25,6 @@ version=1
NetIExt=net
[general]
version=1
[eeschema]
version=1
LibDir=
[eeschema/libraries]
LibName1=power
LibName2=device
LibName3=switches
LibName4=relays
LibName5=motors
LibName6=transistors
LibName7=conn
LibName8=linear
LibName9=regul
LibName10=74xx
LibName11=cmos4000
LibName12=adc-dac
LibName13=memory
LibName14=xilinx
LibName15=microcontrollers
LibName16=dsp
LibName17=microchip
LibName18=analog_switches
LibName19=motorola
LibName20=texas
LibName21=intel
LibName22=audio
LibName23=interface
LibName24=digital-audio
LibName25=philips
LibName26=display
LibName27=cypress
LibName28=siliconi
LibName29=opto
LibName30=atmel
LibName31=contrib
LibName32=valves
LibName33=stm32
[schematic_editor]
version=1
PageLayoutDescrFile=
@ -72,3 +35,6 @@ NetFmtName=Pcbnew
SpiceForceRefPrefix=0
SpiceUseNetNumbers=0
LabSize=60
[eeschema]
version=1
LibDir=

View File

@ -26,6 +26,8 @@
#include "protocol.h"
volatile uint32_t Tms = 0;
uint16_t flow_rate = 0; // flow sensor rate
uint16_t flow_cntr = 0; // flow sensor trigger counter
// Called when systick fires
void sys_tick_handler(void){
@ -33,7 +35,7 @@ void sys_tick_handler(void){
}
int main(void){
// uint32_t lastT = 0;
uint32_t lastTflow = 0;
char *txt;
hw_setup();
SysTick_Config(6000, 1);
@ -47,9 +49,11 @@ int main(void){
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
while (1){
IWDG->KR = IWDG_REFRESH;
/*if(lastT > Tms || Tms - lastT > 499){
lastT = Tms;
}*/
if(Tms - lastTflow > FLOW_RATE_MS){ // onse per one second check flow sensor counter
lastTflow = Tms;
flow_rate = flow_cntr;
flow_cntr = 0;
}
if(usart1_getline(&txt)){ // usart1 received command, process it
txt = process_command(txt);
}else txt = NULL;

View File

@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hardware.h"
#include "protocol.h"
#include "usart.h"
#include "adc.h"
@ -40,6 +41,14 @@ static void debugging_proc(const char *command){
}
put_string("ADC value: ");
put_uint(getADCval(i));
put_string(", ");
usart1_sendbuf();
break;
case 'F':
put_string("PB_IDR, flow_cntr: ");
put_uint(GPIOB->IDR);
put_string(", ");
put_uint(flow_cntr);
usart1_sendbuf();
break;
case 'T': // all raw T values
@ -70,7 +79,8 @@ static void get_ntc(const char *str){
}
#define SEND(x) usart1_send_blocking(x, 0)
#define STR(a) XSTR(a)
#define XSTR(a) #a
/**
* @brief process_command - command parser
* @param command - command text (all inside [] without spaces)
@ -79,16 +89,66 @@ static void get_ntc(const char *str){
char *process_command(const char *command){
const char *ptr = command;
char *ret = NULL;
int32_t N;
usart1_sendbuf(); // send buffer (if it is already filled)
switch(*ptr++){
case '?': // help
SEND("R - reset\nTx - get NTC temp\nt - get MCU temp\nV - get Vdd");
SEND(
"Ax - alarm on(1)/off(0)\n"
"Cx - cooler PWM\n"
"F - get flow sensor rate for " STR(FLOW_RATE_MS) "ms\n"
"Hx - heater PWM\n"
"L - check water level\n"
"Px - pump PWM\n"
"R - reset\n"
"Tx - get NTC temp\n"
"t - get MCU temp\n"
"V - get Vdd"
);
#ifdef EBUG
SEND("d -> goto debug:");
SEND("\tw - test watchdog\n\tAx - get raw ADCx value");
SEND("\tT - show raw T values");
SEND("d -> goto debug:\n"
"\tAx - get raw ADCx value\n"
"\tF - get flow_cntr\n"
"\tT - show raw T values\n"
"\tw - test watchdog"
);
#endif
break;
case 'A': // turn alarm on/off
if(*ptr == '1') pin_set(GPIOF, 2);
else if(*ptr == '0')pin_clear(GPIOF, 2);
put_string("ALRM=");
put_char(pin_read(GPIOF, 2) + '0');
break;
case 'C': // cooler PWM - TIM14CH1
if(getnum(ptr, &N) && N > -1 && N < 256){
TIM14->CCR1 = N;
}
put_string("COOLERPWM=");
put_int(TIM14->CCR1);
break;
case 'F':
put_string("FLOWRATE=");
put_uint(flow_rate);
break;
case 'H': // heater PWM - TIM16CH1
if(getnum(ptr, &N) && N > -1 && N < 256){
TIM16->CCR1 = N;
}
put_string("HEATERPWM=");
put_int(TIM16->CCR1);
break;
case 'L': // water level
put_string("WATERLEVEL=");
put_char('0' + pin_read(GPIOF, 1));
break;
case 'P': // pump PWM - TIM17CH1
if(getnum(ptr, &N) && N > -1 && N < 256){
TIM17->CCR1 = N;
}
put_string("PUMPPWM=");
put_int(TIM17->CCR1);
break;
case 'R': // reset MCU
NVIC_SystemReset();
break;

View File

@ -34,10 +34,10 @@ static uint8_t linerdy = 0 // received data ready
;
static int rbufno = 0; // current rbuf number
static char rbuf[2][UARTBUFSZ], tbuf[UARTBUFSZ]; // receive & transmit buffers
static char rbuf[2][UARTBUFSZ+1], tbuf[UARTBUFSZ]; // receive & transmit buffers
static char *recvdata = NULL;
static char trbuf[UARTBUFSZ]; // auxiliary buffer for data transmission
static char trbuf[UARTBUFSZ+1]; // auxiliary buffer for data transmission
static int trbufidx = 0;
int put_char(char c){
@ -161,18 +161,19 @@ void usart1_isr(){
}
}
switch(rb){
case '[':
datalen[rbufno] = 0;
tmout = 0;
break;
case '[':
datalen[rbufno] = 0;
tmout = 0;
break;
case ']': // close command - line ready!
dlen = datalen[rbufno];
if(dlen){
linerdy = 1;
incmd = 0;
recvdata = rbuf[rbufno];
rbufno = !rbufno;
datalen[rbufno] = 0;
linerdy = 1;
incmd = 0;
recvdata = rbuf[rbufno];
rbuf[rbufno][dlen] = 0;
rbufno = !rbufno;
datalen[rbufno] = 0;
}
tmout = 0;
break;
@ -257,3 +258,38 @@ TXstatus usart1_send_blocking(const char *str, int len){
txrdy = 1;
return ALL_OK;
}
// read `buf` and get first integer `N` in it
// @return pointer to first non-number if all OK or NULL if first symbol isn't a space or number
char *getnum(const char *buf, int32_t *N){
char c;
int positive = -1;
int32_t val = 0;
//usart1_send_blocking(buf, 0);
while((c = *buf++)){
if(c == '\t' || c == ' '){
if(positive < 0) continue; // beginning spaces
else break; // spaces after number
}
if(c == '-'){
if(positive < 0){
positive = 0;
continue;
}else break; // there already was `-` or number
}
if(c < '0' || c > '9') break;
if(positive < 0) positive = 1;
val = val * 10 + (int32_t)(c - '0');
}
if(positive != -1){
if(positive == 0){
if(val == 0) return NULL; // single '-'
val = -val;
}
*N = val;
}else return NULL;
/* usart1_sendbuf();
put_uint(val);
put_char('\n');*/
return (char*)buf-1;
}

View File

@ -50,5 +50,6 @@ int put_string(const char *str);
int put_int(int32_t N);
int put_uint(uint32_t N);
char *getnum(const char *buf, int32_t *N);
#endif // __USART_H__