Witam,
Pojawił się ostatnio u mnie taki problem. Otóż odczytuję z przetwornika ADC ATmegi16, z kanału ADC0 wartość napięcia (od 0 do 5VDC). Wyświetlam sobie wynik konwersji na LCD i wszystko ładnie działa (liczba na LCD zmienia się w zakresie od 0 do 1023, jak kręcę potencjometrem). Chciałem sterować tym napięciem podłączonym do ADC0 obrotami silnika prądu stałego. W tym celu postanowiłem wykorzystać PWM na Timer/Counter1.
PWM chodzi napewno. Konwersja ADC również. Problem polega na tym, że potrzebuję do OCR1A/ OCR1B wpisywać wartość z przedziału 0 do 100 (moc wyjściowa w %).
Dokonuję sobie przeliczenia mojego wyniku z przetwornika ADC takim sposobem:
i = ((AI1_REG) * 100 / 1023);
gdzie: AI1_REG - rejestr, do którego przepisuję wartość ADC po skończonej konwersji.
Wartość tak obliczonej zmiennej "i" także wyświetlam sobie na moim LCD i tutaj, o dziwo jak dla mnie, czary się dzieją, ponieważ dla zerowego napięcia na wejściu ADC0 wartość wyświetlacz pokazuje mi wartość 0 (z przetwornika) oraz 0 (% mocy PWM) i tak łądnie sobie liczy aż do 63% mocy. Potem wynik zmiennej "i" skacze na zero i znowu liniowo rośnie wraz ze wzrostem napięcia na ADC0 do wartości 37%.
Skąd te czary??? Przecież od razu widać, że suma tych skrajnych wartości mocy daje 100% (czyli tyle, ile powinienem uzyskać dla maksymalnego napięcia wejściowego na ADC0)...
Pisząc wyżej podaną linijkę kodu pomyślałem w taki sposób: "Liczby są typu całkowitego, więc jeśli wynik dzielenia wyjdzie jakiś niecałkowity i będzie coś po przecinku, to i tak to co po przecinku zostanie "obcięte" do wyniku całkowitego".
Czy moje myślenie było już na wejściu błędne? (Dodam, że moje początki z C były jakieś 3 lata temu, potem przerwa aż dotąd, więc może jakiegoś babola strzeliłem...)
Czy ktoś jest mi w stanie pomóc???
Poniżej kod programu głównego wraz z przerwaniami:
Dodatkowo umieszczam również plik z deklaracjami:
No i jeszcze na koniec plik z dodatkowymi funkcjami:
Pliku z funkcjami do LCD nie będę zamieszczał, bo działają napewno. W tych moich funkcjach również nic się nie sypało. Problem jest jedynie z przeliczaniem odczytu z ADC na % mocy wyjściowej PWM.
Pozdrawiam wszystkich, którym się chciało czytać i liczę na jakąkolwiek pomoc.
Pojawił się ostatnio u mnie taki problem. Otóż odczytuję z przetwornika ADC ATmegi16, z kanału ADC0 wartość napięcia (od 0 do 5VDC). Wyświetlam sobie wynik konwersji na LCD i wszystko ładnie działa (liczba na LCD zmienia się w zakresie od 0 do 1023, jak kręcę potencjometrem). Chciałem sterować tym napięciem podłączonym do ADC0 obrotami silnika prądu stałego. W tym celu postanowiłem wykorzystać PWM na Timer/Counter1.
PWM chodzi napewno. Konwersja ADC również. Problem polega na tym, że potrzebuję do OCR1A/ OCR1B wpisywać wartość z przedziału 0 do 100 (moc wyjściowa w %).
Dokonuję sobie przeliczenia mojego wyniku z przetwornika ADC takim sposobem:
i = ((AI1_REG) * 100 / 1023);
gdzie: AI1_REG - rejestr, do którego przepisuję wartość ADC po skończonej konwersji.
Wartość tak obliczonej zmiennej "i" także wyświetlam sobie na moim LCD i tutaj, o dziwo jak dla mnie, czary się dzieją, ponieważ dla zerowego napięcia na wejściu ADC0 wartość wyświetlacz pokazuje mi wartość 0 (z przetwornika) oraz 0 (% mocy PWM) i tak łądnie sobie liczy aż do 63% mocy. Potem wynik zmiennej "i" skacze na zero i znowu liniowo rośnie wraz ze wzrostem napięcia na ADC0 do wartości 37%.
Skąd te czary??? Przecież od razu widać, że suma tych skrajnych wartości mocy daje 100% (czyli tyle, ile powinienem uzyskać dla maksymalnego napięcia wejściowego na ADC0)...
Pisząc wyżej podaną linijkę kodu pomyślałem w taki sposób: "Liczby są typu całkowitego, więc jeśli wynik dzielenia wyjdzie jakiś niecałkowity i będzie coś po przecinku, to i tak to co po przecinku zostanie "obcięte" do wyniku całkowitego".
Czy moje myślenie było już na wejściu błędne? (Dodam, że moje początki z C były jakieś 3 lata temu, potem przerwa aż dotąd, więc może jakiegoś babola strzeliłem...)
Czy ktoś jest mi w stanie pomóc???
Poniżej kod programu głównego wraz z przerwaniami:
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <sterownik_deklaracje.h>
#include <lcd.h>
#include <avr/interrupt.h>
#include <util/delay.h>
/*************************************************************************************************
**************************************************************************************************
*************** PĘTLA GŁÓWNA PROGRAMU ****************
**************************************************************************************************
*************************************************************************************************/
int main(void)
{
config_function();
lcd_init(LCD_DISP_ON);
uint8_t i,i_pop;
char dupa[10];
while(1)
{
i = ((AI1_REG) * 100 / 1023);
if(i != i_pop)
{
h_bridge_pwm(LEWO,i);
i_pop = i;
lcd_clrscr();
itoa( AI1_REG , dupa, 10);
lcd_puts(dupa);
lcd_gotoxy(0,1);
itoa( i , dupa, 10);
lcd_puts(dupa);
}
}
}
/*************************************************************************************************
**************************************************************************************************
*************** PROCEDURY OBSŁUGI PRZERWAŃ ****************
**************************************************************************************************
*************************************************************************************************/
//=================================================================================
//przerwanie od przepełnienia licznika TC0 - obsługuje klawiaturę i wejścia cyfrowe
//=================================================================================
void TIMER0_OVF_vect(void)
{
TCNT0 = 99; //odtworzenie wartości początkowej licznika TC0
static uint8_t przycisk_pop_SW1; //zmienne do obsługi klawiszy
static uint8_t przycisk_pop_SW2; //
static uint8_t przycisk_pop_SW3; //
static uint8_t przycisk_temp_SW1; //
static uint8_t przycisk_temp_SW2; //
static uint8_t przycisk_temp_SW3; //
static uint8_t temp_DI1; //zmienne do obsługi wejść DI1-4
static uint8_t temp_DI2; //
static uint8_t temp_DI3; //
static uint8_t temp_DI4; //
static uint8_t pop_DI1; //
static uint8_t pop_DI2; //
static uint8_t pop_DI3; //
static uint8_t pop_DI4; //
static uint8_t licz_odczyt; //liczniki odczytów klawiatury i wejść DI
//Obsługa klawiszy funkcyjnych KLAW_PLUS, KLAW_MINUS, KLAW_MODE
//oraz wejść cyfrowych DI1, DI2, DI3, DI4
przycisk_temp_SW1 = 0; //domyślnie klawisze wciśnięte
przycisk_temp_SW2 = 0;
przycisk_temp_SW3 = 0;
temp_DI1 = 0;
temp_DI2 = 0;
temp_DI3 = 0;
temp_DI4 = 0;
if((SW_PIN & _BV(SW1)) == 0) //test przycisku KLAW_MODE
przycisk_temp_SW1 = 1;
if((SW_PIN & _BV(SW2)) == 0) //test przycisku KLAW_MINUS
przycisk_temp_SW2 = 1;
if((SW_PIN & _BV(SW3)) == 0) //test przycisku KLAW_PLUS
przycisk_temp_SW3 = 1;
if((DI_PIN & _BV(DI1)) == 1) //test wejścia DI1
temp_DI1 = 1;
if((DI_PIN & _BV(DI2)) == 1) //test wejścia DI2
temp_DI2 = 1;
if((DI_PIN & _BV(DI3)) == 1) //test wejścia DI3
temp_DI3 = 1;
if((DI_PIN & _BV(DI3)) == 1) //test wejścia DI4
temp_DI4 = 1;
if(pop_DI1 == temp_DI1 && pop_DI2 == temp_DI2 && pop_DI3 == temp_DI3 && pop_DI4 == temp_DI4 \
&& przycisk_temp_SW1 == przycisk_pop_SW1 && przycisk_temp_SW2 == przycisk_pop_SW2 \
&& przycisk_temp_SW3 == przycisk_pop_SW3)
licz_odczyt--;
else
{
przycisk_pop_SW1 = przycisk_temp_SW1;
przycisk_pop_SW2 = przycisk_temp_SW2;
przycisk_pop_SW3 = przycisk_temp_SW3;
pop_DI1 = temp_DI1;
pop_DI2 = temp_DI2;
pop_DI3 = temp_DI3;
pop_DI4 = temp_DI4;
licz_odczyt = LICZ_ODCZYT_START_VALUE;
}
if(licz_odczyt == 0)
{
KLAW_MODE = przycisk_temp_SW1;
KLAW_MINUS = przycisk_temp_SW2;
KLAW_PLUS = przycisk_temp_SW3;
WE_DI1 = temp_DI1;
WE_DI2 = temp_DI2;
WE_DI3 = temp_DI3;
WE_DI4 = temp_DI4;
licz_odczyt = LICZ_ODCZYT_START_VALUE;
}
}
//==================================================================
//przerwanie od przepełnienia licznika TC2 - liczy czas w sterowniku
//==================================================================
void TIMER2_OVF_vect(void)
{
LICZ_PRZERW --;
if(LICZ_PRZERW == 0)
{
LICZ_PRZERW = 250; //odtwórz wartość pierwotną LICZ_PRZERW
LICZ_SEK ++;
if(LICZ_SEK == 60)
{
LICZ_SEK = 0;
LICZ_MIN ++;
}
if(LICZ_MIN == 60)
{
LICZ_MIN = 0;
LICZ_GODZ ++;
}
if(LICZ_GODZ == 24)
{
LICZ_GODZ = 0;
}
}
}
//==============================
//przerwanie od przetwornika ADC
//==============================
void ADC_vect(void)
{
//przerwanie obsługujące przetwornik ADC
static uint8_t zrodlo_adc;
ADCSRA &= ~_BV(ADIF); //na wszelki wypadek wyzeruj flagę przerwania
zrodlo_adc = ADMUX & 0b00000111; //sprawdź wybrane wejście przetwornika ADC
switch (zrodlo_adc)
{
case 0:
{
AI1_REG = ADCW;
}
case 1:
{
AI2_REG = ADCW;
}
case 2:
{
AI3_REG = ADCW;
}
case 3:
{
AI4_REG = ADCW;
}
case 4:
{
H_FB_REG = ADCW;
}
}
zrodlo_adc += 1;
if(zrodlo_adc == 5)
zrodlo_adc = 0;
ADMUX &= 0b11111000; //zmień kanał przetwornika
ADMUX |= zrodlo_adc;
ADCSRA |= _BV(ADSC); //Start nowej konwersji
}
Dodatkowo umieszczam również plik z deklaracjami:
/****************************************************************************************************
*****************************************************************************************************
**** BIBLIOTEKA Z ZADEKLAROWANYMI NAZWAMI REJESTRÓW I STAŁYCH UŻYWANYCH W PROGRAMIE GŁÓWNYM ORAZ ****
**** W PRZERWANIACH ****
*****************************************************************************************************
*****************************************************************************************************
**** AUTOR: AŁEK ART. *******************************************************************************
*****************************************************************************************************
****************************************************************************************************/
#define LICZ_ODCZYT_START_VALUE 2 //Ilość zgodnych odczytów stanu klawiszy
volatile uint8_t LICZ_SEK; //
volatile uint8_t LICZ_MIN; //
volatile uint8_t LICZ_GODZ; //do użycia w przerwaniu od TC2
volatile uint8_t LICZ_PRZERW; //co tyle przerwań wejdzie do obsł. czasu
//**************************************
// Nazwy wejść analogowych i cyfrowych:
//**************************************
#define AI_PORT PORTA //Port procka, na którym wiszą wejścia analogowe
#define AI1 0 //Pierwsze wejście analogowe (pin nr 0 w porcie A)
#define AI2 1 //Drugie wejście analogowe (pin nr 1 w porcie A)
#define AI3 2 //Trzecie wejście analogowe (pin nr 2 w porcie A)
#define AI4 3 //Czwarte wejście analogowe (pin nr 3 w porcie A)
#define DI_PORT PORTC //Port procka, na którym wiszą wejścia cyfrowe
#define DI_PIN PINC //fizyczne stany wejść DI
#define DI1 0 //Pierwsze wejście cyfrowe (pin nr 0 w porcie C)
#define DI2 1 //Drugie wejście cyfrowe (pin nr 1 w porcie C)
#define DI3 2 //Trzecie wejście cyfrowe (pin nr 2 w porcie C)
#define DI4 3 //Czwarte wejście cyfrowe (pin nr 3 w porcie C)
volatile uint8_t WE_DI1; //znacznik stanu wejścia DI1
volatile uint8_t WE_DI2; //znacznik stanu wejścia DI2
volatile uint8_t WE_DI3; //znacznik stanu wejścia DI3
volatile uint8_t WE_DI4; //znacznik stanu wejścia DI4
//************************************************************************
//Nazwy rejestrów przechowujących odczytane wartości z wejść analogowych:
//************************************************************************
//Konwersja 10-bitowa -> potrzebne rejestry 16-bitowe (typu "int")
volatile uint16_t AI1_REG; //Rejestr z wartością odczytaną z wejścia AI1
volatile uint16_t AI2_REG; //Rejestr z wartością odczytaną z wejścia AI2
volatile uint16_t AI3_REG; //Rejestr z wartością odczytaną z wejścia AI3
volatile uint16_t AI4_REG; //Rejestr z wartością odczytaną z wejścia AI4
//**********************************************************************
//Nazwy klawiszy na klawiaturze i nazwy znaczników wciśnięcia klawisza:
//**********************************************************************
#define SW_PORT PORTB //Port procka, na którym wiszą klawisze
#define SW_PIN PINB //fizyczne stany klawiszy
#define SW1 0 //Pierwszy klawisz od lewej (pin 0 portu B)
#define SW2 1 //Środkowy klawisz (pin 1 portu B)
#define SW3 2 //Pierwszy klawisz od prawej (pin 2 portu B)
volatile uint8_t KLAW_PLUS; //Znacznik wcisniętego klawisza SW1
volatile uint8_t KLAW_MINUS; //Znacznik wciśniętego klawisza SW2
volatile uint8_t KLAW_MODE; //znacznik wciśniętego klawisza SW3
//***************************************
//Nazwy wyjść cyfrowych przekaźnikowych:
//***************************************
#define RO_PORT PORTD // "RO_PORT" znaczy "RELAY OUTPUT PORT"
#define RO1 7 //Pierwsze wyjście przekaźnikowe (pin 7 portu D)
#define RO2 2 //Drugie wyjście przekaźnikowe (pin 2 portu D)
//jest jednocześnie jednym z wyjść przekaźnikowego
//mostka H
#define RO3 3 //Trzecie wyjście przekaźnikowe (pin 3 portu D)
//jest jednocześnie jednym z wyjść przekaźnikowego
//mostka H
//**********************************************************************
//Nazwy wyjść cyfrowych do i wejścia analogowego ze scalonego mostka H:
//**********************************************************************
#define HO_PORT PORTD //Port procka, na którym wiszą wejścia scalonego mostka H
#define H_ENABLE 6 //Pin portu D sygnału "ENABLE" mostka H
#define H_IN1 5 //Pin portu D sygnału "IN1" mostka H
#define H_IN2 4 //Pin portu D sygnału "IN2" mostka H
#define HI_PORT PORTA //Port procka, na którym wisi wyjście pomiaru prądu mostka H
#define H_FB 4 //Pin portu A sygnału "FEEDBACK" mostka H.
//Wartość sygnału równa 1V/1A.
volatile uint8_t WARTOSC_MOCY; //rejestr zawierający wartość PWM scalonego mostka H
volatile uint8_t KIERUNEK; //kierunek kręcenia silnikiem w mostku H (umownie)
#define STOP 0 //zatrzymany
#define PRAWO 1 //kierunek "w prawo"
#define LEWO 2 //kierunke "w lewo"
//**************************************************************************
//Nazwa rejesru przechowującego odczytaną wartość prądu scalonego mostka H:
//**************************************************************************
volatile uint16_t H_FB_REG; //konwersja 10-bitowa -> potrzebny rejestr 16-bitowy.
//******************************
//Liczniki/Czasomierze - stałe:
//******************************
//*******************************************************************************************
//************************* Deklaracje funkcji: **************************
//*******************************************************************************************
//====================
//deklaracje przerwań:
//====================
extern void TIMER0_OVF_vect(void) __attribute__ ((interrupt));
extern void TIMER2_OVF_vect(void) __attribute__ ((interrupt));
extern void ADC_vect(void) __attribute__((interrupt));
//===========================
//koniec deklaracji przerwań:
//===========================
//==========================
//deklaracje innych funkcji:
//==========================
extern void config_function(void);
extern void h_bridge_pwm(uint8_t KIERUNEK, uint8_t WARTOSC_MOCY);
extern void przekaznik_on(uint8_t nr_przekaznika);
extern void przekaznik_off(uint8_t nr_przekaznika);
No i jeszcze na koniec plik z dodatkowymi funkcjami:
/****************************************************************************************************
*****************************************************************************************************
**** BIBLIOTEKA ZAWIERAJĄCA FYUNKCJE WYKORZYSTYWANE W PROGRAMOWANIU STEROWNIKA. ZAWIERA TEŻ ****
**** FUNKCJE KONFIGURACYJNE I WYKONYWANE NIEZALEŻNIE OD PROGRAMU GŁÓWNEGO (NP. W PRZERWANIACH). ****
*****************************************************************************************************
**** FUNKCJE TE UŻYWAJĄ NAZW ZMIENNYCH ZADEKLAROWANYCH W PLIKU "sterownik_deklaracje.h" ****
*****************************************************************************************************
*****************************************************************************************************
**** AUTOR: AŁEK ART. *******************************************************************************
*****************************************************************************************************
****************************************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <lcd.h>
#include <sterownik_deklaracje.h>
//**************************************************************************************
//Funkcja konfigurująca bebechy mikroklocka. Ustawia odpowiednie tryby pracy liczników,
//konfiguruje przerwania i ustawia wartości początkowe zmiennych dla programu głównego.
//Do funkcji nie są przekazywne żadne parametry, ani funkcja nic nie zwraca.
//Przeznaczona jest do użycia na samym początku programu głównego.
//**************************************************************************************
void config_function(void)
{
//cli(); //na wszelki wypadek wyłączenie wszystkich przerwań
KLAW_MODE = 0;
KLAW_PLUS = 0;
KLAW_MINUS = 0;
//****************************************************************
//ustawienie odpowiednich portów/pinów procka jako wejścia/wyjścia
//****************************************************************
DDRD = 0b11111110; //PORTD: 7-0 wyjścia
RO_PORT = _BV(RO3); //OD RAZU WYŁĄCZ NAPIĘCIE NA PRZEKAŹNIKOWYM MOSTKU H!!!
//(przeoczenie przy projektowaniu obwodu drukowanego).
//ustawi jedynkę na jednym z wejść mostka;
//reszta wyjść na zerach.
DDRC = 0b11110000; //PORTC: 7-4 wyjścia, 3-0 wejścia
PORTC = 0b00000000; //3-0: Pull-Up wyłączony na wszystkich pinach
DDRB = 0b11111000; //PORTB: 2-0 wejścia na klawisze
PORTB = 0b00000111; //2-0: Pull-Up włączony na tych pinach
DDRA = 0b11100000; //PORTA: 7-5 wyjścia, 4-0 wejścia
PORTA = 0b00000000;
//********************************
//Ustawienie trybu pracy liczników
//********************************
//==============================================================
//LICZNIK TC0 - używany do kontroli klawiatury i wejść cyfrowych
//==============================================================
TCCR0 = 0b00000101; //Timer TC0: ftakt=fcpu/1024, tryb "NORMAL"
TCNT0 = 99; //przerwanie co 10ms
//=======================================================
//LICZNIK TC2 - używany do odmierzania czasu w sterowniku
//=======================================================
TCCR2 |= (_BV(WGM21) | _BV(CS22) | _BV(CS21)); //Timer TC2: ftakt=fcpu/256, tryb "CTC"
TCNT2 = 249; //Wartość początkowa licznika TC2 - przerwanie co 4ms
//Liczba zliczanych impulsów: 250.
//=========================================================
//LICZNIK TC1 - odpowiada za PWM (na wyjściach OC1A i OC1B)
//=========================================================
TCCR1A = 0b10100010; //Tryb: FAST PWM
TCCR1B = 0b00011000; //licznik na dzień dobry zatrzymany
ICR1 = 100; //rozdzielczość PWM: 7-bit
//************************************************
//Konfiguracja modułu przetwornika ADC mikroklocka
//************************************************
ADCSRA = 0b00000111; //preskaler: 1/128 (125kHz) -> fs = 9.6kHz/5 = 1.9kHz
ADCSRA |= 0b10001000; //włączony przetwornik i przerwanie po konwersji
ADMUX = 0b01000000; //Vref = AVCC; wynik naturalny; kanał ADC0
_delay_us(130); //poczekaj 130us
//Wszystko już zrobione. Start konwersji później.
ADCSRA |= _BV(ADSC); //Start konwersji
TIMSK = 0b00000001; //przerwania od TC1 - nieaktywne
sei(); //Włączenie wszystkich przerwań
}
//*******************************************************************************************
// Koniec funkcji konfiguracyjnej
//*******************************************************************************************
//************************************************************************************************
//Funkcja włączająca scalony mostek H. Steruje mocą obwodu wyjściowego (zmienna WARTOSC_PWM)
//oraz polaryzacją napięcia wyjściowego (zmienna KIERUNEK).
//Można podać następujące wartości parametrów wejściowych:
//
// KIERUNEK:
// *STOP
// *PRAWO
// *LEWO
//
// WARTOSC_PWM: dowolna liczba int (procenty) z przedziału <0;100> - im większa, tym większa moc.
//************************************************************************************************
void h_bridge_pwm(uint8_t KIERUNEK, uint8_t WARTOSC_PWM)
{
if(KIERUNEK == STOP) //Gdy ma być zatrzymany, to:
{
HO_PORT &= ~_BV(H_ENABLE); //wyłączy mostek H
TCCR1B &= ~(_BV(CS12) | _BV(CS10)); //zatrzyma licznik TC1
OCR1A = 0; //wyzeruje oba PWMy
OCR1B = 0; //
}
if(KIERUNEK == PRAWO) //Gdy ma się kręcić w prawo, to:
{
HO_PORT &= ~_BV(H_ENABLE); //zatrzyma mostek H
TCCR1B &= ~(_BV(CS12) | _BV(CS10)); //wyłączy licznik TC1
OCR1A = WARTOSC_PWM; //załaduje odpowiednie wartości do OCR1x
OCR1B = 0; //
TCCR1B |= (_BV(CS12) | _BV(CS10)); //włączy licznik TC1
HO_PORT |= _BV(H_ENABLE); //włączy mostek H
}
if(KIERUNEK == LEWO) //Gdy ma się kręcic w lewo, to:
{
HO_PORT &= ~_BV(H_ENABLE); //zatrzyma mostek H
TCCR1B &= ~(_BV(CS12) | _BV(CS10)); //wyłączy licznik TC1
OCR1A = 0; //załaduje odpowiednie wartości do OCR1x
OCR1B = WARTOSC_PWM; //
TCCR1B |= (_BV(CS12) | _BV(CS10)); //włączy licznik TC1
HO_PORT |= _BV(H_ENABLE); //włączy mostek H
}
}
//*******************************************************************************************
// Koniec funkcji sterującej PWM
//*******************************************************************************************
//*******************************************************************************************
//Funkcja włączająca przekaźnik wyjściowy o numerze "nr_przekaznika"
//możliwe wartości parametru wejściowego:
// *RO1
// *RO2
// *RO3
//*******************************************************************************************
void przekaznik_on(uint8_t nr_przekaznika)
{
RO_PORT |= _BV(nr_przekaznika);
}
//*******************************************************************************************
//Funkcja wyłączająca przekaźnik wyjściowy o numerze "nr_przekaznika"
//możliwe wartości parametru wejściowego:
// *RO1
// *RO2
// *RO3
//*******************************************************************************************
void przekaznik_off(uint8_t nr_przekaznika)
{
RO_PORT &= ~_BV(nr_przekaznika);
}
Pliku z funkcjami do LCD nie będę zamieszczał, bo działają napewno. W tych moich funkcjach również nic się nie sypało. Problem jest jedynie z przeliczaniem odczytu z ADC na % mocy wyjściowej PWM.
Pozdrawiam wszystkich, którym się chciało czytać i liczę na jakąkolwiek pomoc.
