You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
4.7 KiB
C

6 years ago
/*
* geigerzaehler.c
6 years ago
*
6 years ago
* Created : 28.02.2019 09:07:22
* Author : John Ditgens, Alexander Brandscheidt
* Git-Repository : https://gitea.Railduction.eu/JohnD/Geigerzaehler.git
*
* MController : AtMega328P
* Board : Arduino Nano
6 years ago
*/
#define F_CPU 16000000UL // Clock speed: 16 MHz - Speed from onboard oscillator
6 years ago
6 years ago
// Imports
6 years ago
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
// Global variable declaration
uint16_t boost_frequency = 2000; // 2kHz frequency
uint16_t signalOutput_time = 200; // 200ms
6 years ago
uint8_t boost_highVoltage_nextHigh = 1;
uint16_t boost_highVoltage_nextTick = 1;
6 years ago
uint8_t signalOutput_nextHigh = 1;
uint16_t signalOutput_nextTick = 0;
6 years ago
uint8_t timer1_prescaler = 1;
uint16_t test = 0;
int main()
6 years ago
{
// Inputs
DDRD &= (0 << PORTD2); // Activate input PD2
DDRD &= (0 << PORTD3); // Activate input PD3
//PORTD |= (1 << PORTD2); // Enable pull-up-resistor D2
//PORTD |= (1 << PORTD3); // Enable pull-up-resistor D3
// Todo [CRITICAL]: External pull-down resistors 10kOhm
// Outputs
DDRD |= (1 << PORTD4);
DDRD |= (1 << PORTD5);
DDRD |= (1 << PORTD6);
DDRB |= (1 << PORTB5); // Onboard-Led
6 years ago
// Interrupt for INT0 Pin-D2 High-voltage check
EICRA |= (0 << ISC01)|(1 << ISC00); // On at any edge [Code: 01]
6 years ago
EIMSK |= (1 << INT0); // Activate Interrupt INT0
6 years ago
// Interrupt for INT1 Pin-D3 Counter-click
EICRA |= (1 << ISC11)|(1 << ISC10); // On rising edge [Code: 11]
6 years ago
EIMSK |= (1 <<INT1); // Activate Interrupt INT1
6 years ago
// Init timer1
timer1_init();
6 years ago
sei(); // Activate global interrupts
6 years ago
6 years ago
// Endless loop
6 years ago
while (1)
{
/*
* HighVoltage boosting
*/
if(boost_highVoltage_nextTick > 0 && (uint16_t)TCNT1 >= boost_highVoltage_nextTick) // If we are on or after the tick it should be executed
6 years ago
{
// Set pin according to next exec
if(boost_highVoltage_nextHigh == 1)
6 years ago
{
// Set it high
PORTD |= (1 << PORTD4);
boost_highVoltage_nextHigh = 0; // Next is low
6 years ago
}
else
6 years ago
{
// Set it low
PORTD |= (0 << PORTD4);
boost_highVoltage_nextHigh = 1; // Next is high
6 years ago
}
// Calculate when next high/low should be set
boost_highVoltage_nextTick = (uint16_t)TCNT1 + F_CPU/timer1_prescaler * 1/(boost_frequency/2); // Half of time it should be high/low
if(boost_highVoltage_nextTick == 0) boost_highVoltage_nextTick++; // If its 0, it stops, we dont want that
6 years ago
}
/*
* Signal output
*/
if(signalOutput_nextTick > 0 && (uint16_t)TCNT1 >= signalOutput_nextTick) // If we are on or after the tick it should be executed
6 years ago
{
// Set pin according to next exec
if(signalOutput_nextHigh == 1) // Set it high
6 years ago
{
PORTD |= (1 << PORTD5);
PORTD |= (1 << PORTD6);
signalOutput_nextHigh = 0; // Next is low
// When the signal should stop
signalOutput_nextTick = (uint16_t)TCNT1 + F_CPU/timer1_prescaler * signalOutput_time/1000; // nextTick is in signalOutput_time in ms
if(signalOutput_nextTick == 0) signalOutput_nextTick++; // If its 0, it stops, we dont want that
}
else // Set it low
{
PORTD |= (0 << PORTD5);
PORTD |= (0 << PORTD6);
signalOutput_nextHigh = 1; // Next is high
6 years ago
signalOutput_nextTick = 0; // Disable signalOutput
6 years ago
}
}
6 years ago
}
}
/*
* Init timer1 (16-bit) in "normal mode"
*/
void timer1_init()
{
// set up timer with speed: cpu-clock / prescaler
switch(timer1_prescaler){ // [CS12 CS11 CS10]
default:
case 1:
TCCR1B |= (1 << CS10); // [0 0 1 ]
break;
case 8:
TCCR1B |= (1 << CS11); // [0 1 0 ]
break;
case 64:
TCCR1B |= (1 << CS10); // [0 1 1 ]
TCCR1B |= (1 << CS11);
break;
case 256:
TCCR1B |= (1 << CS12); // [1 0 0 ]
break;
case 1024:
TCCR1B |= (1 << CS10); // [1 0 1 ]
TCCR1B |= (1 << CS12);
break;
}
// initialize counter
TCNT1 = (uint16_t)0;
}
/*
* Interrupt-handler
* ISR - Interrupt service routine
*/
// Address: 0x001 INT0 - On any edge [Code: 01]
// Handles: Over/Below working voltage
ISR(INT0_vect)
6 years ago
{
if(!(PIND & (1 << PORTD2))) // Falling edge
6 years ago
{
// Below ~400V, activate booster
boost_highVoltage_nextTick = 1; // Run as soon as possible
PORTB |= (1 << PORTB5); // Onboard-Led
6 years ago
}
else // Rising edge
{
// Reached ~400V, deactivate booster
boost_highVoltage_nextTick = 0;
PORTB |= (0 << PORTB5); // Onboard-Led
// reset state
PORTD |= (0 << PORTD4); // pin on low
boost_highVoltage_nextHigh = 1; // next is high
6 years ago
}
reti(); // Exit interrupt-handler
6 years ago
}
// Address: 0x002 INT1 - On rising edge [Code: 11]
// Handles: Counter tube "tick"
6 years ago
ISR(INT1_vect)
{
6 years ago
// Tick detected, signalOutput
signalOutput_nextTick = 1; // Run as soon as possible
reti(); // Exit interrupt-handler
6 years ago
}