Compare commits
10 Commits
8a4bac8ee6
...
2f7f4906bc
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f7f4906bc | |||
| cc46c0696b | |||
| 73c78133ac | |||
| 74a3ace504 | |||
| 3261e399ba | |||
| 943a92869f | |||
| ee136cc840 | |||
| 548cee71f4 | |||
| fd658face8 | |||
| 67f4677053 |
@@ -37,4 +37,6 @@ target_sources(${PROJECT_NAME} PRIVATE
|
|||||||
src/main.c
|
src/main.c
|
||||||
src/input_handler.c
|
src/input_handler.c
|
||||||
src/timer_counter.c
|
src/timer_counter.c
|
||||||
|
src/adc_probe_ext.c
|
||||||
|
src/led_pwm.c
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
set(CMAKE_SYSTEM_NAME Generic)
|
set(CMAKE_SYSTEM_NAME Generic)
|
||||||
set(CMAKE_SYSTEM_PROCESSOR avr)
|
set(CMAKE_SYSTEM_PROCESSOR avr)
|
||||||
|
|
||||||
set(AVR_MCU "ATtiny24")
|
set(AVR_MCU "attiny24")
|
||||||
set(AVR_PROGRAMMER "usbasp")
|
set(AVR_PROGRAMMER "usbasp")
|
||||||
|
|
||||||
# compiler and linker settings
|
# compiler and linker settings
|
||||||
|
|||||||
39
src/adc_probe_ext.c
Normal file
39
src/adc_probe_ext.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include "adc_probe_ext.h"
|
||||||
|
|
||||||
|
void adc_init(void)
|
||||||
|
{
|
||||||
|
// Vcc as reference, select ADC2 (MUX = 0b010)
|
||||||
|
ADMUX = (0 << REFS1) | (0 << REFS0) | // VCC as reference
|
||||||
|
(0 << ADLAR) | // Right adjust result
|
||||||
|
(0b010); // ADC2
|
||||||
|
|
||||||
|
// Enable ADC, prescaler = 64 (assuming 8 MHz → ADC freq = 125 kHz)
|
||||||
|
ADCSRA = (1 << ADEN) | // Enable ADC
|
||||||
|
(1 << ADPS2) | (1 << ADPS1); // Prescaler = 64
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t adc_read(uint8_t channel)
|
||||||
|
{
|
||||||
|
// Set channel (0–7), keeping the other bits in ADMUX
|
||||||
|
ADMUX = (ADMUX & 0xF8) | (channel & 0x07);
|
||||||
|
|
||||||
|
ADCSRA |= (1 << ADSC); // Start conversion
|
||||||
|
while (ADCSRA & (1 << ADSC))
|
||||||
|
; // Wait for conversion to finish
|
||||||
|
|
||||||
|
return ADC; // Return 10-bit result
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t is_device_connected(void)
|
||||||
|
{
|
||||||
|
uint16_t value = adc_read(2); // ADC2 = PA2
|
||||||
|
|
||||||
|
// Zakładamy 5V Vcc → 2.5V = około 512
|
||||||
|
if (value > 400 && value < 600)
|
||||||
|
{
|
||||||
|
return 1; // Podłączone (w granicach tolerancji)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Odłączone (napięcie bliskie 0 lub 5V)
|
||||||
|
}
|
||||||
5
src/adc_probe_ext.h
Normal file
5
src/adc_probe_ext.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void adc_init(void);
|
||||||
|
uint16_t adc_read(uint8_t channel);
|
||||||
|
uint8_t is_device_connected(void);
|
||||||
23
src/defs.h
23
src/defs.h
@@ -8,15 +8,16 @@
|
|||||||
#define LED34_SW_DDR DDRA
|
#define LED34_SW_DDR DDRA
|
||||||
#define LED34_SW_PORT PORTA
|
#define LED34_SW_PORT PORTA
|
||||||
|
|
||||||
#define LED_PWM_PIN PA6
|
#define LED_PWM1_PIN PA6
|
||||||
|
#define LED_PWM2_PIN PA5
|
||||||
#define LED_PWM_DDR DDRA
|
#define LED_PWM_DDR DDRA
|
||||||
#define LED_PWM_PORT PORTA
|
#define LED_PWM_PORT PORTA
|
||||||
|
|
||||||
#define PROBE_OUT_PIN PB1
|
#define PROBE_OUT_PIN PB0
|
||||||
#define PROBE_OUT_DDR DDRB
|
#define PROBE_OUT_DDR DDRB
|
||||||
#define PROBE_OUT_PORT PORTB
|
#define PROBE_OUT_PORT PORTB
|
||||||
|
|
||||||
#define ESTOP_OUT_PIN PB0
|
#define ESTOP_OUT_PIN PB1
|
||||||
#define ESTOP_OUT_DDR DDRB
|
#define ESTOP_OUT_DDR DDRB
|
||||||
#define ESTOP_OUT_PORT PORTB
|
#define ESTOP_OUT_PORT PORTB
|
||||||
|
|
||||||
@@ -34,4 +35,18 @@
|
|||||||
|
|
||||||
#define PROBE_EXT_PIN PA3
|
#define PROBE_EXT_PIN PA3
|
||||||
#define PROBE_EXT_DDR DDRA
|
#define PROBE_EXT_DDR DDRA
|
||||||
#define PROBE_EXT_PORT PORTA
|
#define PROBE_EXT_PORT PORTA
|
||||||
|
|
||||||
|
|
||||||
|
#define LED_LEFT_GREEN() (LED12_SW_PORT &= ~(1 << LED12_SW_PIN))
|
||||||
|
#define LED_LEFT_RED() (LED12_SW_PORT |= (1 << LED12_SW_PIN))
|
||||||
|
#define LED_RIGHT_GREEN() (LED34_SW_PORT &= ~(1 << LED34_SW_PIN))
|
||||||
|
#define LED_RIGHT_RED() (LED34_SW_PORT |= (1 << LED34_SW_PIN))
|
||||||
|
|
||||||
|
#define LED_GREEN_BRIGHTNESS 2
|
||||||
|
#define LED_RED_BRIGHTNESS 20
|
||||||
|
|
||||||
|
#define SET_PROBE_HEIGHT() (PROBE_OUT_PORT &= ~(1 << PROBE_OUT_PIN))
|
||||||
|
#define SET_PROBE_LOW() (PROBE_OUT_PORT |= (1 << PROBE_OUT_PIN))
|
||||||
|
#define SET_ESTOP_HEIGHT() (ESTOP_OUT_PORT &= ~(1 << ESTOP_OUT_PIN))
|
||||||
|
#define SET_ESTOP_LOW() (ESTOP_OUT_PORT |= (1 << ESTOP_OUT_PIN))
|
||||||
70
src/led_pwm.c
Normal file
70
src/led_pwm.c
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include "defs.h"
|
||||||
|
#include "led_pwm.h"
|
||||||
|
|
||||||
|
#define PWM_LEFT OCR1B
|
||||||
|
#define PWM_RIGHT OCR1A
|
||||||
|
|
||||||
|
static void led_pwm_init(void)
|
||||||
|
{
|
||||||
|
// Ustaw pin PB1 (OC1A) jako wyjście
|
||||||
|
LED_PWM_DDR |= (1 << LED_PWM1_PIN) | (1 << LED_PWM2_PIN);
|
||||||
|
|
||||||
|
// Fast PWM, 8-bit mode, non-inverting mode
|
||||||
|
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10); // Clear OC1A on compare match
|
||||||
|
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // Prescaler 64
|
||||||
|
|
||||||
|
PWM_RIGHT = 0;
|
||||||
|
PWM_LEFT = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_init(void)
|
||||||
|
{
|
||||||
|
// Set pins for LED control as output
|
||||||
|
LED12_SW_DDR |= (1 << LED12_SW_PIN);
|
||||||
|
LED34_SW_DDR |= (1 << LED34_SW_PIN);
|
||||||
|
|
||||||
|
// Turn on red LEDs initially
|
||||||
|
LED_LEFT_RED();
|
||||||
|
LED_RIGHT_RED();
|
||||||
|
|
||||||
|
// Initialize PWM for LEDs
|
||||||
|
led_pwm_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_set_color(led_color_t color, led_side_t side)
|
||||||
|
{
|
||||||
|
uint8_t pwm_percent = 0;
|
||||||
|
|
||||||
|
if (side == LED_LEFT)
|
||||||
|
{
|
||||||
|
if (color == LED_COLOR_GREEN)
|
||||||
|
{
|
||||||
|
LED_LEFT_GREEN();
|
||||||
|
pwm_percent = LED_GREEN_BRIGHTNESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LED_LEFT_RED();
|
||||||
|
pwm_percent = LED_RED_BRIGHTNESS;
|
||||||
|
}
|
||||||
|
PWM_LEFT = (pwm_percent * 255UL) / 100; // Set PWM duty cycle for left LED
|
||||||
|
}
|
||||||
|
|
||||||
|
if (side == LED_RIGHT)
|
||||||
|
{
|
||||||
|
if (color == LED_COLOR_GREEN)
|
||||||
|
{
|
||||||
|
LED_RIGHT_GREEN();
|
||||||
|
pwm_percent = LED_GREEN_BRIGHTNESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LED_RIGHT_RED();
|
||||||
|
pwm_percent = LED_RED_BRIGHTNESS;
|
||||||
|
}
|
||||||
|
PWM_RIGHT = (pwm_percent * 255UL) / 100; // Set PWM duty cycle for right LED
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
src/led_pwm.h
Normal file
15
src/led_pwm.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LED_COLOR_RED,
|
||||||
|
LED_COLOR_GREEN,
|
||||||
|
} led_color_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LED_LEFT = 1,
|
||||||
|
LED_RIGHT = 2,
|
||||||
|
LED_BOTH = 3,
|
||||||
|
} led_side_t;
|
||||||
|
|
||||||
|
void led_init(void);
|
||||||
|
void led_set_color(led_color_t color, led_side_t side);
|
||||||
196
src/main.c
196
src/main.c
@@ -3,54 +3,174 @@
|
|||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "input_handler.h"
|
||||||
|
#include "timer_counter.h"
|
||||||
|
#include "adc_probe_ext.h"
|
||||||
|
#include "led_pwm.h"
|
||||||
|
|
||||||
void led_pwm(void);
|
void led_pwm(void);
|
||||||
|
void probe_int_on(ButtonKey_t *key);
|
||||||
|
void probe_int_off(ButtonKey_t *key);
|
||||||
|
void probe_ext_on(ButtonKey_t *key);
|
||||||
|
void probe_ext_off(ButtonKey_t *key);
|
||||||
|
void estop_on(ButtonKey_t *key);
|
||||||
|
void estop_off(ButtonKey_t *key);
|
||||||
|
|
||||||
|
ButtonKey_t probe_int = {
|
||||||
|
.instance = {1, &PINA, PROBE_INT_PIN},
|
||||||
|
.state = IDLE,
|
||||||
|
.last_state = IDLE,
|
||||||
|
.active_state = GPIO_PIN_SET,
|
||||||
|
.timer_debounce_on = 10, // 1000 ms
|
||||||
|
.timer_debounce_off = 10, // 1 ms
|
||||||
|
.buttonReleased = probe_int_off,
|
||||||
|
.buttonPressed = probe_int_on,
|
||||||
|
};
|
||||||
|
ButtonKey_t probe_ext = {
|
||||||
|
.instance = {2, &PINA, PROBE_EXT_PIN},
|
||||||
|
.state = IDLE,
|
||||||
|
.last_state = IDLE,
|
||||||
|
.active_state = GPIO_PIN_RESET,
|
||||||
|
.timer_debounce_on = 10, // 1000 ms
|
||||||
|
.timer_debounce_off = 10, // 1 ms
|
||||||
|
.buttonReleased = probe_ext_off,
|
||||||
|
.buttonPressed = probe_ext_on,
|
||||||
|
};
|
||||||
|
|
||||||
|
ButtonKey_t estop_in = {
|
||||||
|
.instance = {3, &PINA, ESTOP_IN_PIN},
|
||||||
|
.state = IDLE,
|
||||||
|
.last_state = IDLE,
|
||||||
|
.active_state = GPIO_PIN_RESET,
|
||||||
|
.timer_debounce_on = 10, // 1 ms
|
||||||
|
.timer_debounce_off = 10, // 1 ms
|
||||||
|
.buttonReleased = estop_off,
|
||||||
|
.buttonPressed = estop_on,
|
||||||
|
};
|
||||||
|
ButtonKey_t *inputs[3] = {
|
||||||
|
&probe_int,
|
||||||
|
&probe_ext,
|
||||||
|
&estop_in,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t ext_probe_connected = 0;
|
||||||
|
uint8_t estop_triggered = 0;
|
||||||
|
uint8_t blink_state = 0;
|
||||||
|
uint16_t last_blink_time = 0;
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
LED12_SW_DDR |= (1 << LED12_SW_PIN);
|
PROBE_OUT_DDR |= (1<< PROBE_OUT_PIN);
|
||||||
LED34_SW_DDR |= (1 << LED34_SW_PIN);
|
ESTOP_OUT_DDR |= (1<< ESTOP_OUT_PIN);
|
||||||
|
|
||||||
|
PROBE_OUT_PORT |= (1<< PROBE_OUT_PIN);
|
||||||
|
ESTOP_OUT_PORT |= (1<< ESTOP_OUT_PIN);
|
||||||
|
|
||||||
// LED12_SW_PORT |= (1 << LED12_SW_PIN);
|
led_init();
|
||||||
// LED34_SW_PORT |= (1 << LED34_SW_PIN);
|
timer0_init();
|
||||||
led_pwm();
|
adc_init();
|
||||||
|
|
||||||
// uint8_t i = 0;
|
sei(); // Enable global interrupts
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (PINA & (1 << PROBE_INT_PIN))
|
|
||||||
{
|
|
||||||
LED12_SW_PORT |= (1 << LED12_SW_PIN);
|
|
||||||
LED34_SW_PORT |= (1 << LED34_SW_PIN);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LED12_SW_PORT &= ~(1 << LED12_SW_PIN);
|
|
||||||
LED34_SW_PORT &= ~(1 << LED34_SW_PIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(PINA & (1 << ESTOP_IN_PIN)))
|
while (1)
|
||||||
{
|
{
|
||||||
TCCR1A &= ~(1 << COM1A1); // Wyłącz PWM
|
if (estop_triggered)
|
||||||
LED_PWM_PORT &= ~(1 << LED_PWM_PIN);
|
{
|
||||||
}
|
uint16_t now = ticks100us(); // Musisz mieć funkcję zwracającą czas w ms, np. z timer0
|
||||||
else
|
if (now - last_blink_time >= 2000) // 0.5 sekundy
|
||||||
{
|
{
|
||||||
TCCR1A |= (1 << COM1A1); // Włącz PWM
|
last_blink_time = now;
|
||||||
// LED_PWM_PORT |= (1 << LED_PWM_PIN);
|
blink_state = !blink_state;
|
||||||
}
|
if (blink_state)
|
||||||
}
|
{
|
||||||
return 0;
|
led_set_color(LED_COLOR_RED, LED_LEFT);
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_RIGHT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_LEFT);
|
||||||
|
led_set_color(LED_COLOR_RED, LED_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ext_probe_connected != is_device_connected())
|
||||||
|
{
|
||||||
|
ext_probe_connected = is_device_connected();
|
||||||
|
if (ext_probe_connected)
|
||||||
|
{
|
||||||
|
led_set_color(LED_COLOR_RED, LED_RIGHT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < sizeof(inputs) / sizeof(inputs[0]); i++)
|
||||||
|
{
|
||||||
|
buttonHandler(inputs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
void led_pwm(void)
|
|
||||||
|
|
||||||
|
void probe_int_on(ButtonKey_t *key)
|
||||||
{
|
{
|
||||||
// Ustaw pin PB1 (OC1A) jako wyjście
|
PROBE_OUT_PORT &= ~(1 << PROBE_OUT_PIN);
|
||||||
LED_PWM_DDR |= (1 << LED_PWM_PIN);
|
led_set_color(LED_COLOR_RED, LED_LEFT);
|
||||||
|
|
||||||
|
if (!ext_probe_connected)
|
||||||
|
{
|
||||||
|
led_set_color(LED_COLOR_RED, LED_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ustaw Timer1 w trybie Fast PWM, 8-bit (WGM13:0 = 0b0101)
|
void probe_int_off(ButtonKey_t *key)
|
||||||
TCCR1A = (1 << COM1A1) | (1 << WGM10); // Clear OC1A on compare match
|
{
|
||||||
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // Prescaler 64
|
PROBE_OUT_PORT |= (1 << PROBE_OUT_PIN);
|
||||||
|
|
||||||
|
if (estop_triggered)
|
||||||
|
{
|
||||||
|
estop_triggered = 0; // Reset estop when probe back to normal
|
||||||
|
led_set_color(LED_COLOR_RED, LED_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
// Ustaw wartość w rejestrze OCR1A (wypełnienie PWM)
|
led_set_color(LED_COLOR_GREEN, LED_LEFT);
|
||||||
OCR1A = 2; // 50% wypełnienia (dla 8-bit: 128/255)
|
|
||||||
|
if (!ext_probe_connected)
|
||||||
|
{
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void probe_ext_on(ButtonKey_t *key)
|
||||||
|
{
|
||||||
|
PROBE_OUT_PORT &= ~(1 << PROBE_OUT_PIN);
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void probe_ext_off(ButtonKey_t *key)
|
||||||
|
{
|
||||||
|
PROBE_OUT_PORT |= (1 << PROBE_OUT_PIN);
|
||||||
|
|
||||||
|
if (estop_triggered)
|
||||||
|
{
|
||||||
|
estop_triggered = 0; // Reset estop when probe back to normal
|
||||||
|
led_set_color(LED_COLOR_GREEN, LED_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
led_set_color(LED_COLOR_RED, LED_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void estop_on(ButtonKey_t *key)
|
||||||
|
{
|
||||||
|
ESTOP_OUT_PORT &= ~(1 << ESTOP_OUT_PIN);
|
||||||
|
estop_triggered = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void estop_off(ButtonKey_t *key)
|
||||||
|
{
|
||||||
|
ESTOP_OUT_PORT |= (1 << ESTOP_OUT_PIN);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user