/*
Titel: S7-1200_1215C_AO-Simulation
Autor: Niklas Menke - www.niklas-menke.de
Erstelldatum: 10.04.2019
Version: 1.1.0
Aktualisierungsdatum: 13.10.2020
*/
#define F_CPU 8000000 // Takt: 8Mhz
// --- Bibliotheken START ---
#include <avr/io.h> // Definition der IO-Pins des Mikrocontrollers
#include <util/delay.h> // Zeitverzoegerungen
// --- Bibliotheken ENDE ---
// --- Definitionen START ---
// Segmente der 7-Segment-Anzeige
static uint8_t segments_A[10] = {0x7A, 0x40, 0x2A, 0x4A, 0x50, 0x5A, 0x7A, 0x48, 0x7A, 0x5A}; // Speichert die Pins von PORTA, welche für die Zahlen 0-9 auf High gesetzt werden müssen
static uint8_t segments_C[10] = {0x10, 0x10, 0x30, 0x30, 0x30, 0x20, 0x20, 0x10, 0x30, 0x30}; // Wie oben für PORTC
static uint8_t digits_B[6] = {0x04, 0, 0x08, 0, 0, 0x02}; // Speichert den Pin von PORTB, welcher für die entsprechende Stelle einer Ziffer auf High gesetzt werden muss
static uint8_t digits_C[6] = {0, 0x04, 0, 0x02, 0x01, 0}; // Wie oben für PORTC
#define DP_A 2 // Pin von PORTA des Dezimalpunkts
// --- Definitionen ENDE ---
// --- analog_input START ---
// Lese die analogen Werte von der SPS ein
int analog_input(const uint8_t pin) {
ADMUX = pin ? 0x44 : 0x45; // Dem ADC den geforderten Analogeingang zuweisen (pin = 0 --> AI0 mit der Adresse 0x45; pin = 1 --> AI1 mit der Adresse 0x44)
ADCSRA |= (1<<ADEN) | (1<<ADSC); // ADC einschalten und Wert einlesen
while (ADCSRA & (1<<ADSC)); // Warten, bis der Wert eingelesen wurde
ADCSRA = 0; // ADC abschalten
return (ADC*0.02+0.05)*10; // Eingelesenen Wert in den Stromwert umrechnen, Runden, eine Nachkommastelle vor das Komma setzen und zurueckgeben
}
// --- analog_input ENDE ---
// --- lcd_print START ---
// Wert auf einer der Anzeigen darstellen
void lcd_print(uint16_t value, uint8_t display) {
if(display > 1) display = 1;
// Schleife für jede Ziffer ausfuehren
for (uint8_t dg = 0; dg < 6; dg+=2)
{
PORTB = 0; // Port B zurücksetzen
// Setze notwendige Pins auf High, um die letzte Ziffer aus value anzuzeigen
PORTA = segments_A[value%10];
PORTC = segments_C[value%10];
value /= 10; // Letzte Ziffer entfernen
// Pin der entsprechenden Stelle der Ziffer einschalten
PORTB = digits_B[dg+display];
PORTC |= digits_C[dg+display];
// Wenn die zweite Ziffer angezeigt wird, dann Dezimalpunkt setzen
if(dg == 2) PORTA |= (1<<DP_A);
_delay_us(25); // Den LEDs Zeit zum Leuchten geben
} // for END
// Alles zuruecksetzen
PORTA = 0;
PORTB = 0;
PORTC = 0;
_delay_us(600); // Warten, um "ueberschreiben" zu verhindern
}
// --- lcd_print ENDE ---
// --- Hauptfunktion START ---
int main(void)
{
// Variablendefinition
uint16_t laup = 0; // Zaehler
uint16_t AI0 = analog_input(0); // Wert von AI0
uint16_t AI1 = analog_input(1); // Wert von AI1
// Pins als Ein- bzw. Ausgaenge definieren
DDRA = 0x7E;
DDRB = 0xE;
DDRC = 0x37;
// Hauptschleife
while (1)
{
lcd_print(AI0, 0); // Wert auf Anzeige 1 schreiben
lcd_print(AI1, 1); // Wert auf Anzeige 2 schreiben
laup++; // Zaehler um 1 hochsetzen
// Wenn der Zaehler groesser als 50 ist, dann den Zaehler zuruecksetzen und die Analogwerte aktualisieren
if (laup > 50)
{
laup = 0;
AI0 = analog_input(0);
AI1 = analog_input(1);
}
}
}
// --- Hauptfunktion ENDE ---