Зачем тогда обращаться за помощью, если ее не будет ?!
Помощь будет тогда, когда Вы научитесь правильно задавать вопросы. А "У меня глючит программа на 3-ёх компиляторах, что мне делать ?" - не вопрос. Тут ответ один - экстрасенсы в отпуске, а Вам отладчик в руки и искать косяки.
PORTB = (unsigned char)(val & 0xFF); на эту строку и ругается.
Может я не выспался или переработал, но в упор не вижу тут ошибок. Тем более - " '(' expected "
эти выражения надо вставлять в цикле где работаем с этими портами
Да.
Alex,спасибо,помог.Я объявлял это выражение глобально и компилятор ругался,а вставил в функцию где работаю с портами,и все заработало... Еще вопрос в ATtiny2313, 7 выходов порта D,а D.0 у меня настроен на вход ,как это дело грамотней записать(val>>6),или это не правильно??? Спасибо.
// для измерения температуры unsigned char rom_code[8][9]; //масив с адресами найденых датчиков [мак кол во датчиков] [] unsigned char MAX_DEVICES ; unsigned char nomer_datchika = 1; //переменная в которой количество присоеденённых датчиков, и номер выбранного датчика float temp; //переменная для хранения температуры float datchik_temp[8]; float datchik_temp_min[8]; float datchik_temp_max[8];
unsigned int nomer_dat = 0;
// unsigned int TECT ; // для теста
//unsigned char rom_codes[MAX_DEVICES][9];
#define in_knopok PINC.3 #define in_gaz_klapon PINC.4 #define in_ACC PINC.2 #define smena_indikacii 100 // максимум 250 через какае время будет менятся информация #define lamp_G PORTB.2 //зеленый светодиод #define lamp_R PORTB.1 // красный светодиод #define sredn_tochka 5 // сколько раз будет делаться измерения для вычисления среднего значения топлива в одной точке (не в массиве) #define proz_pri_kalibr 1 //
eeprom unsigned char auto_toplivo = 1;// если 0 значит в ручном режиме eeprom unsigned char avto_vremya = 0; // для возврата в режим часы через 24 секунды
eeprom unsigned int max_delta_benz; // высчитывается в коллибровке eeprom unsigned int max_delta_gaz;
eeprom unsigned int max_delta_benz_ustanovlenno; eeprom unsigned int max_delta_gaz_ustanovlenno;
eeprom unsigned int tochka_rashod_benza ; // точка отсчета long eeprom unsigned int tochka_rashod_gaza ;
eeprom unsigned int Litr_benz[101];//1597Создаем массив где будут храниться значения АЦП с бензинового датчика eeprom unsigned int Litr_gaz[101];//Создаем массив где будут храниться значения АЦП с газового датчика
eeprom unsigned int polnyi_bak_benz ; // сохраняется значение полного бака eeprom unsigned int polnyi_bak_gaz ;
eeprom unsigned int min_uroven_benz = 100; eeprom unsigned int min_uroven_gaz = 100;
// Здесь объявленны переменные для БЕНЗА // Здесь объявленны переменные для ГАЗА
unsigned int benz_srednee[20]; unsigned int gaz_srednee[20];
unsigned int Uroven_benzina_dla_rashoda; unsigned int Uroven_gaza_dla_rashoda;
unsigned int ADC_dathika_benz ; unsigned int ADC_dathika_gaz ;
unsigned int rashod_benza ; unsigned int rashod_gaza ;
unsigned int Uroven_benzina ; // переменная где сохраняется вычесленное значение бензина unsigned int Uroven_gaza ; // переменная где сохраняется вычесленное значение газа
bit IGN_benz ; // смотрит включено ли зажигание bit IGN_gaz ;
bit v_rashode_benz_migat ; bit v_rashode_gaz_migat ;
bit zap_rejim; // для запоминания последнего режива при входе в сервисное меню bit v_dop_menu = 0; // для входа в дополнительное меню bit x = 0; // х = 1 - мигать индикатором bit g_b = 0; // для определение на какое топливо переключаться если в ручном рещиме bit a = 1; // а = 0 - потушить индикатор bit v_rejime_rashoda = 0; // если находится в режиме расхода, то = 1 bit tochka = 1; // точка третьего сегмента, включить значит = 1 bit tochka_L = 0; // точка рядом с L unsigned char time_ACC_vyhod = 240; unsigned char d=0; // Для мигания дисплея unsigned char xg_max ; // выбираем максимальное значение unsigned char xg_min ; // выбираем минимальное значение unsigned char iz_dop_meny; // хранится режим меню для возврата из сервистного меню unsigned char dvoinoe_najat_knopki; // переменная которая считает мин время для двойного нажатия кнопки unsigned char vuhod_iz_zapravki; // считаем время через которое автоматически выйдет из заправочного режима unsigned char yarkost_disp ; // для регулировки яркости дисплея unsigned char sec_schet = 0; // считаем десятую часть секунды unsigned char sec = 0 ; // считаем секунды unsigned char min = 0; // считаем минуты unsigned int hours = 12; // считаем часы unsigned int ADC_FOTO; // считанное значение АЦП с фото датчика unsigned char digit_out[4]; //переменные для работы с LED unsigned char r; //разряд unsigned char knopka1=11; // если равно 11, то кнопка не нажата. Если равно 1, то нажата unsigned char knopka2=22; unsigned char knopka3=33; unsigned char z=0; // Для входа в режим колибровки когда жмем кнопку 1 и ждем 5 секунд unsigned char n=0; // Для смены индикации unsigned char dlinnoe_najatie_knopki; // Для подсчета длинного нажатия кнопок unsigned char miganie_lamp; // режиме до полного бака , для отсчета времени мигания лампой unsigned char v_rejim; // для возврата в режим unsigned char el_v_rejim; // для возврата в режим unsigned char g = 0; //// для мигания светодиодом в режиме колибровки unsigned char ff;// для подсчета времени нажатия кнопки unsigned char pereyti_v_vremy; unsigned int indication; //переменная для хранения чисел unsigned int indication_IND; // то что надо отобразить на индикации unsigned int adc_data; //для результата АЦП unsigned int bort_U; // бортовое напряжение unsigned int max_bort_U; // бортовое напряжение максимальное unsigned int min_bort_U; // бортовое напряжение минимальное unsigned char rejim = 2 ; //смена режимов, 2-измерения топлива float Srednee_znahenie_ADC; unsigned char dly_vhoda_v_dop_meny; unsigned char bukva_0 = 255; unsigned char bukva_1 = 255; unsigned char bukva_2 = 255; unsigned char bukva_3 = 255; unsigned int xg = 0; unsigned char off_displey ; unsigned int dlya_kolibrovki_baka; //нужна для колибровки бензинового бака float ADC_bort; unsigned char izmerenie_temperaturu; unsigned char miganie_tochki_L;
//PORTB.0 первая цифра //PORTB.5 вторая цифра //PORTB.3 третья цифра //PORTB.4 четвертая цифра
interrupt [TIM0_OVF] void timer0_ovf_isr(void) //прерывание по перепонению TC/0
{ n++; if (n>=smena_indikacii) {n=0; indication=indication_IND ; // indication=1234;
digit_out[3]=indication%10; //Делим на 10 остаток в массив 1-разряд 2345%10=5 единицы indication=indication/10; //оставляем 1-вые 3 разряда 2345/10=234 if (bukva_3 == 255) {} else digit_out[3] = bukva_3;
digit_out[2]=indication%10; //Делим на 10 остаток в массив 2-разряд 234%10=4 десятки indication=indication/10; //оставляем 1-вые 2 разряда 234/10=23 if (bukva_2 == 255) {} else digit_out[2] = bukva_2;
digit_out[1]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 сотни indication=indication/10; if (bukva_1 == 255) {} else digit_out[1] = bukva_1;
if (indication_IND < 1000) digit_out[0] = 10; else digit_out[0]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 тысячи if (bukva_0 == 255) {} else digit_out[0] = bukva_0; }
//преобразование в 4-х разрядный LED r++; //с каждым срабатыванием таймера, увеличиваем переменную r на 1 if (r==4) r=0; //если r = 4 обнуляем
switch (r)
{ case 0: PORTB &= ~(1 << 4); // бит 4 равен 0 if (a==0) PORTD=digits[10]; else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD PORTB |= (1 << 0), DDRB=0b11111111; // присвоить нулевому биту 1 , DDRB=0b11111111 - для регулировки светодиодов TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости TCCR2B=0b100; // делитель на 32
if (in_knopok==PINB.0)knopka3=3; //если в это время на входе единица, то knopka =1 else knopka3=33; break;
case 1: PORTB &= ~(1<<0), DDRB=0b11111001 ; //выключаем разряд if (a==0) {PORTD=digits[10];} //это постоянно вкл. точка! общий катод else {PORTD=digits[digit_out[r]];} //PORTD.7=1; if (tochka == 1) PORTD.7=1; PORTB |= (1 << 5) ; //включаем разряд TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости TCCR2B=0b100; // делитель на 32
if (in_knopok==PINB.5) knopka2=2; else knopka2=22; break;
case 2: //подаём питание на разряд 3 (1) PORTB &= ~(1<<5) ; if (a==0) PORTD=digits[10]; else PORTD=digits[digit_out[r]]; PORTB |= (1 << 3) ; TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости TCCR2B=0b100; // делитель на 32
if (in_knopok==PINB.3)knopka1=1; else knopka1=11; break;
case 3: //подаём питание на разряд 1 (1) PORTB &= ~(1 << 3); // бит 3 равен 0 if (a==0) PORTD=digits[10]; else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD if (tochka_L == 1) PORTD.7=1; PORTB |= (1 << 4) ; // присвоить нулевому биту 1 //TCNT2=200; // начать отсчет с 0 // переменная для регулировки яркости TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости TCCR2B=0b100; // делитель на 32
} }
interrupt [TIM2_OVF] void timer2_ovf_isr(void) //прерывание по перепонению TC/2
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //прерывание по перепонению TC/1
{ //это прерывание будет с частотой 10 герц будет (10 раз в секунду)
//TCNT1 = 59285 ;// отстают должно быть оно //TCNT1 = 59300 ; // спешат сильно //TCNT1 = 59289; // на 6 сек перегнали за 5 часов TCNT1L = 0x96 ; TCNT1H = 0xE7 ; // 59286 отстают на 12 сек за 12 часов // TCNT1L = 0x97 ; // TCNT1H = 0xE7 ; //59287 перегнали на 5 сек за 8 часов sec_schet++; if (sec_schet == 10) {sec_schet = 0, sec ++; if (sec == 60) {min++, sec = 0; if (min == 60) {hours++, min = 0; if (hours == 24) hours = 0; } } } dvoinoe_najat_knopki++; vuhod_iz_zapravki++; dlinnoe_najatie_knopki++; miganie_lamp ++; ff++; g++; // для мигания светодиодом в режиме колибровки off_displey++; dly_vhoda_v_dop_meny++; izmerenie_temperaturu++; miganie_tochki_L ++; pereyti_v_vremy ++;
if (rejim == 15) //показания топлива газа { if (knopka1==11) z=0; // ВАЖНО для входа в режим колибровки , надо ждать 5 секунд else z++; }
if (rejim == 6){} // что бы не мигал индикатор когда в колибровку входит else { if (x==1) // для мигания индикатора {d++; if (d<3)a = 0; else a = 1;
if (d>7) d = 0; } else a = 1; }
if (rejim == 14) // режим показания расхода бензина {if (lamp_G == 0){g++ ,lamp_R = 0; if (g > 18) g = 0, lamp_R = 1;} //lamp_G == 0 надо для того чтобы ламп светился оранжевым, а подмигивал
}
if (rejim == 17) // режим показания расхода газа { if (lamp_R == 0) {g++ ,lamp_G = 0; if (g > 18) g = 0, lamp_G = 1;} } }
interrupt [ADC_INT] void adc_isr(void) //прерывание по окончании преобразования
Первое, что бросается в глаза - куча глобальных переменных. Это, конечно, не катастрофа, но , даю рубь за сто, можно укоротить этот список раз в десять. Второе. Подобные конструкции:
digit_out[3]=indication%10; //Делим на 10 остаток в массив 1-разряд 2345%10=5 единицы indication=indication/10; //оставляем 1-вые 3 разряда 2345/10=234
digit_out[2]=indication%10; //Делим на 10 остаток в массив 2-разряд 234%10=4 десятки indication=indication/10; //оставляем 1-вые 2 разряда 234/10=23 ....... .......
пихать в обработчик прерываний - уже катастрофа. Они могут выполняться по времени дольше, чем вызовется следующее прерывание, или могут "душить" другие обработчики. Вынесите их в главный цикл.
В третих. У вас программа слишком запутана - куча каких-то условий, блоков, ... В ней очень трудно ориентироваться. Скорее всего, Вы просто сами в ней запутались, а это уже пол-пути к глюку.
Ну и на последок. Скорее всего, у Вас ещё проблемы с атомарностью (этот вариант уже озвучивали тут). "Скорее всего" по тому, что не видно основного цикла.
Alex,у меня надо использовать ПортВ и ПортД.6,Д.5,Д.4,Д.3 как выход с помощью одной переменной(с этим разобрались),а ноги Д.2,Д.1,Д.0 как входы.Вопрос в следующем как правильно записать(var>>???),чтоб перескочить порты Д.0,Д.1,Д.2, и записать значение var в нужные нам Д.6,Д.5,Д.4,Д.3??? Спасибо.
как правильно записать(var>>???),чтоб перескочить порты Д.0,Д.1,Д.2, и записать значение var в нужные нам Д.6,Д.5,Д.4,Д.3???
Сдвинуть переменную на 3 бита влево (var<<3). Либо, записывая в эту переменную данные, учитывать этот сдвиг, а переменную выводить в порты без всяких изменений.
Если строчку if ( 1) ADC_bort = 600; заменить на if (stabilizator_BENZ_bit == 1) ADC_bort = 600; Глюк такой: перестает находить цифровые датчики температуры.
Ну дак не меняйте, и глюка не будет... Фраза "перестает находить цифровые датчики температуры" не несёт никакой информации о проблеме. Мне например, так же как и многим, не очень хочется разгадывать "тайны", хранящиеся у Вас в голове. Почему подобные "глюки" происходят можете понять только Вы, как автор программы (если, конечно, Вы таковым являетесь).
Если строчку if ( 1) ADC_bort = 600; заменить на if (stabilizator_BENZ_bit == 1) ADC_bort = 600; Глюк такой: перестает находить цифровые датчики температуры.
Ну дак не меняйте, и глюка не будет... Фраза "перестает находить цифровые датчики температуры" не несёт никакой информации о проблеме. Мне например, так же как и многим, не очень хочется разгадывать "тайны", хранящиеся у Вас в голове. Почему подобные "глюки" происходят можете понять только Вы, как автор программы (если, конечно, Вы таковым являетесь).
Вот и я не пойму, почему глючит компиль! В этой функции нет ни какого отношения к измерению и инициализации датчиков температуры.
Не стоит делать таких громких заявлений. Я больше чем уверен, что проблема в Вашем коде. Когда обвиняют компилятор, приводят неоспоримые доказательства этому, прикладывая все "улики" в подробностях.
компилятор как компилятор. Дело не в бобине. вы используете для термодатчиков закрытую библиотеку, входящую в его состав, а затем своими прерываниями нарушаете ее работу. Можно портировать из винавр, например, фунцию работы с датчиками, в свою прогу. Ну и стиль написания еще тот, конечно... Не старайтесь все влепить в 1 файл, разбейте на структуры свалку ваших переменных, выражение if (rejim == 15) - ну не должно такого быть в нормальной программе в принципе, используйте перечисление.
Добрый День всем. Может кто подскажет как компактнее написать код в CVARV. Суть вопроса такая: Есть две переменные A и B, у каждой значение от 1 до 100(цифры просто для примера),как описать между ними линейную зависимость? Допустим если переменная A равна 50, то B должна принять значение 50,ну так далее,другими словами нужно значение шим выставлять от температуры. Как я вижу код:
unsigned char A[]={здесь значение от 1 до 100}; unsigned char B[]={здесь значение от 1 до 100}; //объявляю массив данных
дальше где нужно опрашивать значение в коде, пишем код:
if (Temp == A[1]) { OCR2 = B[1]; };
ну и так 100 раз написать. Понимая что нехороший код,но в голову ничего другого не приходить.
Не понятно, зачем использовать 2 массива ? Достаточно одного - зависимость температура/скважность. Заполняем массив значениями скважности и выбираем из него по индексу, равному температуре, без всяких циклов и переборов. Если у Вас в массиве значения температуры будут не с определённым шагом (например 1,3,10,15, ..), то способ