485 lines
10 KiB
C
485 lines
10 KiB
C
#include <stm32f10x.h>
|
|
#include <armv30_std.h>
|
|
#include <Nextion.h>
|
|
//#include "nex_ui.h"
|
|
#include <stdbool.h>
|
|
|
|
|
|
//---------------------Nextion-Objekte------------------------
|
|
|
|
NexEventObj fuellstandInd;
|
|
NexEventObj pumpeInd;
|
|
NexEventObj leerInd;
|
|
NexEventObj feinInd;
|
|
NexEventObj grobInd;
|
|
NexEventObj fehlerInd;
|
|
|
|
NexEventObj fuellstandText;
|
|
|
|
//---------------------Alias-Defines------------------------
|
|
|
|
#define BITBAND_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
|
|
|
|
#define FEHLER *((volatile unsigned long *)(BITBAND_PERI(GPIOC_ODR,1))) // V3
|
|
#define LEERBLASEN *((volatile unsigned long *)(BITBAND_PERI(GPIOC_ODR,2))) // V4
|
|
#define FEIN *((volatile unsigned long *)(BITBAND_PERI(GPIOC_ODR,13))) // V5
|
|
#define GROB *((volatile unsigned long *)(BITBAND_PERI(GPIOB_ODR,7))) // V6
|
|
#define PUMPE *((volatile unsigned long *)(BITBAND_PERI(GPIOB_ODR,6))) // V7
|
|
|
|
#define Switch5 *((volatile unsigned long *)(BITBAND_PERI(GPIOB_IDR,12))) // DIL5
|
|
#define Switch4 *((volatile unsigned long *)(BITBAND_PERI(GPIOB_IDR,15))) // DIL4
|
|
#define Switch6 *((volatile unsigned long *)(BITBAND_PERI(GPIOB_IDR,14))) // DIL6
|
|
#define Switch7 *((volatile unsigned long *)(BITBAND_PERI(GPIOB_IDR,13))) // DIL7
|
|
#define Switch1 *((volatile unsigned long *)(BITBAND_PERI(GPIOC_IDR,10))) // DIL1
|
|
#define Switch0 *((volatile unsigned long *)(BITBAND_PERI(GPIOC_IDR,6))) // DIL0
|
|
#define Switch2 *((volatile unsigned long *)(BITBAND_PERI(GPIOA_IDR,11))) // DIL2
|
|
#define Switch3 *((volatile unsigned long *)(BITBAND_PERI(GPIOA_IDR,12))) // DIL3
|
|
|
|
//---------------------Variablen------------------------
|
|
|
|
#define NEX_PID_MAIN 0
|
|
#define NEX_CID_PROG 1
|
|
|
|
#define SOLLWERT 0x7F // 127d
|
|
#define GAP 0x5F // 95d
|
|
#define NACHLAUF 0x5
|
|
|
|
volatile unsigned long* Switch[8] ={&Switch0, &Switch1, &Switch2, &Switch3, &Switch4, &Switch5, &Switch6, &Switch7};
|
|
int nachlaufOffset = 0;
|
|
|
|
//------------------------------------------------------
|
|
|
|
void SysTick_Handler()
|
|
{
|
|
STD_IncTick();
|
|
}
|
|
|
|
void PortConfig(void)
|
|
{
|
|
RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN; //Takt für Port C aktivieren
|
|
RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN; //Takt für Port B aktivieren
|
|
RCC -> APB2ENR |= RCC_APB2ENR_IOPAEN; //Takt für Port A aktivieren
|
|
|
|
GPIOB -> CRL &= 0x00000000;
|
|
GPIOB -> CRL = 0x22222222;
|
|
GPIOB -> CRH &= 0x00000000;
|
|
GPIOB -> CRH |= 0x88880000;
|
|
|
|
GPIOA -> CRL &= 0x00000000;
|
|
GPIOA -> CRL = 0x22222222;
|
|
GPIOA -> CRH &= 0x00000000;
|
|
GPIOA -> CRH |= 0x00088000;
|
|
|
|
GPIOC -> CRL &= 0x00000000;
|
|
GPIOC -> CRL |= 0x28222222;
|
|
GPIOC -> CRH &= 0x00000000;
|
|
GPIOC -> CRH |= 0x22222822;
|
|
|
|
GPIOA -> ODR &= 0x0000;
|
|
GPIOB -> ODR &= 0x0000;
|
|
GPIOC -> ODR &= 0x0000;
|
|
|
|
GPIOA -> ODR |= 0x1800;
|
|
GPIOB -> ODR |= 0xF000;
|
|
GPIOC -> ODR |= 0x0440;
|
|
}
|
|
|
|
void uart2_init(void)
|
|
{
|
|
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN; // 0x4
|
|
RCC->APB1ENR |= 0x20000; // UART2 Taktversorgung
|
|
|
|
GPIOA->CRL &= 0xFFFFF0FF;
|
|
GPIOA->CRL |= 0xB00;
|
|
|
|
GPIOA->CRL &= 0xFFFF0FFF;
|
|
GPIOA->CRL |= 0x4000;
|
|
|
|
USART2->CR1 &= ~0x1000; // M:--> Start bit, 8 Data bits, n Stop bit
|
|
USART2->CR1 &= ~0x0400; // PCE: 0: Parity control disabled
|
|
USART2->CR2 &= ~0x3000; // STOP: 00: 1 Stop bit afungsbil
|
|
USART2->BRR = 0x0753; // set Baudrate to 9600 Baud (SysClk 72Mhz)
|
|
USART2->CR1 |= 0x0C; // enable Receiver and Transmitter
|
|
USART2->CR1 |= 0x2000; // Set USART Enable Bit
|
|
}
|
|
|
|
void uart2_putChar(char zeichen)
|
|
{
|
|
while(!((USART2->SR & 0x80) == 0x80));
|
|
USART2->DR = zeichen;
|
|
}
|
|
|
|
void uart2_putString(char* string)
|
|
{
|
|
while(*string)
|
|
{
|
|
uart2_putChar(*string++);
|
|
}
|
|
}
|
|
|
|
char uart2_getChar(void)
|
|
{
|
|
while(!(USART2->SR & 0x20));
|
|
return ((char) (USART2->DR & 0xFF));
|
|
}
|
|
|
|
static void NexEventObj_Init(NexEventObj *obj, uint8_t pid, uint8_t cid, const char *name)
|
|
{
|
|
obj->pid = pid;
|
|
obj->cid = cid;
|
|
obj->name = name;
|
|
obj->pophandler = NULL;
|
|
obj->pushhandler = NULL;
|
|
}
|
|
|
|
void configNexObjects(void)
|
|
{
|
|
NexEventObj_Init(&fuellstandInd, NEX_PID_MAIN, NEX_CID_PROG, "fuellstand");
|
|
NexEventObj_Init(&fehlerInd, NEX_PID_MAIN, NEX_CID_PROG, "fehlerInd");
|
|
NexEventObj_Init(&leerInd, NEX_PID_MAIN, NEX_CID_PROG, "leerInd");
|
|
NexEventObj_Init(&feinInd, NEX_PID_MAIN, NEX_CID_PROG, "feinInd");
|
|
NexEventObj_Init(&grobInd, NEX_PID_MAIN, NEX_CID_PROG, "grobInd");
|
|
NexEventObj_Init(&pumpeInd, NEX_PID_MAIN, NEX_CID_PROG, "pumpeInd");
|
|
|
|
NexEventObj_Init(&fuellstandText, NEX_PID_MAIN, NEX_CID_PROG, "fuellstandn");
|
|
}
|
|
|
|
void fehler(bool state)
|
|
{
|
|
static bool lastStateF = true;
|
|
static bool firstCallF = true;
|
|
|
|
if (firstCallF)
|
|
{
|
|
firstCallF = false;
|
|
NexProgressBar_setValue(&fehlerInd, 0);
|
|
return;
|
|
}
|
|
else if (state == lastStateF)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastStateF = state;
|
|
if(state)
|
|
{
|
|
NexProgressBar_setValue(&fehlerInd, 100);
|
|
FEHLER = 1;
|
|
uart2_putString("Fehler aufgetreten!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&fehlerInd, 0);
|
|
FEHLER = 0;
|
|
uart2_putString("Fehler behoben!\r\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void leerBlasen(bool state)
|
|
{
|
|
static bool lastStateB;
|
|
static bool firstCallB = true;
|
|
|
|
if (firstCallB)
|
|
{
|
|
firstCallB = false;
|
|
NexProgressBar_setValue(&leerInd, 0);
|
|
return;
|
|
}
|
|
else if (state == lastStateB)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastStateB = state;
|
|
|
|
if(state)
|
|
{
|
|
NexProgressBar_setValue(&leerInd, 100);
|
|
LEERBLASEN = 1;
|
|
uart2_putString("Leerblasventil geoeffnet!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&leerInd, 0);
|
|
LEERBLASEN = 0;
|
|
uart2_putString("Leerblasventil geschlossen!\r\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void fein(bool state)
|
|
{
|
|
static bool lastStateFein;
|
|
static bool firstCallFein = true;
|
|
|
|
if (firstCallFein)
|
|
{
|
|
firstCallFein = false;
|
|
NexProgressBar_setValue(&feinInd, 0);
|
|
return;
|
|
}
|
|
else if (state == lastStateFein)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastStateFein = state;
|
|
if(state)
|
|
{
|
|
NexProgressBar_setValue(&feinInd, 100);
|
|
FEIN = 1;
|
|
uart2_putString("Feinventil geoeffnet!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&feinInd, 0);
|
|
FEIN = 0;
|
|
uart2_putString("Feinventil geschlossen!\r\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void grob(bool state)
|
|
{
|
|
static bool lastStateGrob;
|
|
static bool firstCallGrob = true;
|
|
|
|
if (firstCallGrob)
|
|
{
|
|
firstCallGrob = false;
|
|
NexProgressBar_setValue(&grobInd, 0);
|
|
return;
|
|
}
|
|
else if (state == lastStateGrob)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastStateGrob = state;
|
|
|
|
if(state)
|
|
{
|
|
NexProgressBar_setValue(&grobInd, 100);
|
|
GROB = 1;
|
|
uart2_putString("Grobventil geoeffnet!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&grobInd, 0);
|
|
GROB = 0;
|
|
uart2_putString("Grobventil geschlossen!\r\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void pumpe(bool state)
|
|
{
|
|
static bool lastState;
|
|
static bool firstCall = true;
|
|
|
|
if (firstCall)
|
|
{
|
|
firstCall = false;
|
|
NexProgressBar_setValue(&pumpeInd, 0);
|
|
return;
|
|
}
|
|
else if (state == lastState)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastState = state;
|
|
|
|
if(state)
|
|
{
|
|
NexProgressBar_setValue(&pumpeInd, 100);
|
|
PUMPE = 1;
|
|
//uart2_putString("Pumpe eingeschaltet!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&pumpeInd, 0);
|
|
PUMPE = 0;
|
|
uart2_putString("Pumpe ausgeschaltet!\r\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void fuellstand(int8_t value)
|
|
{
|
|
static bool firstCall = true;
|
|
static int8_t lastValue = -1; // ungültiger Startwert
|
|
if(firstCall)
|
|
{
|
|
firstCall = false;
|
|
NexProgressBar_setValue(&fuellstandInd, 0);
|
|
return;
|
|
}
|
|
else if (value == lastValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastValue = value;
|
|
if(value >= 0 && value <= 100)
|
|
{
|
|
NexProgressBar_setValue(&fuellstandInd, value);
|
|
uart2_putString("Fuellstand geaendert!\r\n");
|
|
}
|
|
else
|
|
{
|
|
NexProgressBar_setValue(&fuellstandInd, 0);
|
|
uart2_putString("Uengueltiger Fuellstandswert!\r\n");
|
|
}
|
|
}
|
|
|
|
uint8_t toPercent(uint8_t value, uint8_t max)
|
|
{
|
|
if (value > max) value = max;
|
|
return (value * 100 + max / 2) / max;
|
|
}
|
|
|
|
void setFuellstand(uint8_t value)
|
|
{
|
|
char buf[20];
|
|
|
|
sprintf(buf, "%u l", value);
|
|
|
|
NexText_setText(&fuellstandText, buf);
|
|
fuellstand(toPercent(value, 255));
|
|
}
|
|
|
|
int SwitchesToInt(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t i = 0;
|
|
|
|
for (i = 0; i < 7; i++)
|
|
{
|
|
if (!*Switch[i])
|
|
{
|
|
result |= (1 << i);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
PortConfig();
|
|
uart2_init();
|
|
|
|
NexEventObj *nextlisten_list[] = {NULL};
|
|
configNexObjects();
|
|
Nex_Init(0);
|
|
Init_Nex_UI();
|
|
|
|
fuellstand(0);
|
|
fehler(false);
|
|
leerBlasen(false);
|
|
fein(false);
|
|
grob(false);
|
|
pumpe(false);
|
|
wait_sys_ms(20);
|
|
|
|
bool leerGeblasen = false;
|
|
bool leitungBenutzt = false;
|
|
|
|
uart2_putString("Dosieranlage V01\r\n");
|
|
|
|
while(1)
|
|
{
|
|
Nex_Event_Loop(nextlisten_list);
|
|
wait_sys_ms(5);
|
|
uint8_t istWert = SwitchesToInt();
|
|
uint16_t effektiverWert = istWert + nachlaufOffset;
|
|
|
|
if(*Switch[7] == 0)
|
|
{
|
|
leerGeblasen = true;
|
|
leitungBenutzt = false;
|
|
|
|
pumpe(true);
|
|
|
|
if(effektiverWert < SOLLWERT - NACHLAUF)
|
|
{
|
|
fein(true);
|
|
leitungBenutzt = true;
|
|
}
|
|
else if(effektiverWert >= SOLLWERT - NACHLAUF)
|
|
{
|
|
fein(false);
|
|
}
|
|
|
|
if(effektiverWert < GAP)
|
|
{
|
|
grob(true);
|
|
leitungBenutzt = true;
|
|
}
|
|
else if(effektiverWert < SOLLWERT)
|
|
{
|
|
grob(false);
|
|
}
|
|
else
|
|
{
|
|
grob(false);
|
|
}
|
|
|
|
setFuellstand(effektiverWert);
|
|
wait_sys_ms(5);
|
|
}
|
|
else
|
|
{
|
|
if(leerGeblasen)
|
|
{
|
|
pumpe(false);
|
|
grob(false);
|
|
fein(false);
|
|
leerBlasen(true);
|
|
|
|
if(leitungBenutzt)
|
|
{
|
|
int time = 3000 / NACHLAUF;
|
|
int rest = 3000 % NACHLAUF;
|
|
|
|
fein(true);
|
|
grob(true);
|
|
|
|
uint8_t i = 0;
|
|
for(i = 0; i < NACHLAUF; i++)
|
|
{
|
|
wait_sys_ms(time);
|
|
|
|
if(rest > 0)
|
|
{
|
|
wait_sys_ms(1);
|
|
rest -= 1;
|
|
}
|
|
|
|
nachlaufOffset += 1;
|
|
setFuellstand(istWert + nachlaufOffset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wait_sys_ms(3000);
|
|
}
|
|
|
|
fein(false);
|
|
grob(false);
|
|
leerBlasen(false);
|
|
leerGeblasen = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|