Страница 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л.
Так как у разных производителей разное количество достижения одного литра и сделана

выборка частоты.
Если в кратце то эту задачу и имитирует генератор.
В первом файле никак не мог подружить частоту и литры. Во втором кое как смог, но не уверен что правильно решил задачу.
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;}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
но я её исправил и во втором архиве он написан так
И всё-равно непраивльно. Вы не уловили то,что большими буквами написано в статье.