Страница 1 из 1

передать значение переменной в функцию из main

Добавлено: Вс май 24, 2020 14:45:06
RishatPF
Всем доброго дня. Надеюсь на вашу помощь. Прошу сильно не пинать.
Для наглядности выложил проект в протеусе во вложении.
Проблема в том что мне нужно в зависимости от выбранных значений переменных z и k получить на выходе сигнал с определенной частотой и количеством импульсов.
Если пишу просто
Спойлер

Код: Выделить всё

ISR (TIMER1_COMPA_vect)
  {  
   d=0;
 if((z==5) &(k==1)){d=5;}

if( c<d*4){
       switch(b)
    {
     case 0:PORTC =(1<<0)|(0<<1); break;        // светодиод 1 включить// светодиод  2 выключить
       case 1:PORTC =(1<<0)|(1<<1); break;    // светодиод 1 включить // светодиод  2 включить
        case 2:	PORTC =(0<<0)|(1<<1); break; // светодиод 1 выключить     // светодиод  2 включить
           case 3:  PORTC =(0<<0)|(0<<1); break;   // светодиод 1 выключить // светодиод  2 выключить
	}       
b++;
b%=4;
	c++; 
	} 

  }
то всё работает отлично. Но как только задаю другие значения, начинается не понятно что.
Спойлер

Код: Выделить всё

ISR (TIMER1_COMPA_vect)
  {  
  
	 d=0;
     if((z==5) &(k==1)){d=5;}
  if((z==5) &(k==10)){d=50;}
   if((z==5) &(k==50)){d=250;}
   if((z==5) &(k==100)){d=500;}
   if((z==5) &(k==200)){d=1000;}
   
f( c<d*4){
       switch(b)
    {
     case 0:PORTC =(1<<0)|(0<<1); break;        // светодиод 1 включить// светодиод  2 выключить
       case 1:PORTC =(1<<0)|(1<<1); break;    // светодиод 1 включить // светодиод  2 включить
        case 2:	PORTC =(0<<0)|(1<<1); break; // светодиод 1 выключить     // светодиод  2 включить
           case 3:  PORTC =(0<<0)|(0<<1); break;   // светодиод 1 выключить // светодиод  2 выключить
	}       
b++;
b%=4;
	c++; 
	} 

  }

Вчем я делаю ошибку, если не трудно разъясните пожалуйста по подробнее, так как я только учусь :(

Добавлено after 4 hours 12 minutes 59 seconds:
Запустил проект, буду весьма благодарен если проверите и дадите свои советы по оптимизации..

Re: передать значение переменной в функцию из main

Добавлено: Вс май 24, 2020 15:42:50
Ярослав555

Re: передать значение переменной в функцию из main

Добавлено: Пн май 25, 2020 12:27:18
NStorm
Чем отличаются 2 архива?
Что должен делать проект? Опишите цель.

Re: передать значение переменной в функцию из main

Добавлено: Пн май 25, 2020 16:22:20
RishatPF
[uquote="NStorm",url="/forum/viewtopic.php?p=3845965#p3845965"]Чем отличаются 2 архива?
Что должен делать проект? Опишите цель.[/uquote]
Здравствуйте. Спасибо что откликнулись.
С начало цель. Сделать универсальный генератор импульсов для ремонта топливораздаточных колонок на АЗС.
На дисплее один отображается выбранная с помощью кнопок С4 и С5 частота, это 1Гц, 10Гц, 50Гц, 100Гц и 200Гц.
На дисплее 2 выбираются прогоночные литры 5л, 10л, 20л и 50л.
Так как у разных производителей разное количество достижения одного литра и сделана :hunger: выборка частоты.
Если в кратце то эту задачу и имитирует генератор.
В первом файле никак не мог подружить частоту и литры. Во втором кое как смог, но не уверен что правильно решил задачу.

Re: передать значение переменной в функцию из main

Добавлено: Пн май 25, 2020 18:18:23
Ярослав555
Видимо Вы статью не читали и свои ошибки не поняли.

Re: передать значение переменной в функцию из main

Добавлено: Пн май 25, 2020 21:29:39
NStorm
Открыл проект, увидел знакомые места. И увидел что темки то уже были по этому проекту.
Вам в предыдущих темах давали советы уже, но вы их частично только приняли. Вот, например: https://radiokot.ru/forum/viewtopic.php?f=57&t=170763
Такой код разбирать - ужас. z, k, d - ну почему вы не можете называть переменные осмысленно? Вы же сами через месяц уже открыв проект, не вспомните что у вас там за что отвечает? Почему не назвать их нормально? Почему про сдвиги и логические операции не читаете, не слушаете?
Вы в итоге нагородили очень трудно читаемый код, которого хоть и мало, но разбирать это не будут с вероятность в 99%, потому что мало кто захочет ломать голову и вникать в это. Понимаете, код может не работать, может содержать ошибки, но при этом быть читаемым. И по нему можно давать советы. А есть вот такое.

Хотя вам уже Ярослав555 указал на ошибку. Дабы вы сами дошли до понимания, не буду давать подробностей тоже. Дам подсказку еще - читайте про логические операции и битовые операции в C.

Re: передать значение переменной в функцию из main

Добавлено: Вт май 26, 2020 05:02:28
RishatPF
[uquote="NStorm",url="/forum/viewtopic.php?p=3846182#p3846182"]Открыл проект, увидел знакомые места. И увидел что темки то уже были по этому проекту.
Вам в предыдущих темах давали советы уже, но вы их частично только приняли. Вот, например: https://radiokot.ru/forum/viewtopic.php?f=57&t=170763.......[/uquote]
Спасибо за то что уделили внимание и просмотрели код. Действительно многое пока не понимаю, так как начал изучать контроллеры не давно. Раньше тоже пытался, но не было времени, а теперь изза вируса практически сижу дома и решил подтянутся.
Названия переменных обязательно поменяю.
Про сдвиги и логические операции читал и слушал. Но похоже что то не допонимаю. В чём именно я что то делаю не так? Если не трудно ткните пальцем.
что означает не читаемый код? Я пытался по максимуму закомментировать, разбить на блоки но похоже вновь что то делаю не так :(

Re: передать значение переменной в функцию из main

Добавлено: Вт май 26, 2020 09:42:35
Ярослав555
да пофиг на читаемость кода - твое дело. СТАТЬЮ ОТКРОЙ и почитай, а потом подумай почему тебе ее дали почитать и как оно соотносится с твоим кодом.

Re: передать значение переменной в функцию из main

Добавлено: Вт май 26, 2020 11:21:14
NStorm
RishatPF, еще разок - по ссылке прям огромным шрифтом в самом верху выделена одна простая вещь - логическая и битовая операция. Найдите что у вас в коде применяется, хотя бы в 1ом посте тут. И подумайте - а точно это то, что вам нужно и каков будет результат.

Добавлено after 23 minutes 50 seconds:
Читаемость кода - это нормально и доступное именования функций и переменных, нормальные комментарии, правильные отступы, использование макросов и имен вместо магических чисел.
Как-то так для начала. А дальше нормально назвать все эти однобуквенные переменные, которые имеют смысл не просто счетчика. И исправить ошибку в логике. Код я не исправлял намерянно. Он равнозначем вашему. Но прочитать его человеку теперь намного проще.
Спойлер

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define  CHISLO PORTD

unsigned int razr1 = 0, razr2 = 0, razr3 = 0, razr4 = 0, razr5 = 0, razr6 = 0;
unsigned char reg = 1;
volatile unsigned int z, a = 0, i = 0, k = 0, j = 0, c = 0, d = 0, b = 0;
unsigned int comma = 0x80;
unsigned int chisla[11] = {
    // числа от 0 до 9
    0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x80
};

void vse_chislo(unsigned int razbivka_chisla) {
    // индикация первого дисплея 4 индикатора
    razr1 = razbivka_chisla / 1000; // тысячи
    razr2 = razbivka_chisla % 1000 / 100; // сотни
    razr3 = razbivka_chisla % 100 / 10; // десятки
    razr4 = razbivka_chisla % 10; // единицы

}

void vse_chislo1(unsigned int razbivka_chisla1) {
    // индикация второго дисплея 2 индикатора
    razr5 = razbivka_chisla1 % 100 / 10; // десятки
    razr6 = razbivka_chisla1 % 10; // единицы
}

ISR(TIMER0_OVF_vect) {
    //переключение разрядов для обоих дисплеев
    if (reg == 1) {
        PORTB |= (1 << PORTB5);
        PORTB &= ~(1 << PORTB0);
        CHISLO = chisla[razr1];
    } //включаем 1-й разряд, остальные выключаем
    if (reg == 2) {
        PORTB |= (1 << PORTB0);
        PORTB &= ~(1 << PORTB1);
        CHISLO = chisla[razr2];
    } //включаем 2-й разряд, остальные выключаем
    if (reg == 3) {
        PORTB |= (1 << PORTB1);
        PORTB &= ~(1 << PORTB2);
        CHISLO = chisla[razr3];
    } //включаем 3-й разряд, остальные выключаем
    if (reg == 4) {
        PORTB |= (1 << PORTB2);
        PORTB &= ~(1 << PORTB3);
        CHISLO = chisla[razr4] | comma;
    } //включаем 4-й разряд, остальные выключаем
    if (reg == 5) {
        PORTB |= (1 << PORTB3);
        PORTB &= ~(1 << PORTB4);
        CHISLO = chisla[razr5];
    } //включаем 5-й разряд, остальные выключаем
    if (reg == 6) {
        PORTB |= (1 << PORTB4);
        PORTB &= ~(1 << PORTB5);
        CHISLO = chisla[razr6];
    } //включаем 6-й разряд, остальные выключаем

    reg++; // добавляем к переменной reg единицу
    if (reg > 6) reg = 1; // отслеживаем переменную reg, чтобы она не превысила значение 4

}

void timer_ini(void) {
    TCCR1B |= (1 << WGM12); // устанавливаем режим СТС (сброс по совпадению)
    TIMSK |= (1 << OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
    OCR1AH = 0b01111010; //записываем в регистр число для сравнения
    OCR1AL = 0b00010010;
}

//--------------------------------------------

ISR(TIMER1_COMPA_vect) {

    d = 0;
    if ((z = 5) | (k = 1)) { d = 5; }
    if ((z = 5) | (k = 10)) { d = 50; }
    if ((z = 5) | (k = 50)) { d = 250; }
    if ((z = 5) | (k = 100)) { d = 500; }
    if ((z = 5) | (k = 200)) { d = 1000; }

    if ((z = 10) | (k = 1)) { d = 10; }
    if ((z = 10) | (k = 10)) { d = 100; }
    if ((z = 10) | (k = 50)) { d = 500; }
    if ((z = 10) | (k = 100)) { d = 1000; }
    if ((z = 10) | (k = 200)) { d = 2000; }

    if ((z = 20) | (k = 1)) { d = 20; }
    if ((z = 20) | (k = 10)) { d = 200; }
    if ((z = 20) | (k = 50)) { d = 1000; }
    if ((z = 20) | (k = 100)) { d = 20000; }
    if ((z = 20) | (k = 200)) { d = 4000; }

    if ((z = 50) | (k = 1)) { d = 50; }
    if ((z = 50) | (k = 10)) { d = 500; }
    if ((z = 50) | (k = 50)) { d = 2500; }
    if ((z = 50) | (k = 100)) { d = 5000; }
    if ((z = 50) | (k = 200)) { d = 10000; }

    if (c < d * 4) {
        switch (b) {
            case 0:
                PORTC = (1 << 0) | (0 << 1);
                break; // светодиод 1 включить // светодиод  2 выключить
            case 1:
                PORTC = (1 << 0) | (1 << 1);
                break; // светодиод 1 включить // светодиод  2 включить
            case 2:
                PORTC = (0 << 0) | (1 << 1);
                break; // светодиод 1 выключить // светодиод  2 включить
            case 3:
                PORTC = (0 << 0) | (0 << 1);
                break; // светодиод 1 выключить // светодиод  2 выключить
        }
        b++;
        b %= 4;
        c++;
    }

}

//--------------------------------------------

int main(void) {

    // Настройка портов ввода-вывода
    DDRD = 0xFF;
    DDRB = 0xFF;
    DDRC = (1 << DDC0) | (1 << DDC1); // тут не пишем магических чисел, пишем нормально
    PORTC = ~((1 << PC0) | (1 << PC1)); // аналогично

    CHISLO = 0xFF;

    // Настройка 0-го таймер счетчика на прерывание по переполнению
    TCCR0 = (1 << CS01); // f/8 а тут лучше было написать = вместо |= и CS01, вместо 1
    // TCCR0 &= ~((1 << 0) | (1 << 2));  - в этой строке не было никакого смысла в данном случае
    TIMSK |= (1 << TOIE0); // и тут пишем TOIE0 вместо 0
    TCNT0 = 0;
    sei();

    timer_ini(); // импульсы   
    sei(); //разрешаем приревания

    while (1) {
        vse_chislo1(z); //вывод на первый дисплей
        vse_chislo(k); //вывод на второй дисплей

        //*---------------------------------Дисплей 1-------------------------------------------------------*/  
        switch (i) {
            case 1:
                z = 5;
                break;
            case 2:
                z = 10;
                break;
            case 3:
                z = 20;
                break;
            case 4:
                z = 50;
                break;
            default: 
                z = 0;
        }

        /*-------------------------------Дисплей 2---------------------------------------------------------*/
        switch (j) {
            case 1:
                k = 1;
                break;
            case 2:
                k = 10;
                break;
            case 3:
                k = 50;
                break;
            case 4:
                k = 100;
                break;
            case 5:
                k = 200;
                break;
            default:
                k = 0;
        }

        //Переключение делителя  -----------------------------------------------------------------//
        switch (k) {
            case 1:
                TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (1 << CS10);
                OCR1A = 31249;
                break; // 1 Гц установим делитель.

            case 10:
                TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (1 << CS10);
                OCR1A = 3124;
                break; // 10 Гц установим делитель.       

            case 50:
                TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (1 << CS10);
                OCR1A = 624;
                break; // 50 Гц установим делитель.         

            case 100:
                TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
                OCR1A = 2499;
                break; // 100 Гц установим делитель.           

            case 200:
                TCCR1B = (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
                OCR1A = 1249;
                break; // 200 Гц установим делитель.             
        }


        // обработка нажатия кнопок до 50 
        if (bit_is_clear(PINC, 2)) {
            if (i < 4) {
                _delay_ms(1500);
                i = i + 1;
                _delay_ms(1500);
            } else {
                i = 0;
            }
        }

        if (bit_is_clear(PINC, 3)) {
            if (i > 0) {
                _delay_ms(1500);
                i = i - 1;
                _delay_ms(1500);
            } else {
                i = 0;
            }
        }

        // обработка нажатия кнопок до 1500 	
        if (bit_is_clear(PINC, 4)) {
            if (j < 5) {
                _delay_ms(1500);
                j = j + 1;
                _delay_ms(1500);
            } else {
                j = 0;
            }
        }

        if (bit_is_clear(PINC, 5)) {
            if (j > 1) {
                _delay_ms(1500);
                j = j - 1;
                _delay_ms(1500);
            } else {
                j = 0;
            }
        }
    }
    while (1);
}

Re: передать значение переменной в функцию из main

Добавлено: Ср май 27, 2020 05:27:21
RishatPF
[uquote="NStorm",url="/forum/viewtopic.php?p=3846363#p3846363"]RishatPF, еще разок - по ссылке прям огромным шрифтом в самом верху выделена одна простая вещь - логическая и битовая операция. Найдите что у вас в коде применяется, хотя бы в 1ом посте тут. И подумайте - а точно это то, что вам нужно и каков будет результат.[/uquote]
Добрый день. Статью на которую дана ссылка я прочитал.
Вы наверное имеете ввиду эту часть кода

Код: Выделить всё

 if ((z = 5) | (k = 1)) { d = 5; }

но я её исправил и во втором архиве он написан так

Код: Выделить всё

 if((z==5) &(k==1)){d=5;}else{  if((z==10) &(k==1)){d=10;}else{ if((z==20) &(k==1)){d=20;}else{  if((z==50) &(k==1)){d=50;} }}}
Спасибо за пример оформления кода. Сейчас буду переделывать.

Re: передать значение переменной в функцию из main

Добавлено: Ср май 27, 2020 07:29:30
emax
логическое И - &&
у Вас должно быть так if((z==5) &&(k==1)){d=5;}

Re: передать значение переменной в функцию из main

Добавлено: Ср май 27, 2020 09:03:35
NStorm
но я её исправил и во втором архиве он написан так

И всё-равно непраивльно. Вы не уловили то,что большими буквами написано в статье.