Dosieranlage/main.c

406 lines
8.5 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 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;
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 = 0x1D4C; // 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));
}
void configProgressBar(void)
{
fuellstandInd.pid = 0;
fuellstandInd.cid = 1;
fuellstandInd.name = "fuellstand";
fuellstandInd.pophandler = NULL;
fuellstandInd.pushhandler = NULL;
fehlerInd.pid = 0;
fehlerInd.cid = 1;
fehlerInd.name = "fehlerInd";
fehlerInd.pophandler = NULL;
fehlerInd.pushhandler = NULL;
leerInd.pid = 0;
leerInd.cid = 1;
leerInd.name = "leerInd";
leerInd.pophandler = NULL;
leerInd.pushhandler = NULL;
feinInd.pid = 0;
feinInd.cid = 1;
feinInd.name = "feinInd";
feinInd.pophandler = NULL;
feinInd.pushhandler = NULL;
grobInd.pid = 0;
grobInd.cid = 1;
grobInd.name = "grobInd";
grobInd.pophandler = NULL;
grobInd.pushhandler = NULL;
pumpeInd.pid = 0;
pumpeInd.cid = 1;
pumpeInd.name = "pumpeInd";
pumpeInd.pophandler = NULL;
pumpeInd.pushhandler = NULL;
}
void configTextFields(void)
{
fuellstandText.pid = 0;
fuellstandText.cid = 1; // Component ID aus Nextion Editor
fuellstandText.name = "fuellstandn"; // Exakter Name!
fuellstandText.pophandler = NULL;
fuellstandText.pushhandler = NULL;
}
void fehler(int8_t state)
{
if(state == 1)
{
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(int8_t state)
{
if(state == 1)
{
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(int8_t state)
{
if(state == 1)
{
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(int8_t state)
{
if(state == 1)
{
NexProgressBar_setValue(&grobInd, 100);
GROB = 1;
//uart2_putString("Grobventil geoeffnet!\r\n");
}
else
{
NexProgressBar_setValue(&grobInd, 0);
GROB = 0;
//uart2_putString("Grobventil geoeffnet!\r\n");
}
return;
}
void pumpe(int8_t state)
{
if(state == 1)
{
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)
{
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) // setzt Füllstand Text über progress bar
{
char buf[20];
sprintf(buf, "%u l", value);
NexText_setText(&fuellstandText, buf);
fuellstand(toPercent(value, 255));
}
int SwitchesToInt(void) // DIL Leiste zu Int
{
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};
configProgressBar();
configTextFields();
Nex_Init(0);
Init_Nex_UI();
fuellstand(0);
fehler(0);
leerBlasen(0);
fein(0);
grob(0);
pumpe(0);
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(1);
if(effektiverWert < SOLLWERT - NACHLAUF)
{
fein(1);
leitungBenutzt = true;
}
else if(effektiverWert >= SOLLWERT - NACHLAUF)
{
fein(0);
}
if(effektiverWert < GAP)
{
grob(1);
leitungBenutzt = true;
}
else if(effektiverWert < SOLLWERT)
{
grob(0);
}
else
{
grob(0);
}
setFuellstand(effektiverWert);
wait_sys_ms(5);
}
else
{
if(leerGeblasen)
{
pumpe(0);
grob(0);
fein(0);
leerBlasen(1);
if(leitungBenutzt)
{
int time = 3000 / NACHLAUF;
uint8_t i = 0;
for(i = 0; i < NACHLAUF; i++)
{
wait_sys_ms(time);
nachlaufOffset += 1;
setFuellstand(istWert + nachlaufOffset);
}
}
else
{
wait_sys_ms(3000);
}
leerBlasen(0);
leerGeblasen = false;
}
}
}
return 0;
}