Зачем тогда обращаться за помощью, если ее не будет ?!
Помощь будет тогда, когда Вы научитесь правильно задавать вопросы. А "У меня глючит программа на 3-ёх компиляторах, что мне делать ?" - не вопрос. Тут ответ один - экстрасенсы в отпуске, а Вам отладчик в руки и искать косяки.
PORTB = (unsigned char)(val & 0xFF);
на эту строку и ругается.
Может я не выспался или переработал, но в упор не вижу тут ошибок. Тем более - " '(' expected "
эти выражения надо вставлять в цикле где работаем с этими портами
Да.
Alex,спасибо,помог.Я объявлял это выражение глобально и компилятор ругался,а вставил в функцию где работаю с портами,и все заработало...
Еще вопрос в ATtiny2313, 7 выходов порта D,а D.0 у меня настроен на вход ,как это дело грамотней записать(val>>6),или это не правильно???
Спасибо.
Выкладываю часть кода, подскажите, я в правильной последовательности его написал? Спойлер#include <mega168.h>
#include <ds18b20.h>
#include <delay.h>
#include <1wire.h>
// #include <stdio.h> //вроде как для LCD
#asm
.equ __w1_port=8
.equ __w1_bit=0
#endasm
// для измерения температуры
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???
Спасибо.
Как моя программа работает я знаю очень хорошо, ни где не запутался.
Нашел место когда глюк происходит.
Выкладываю код: Спойлерvoid ADC_dathika_benzz(void)
{
unsigned char p;
unsigned long int Vsr = 0;
unsigned int a;
for (p=0;p<sredn_tochka;p++) // не более 255 выборок!!!
{
if ( 1) ADC_bort = 600;
else {
//Инициализация входа АЦП для изм борт напряжения
ADMUX=0b00000101; // bit 7,6=1 - внутр. ИОН= 5 в, bit 3,2,1,0 канал АЦП-adc5
ADCSRA=0b10001111; // бит 7 - разрешить, бит 0..2 частота преобразования, 3 бит - разрешить прерывание
Voltmetr (); //измеряем бортовое напряжение
ADC_bort = Srednee_znahenie_ADC ; //присваеваем значение АЦП борт сети
}
//Инициализация входа АЦП для изм датчика бензина
ADMUX=0b00000110; // bit 7,6=1 - внутр. ИОН=2,56в, bit 3,2,1,0 канал АЦП-adc6
ADCSRA=0b10001111; // бит 7 - разрешить, бит 0..2 частота преобразования, 3 бит - разрешить прерывание
Voltmetr ();
ADC_dathika_benzzz = (Srednee_znahenie_ADC*1000)/ADC_bort ;
if ( 1) ADC_bort = 600;
else {
//Инициализация входа АЦП для изм борт напряжения
ADMUX=0b00000101; // bit 7,6=1 - внутр. ИОН= 5 в, bit 3,2,1,0 канал АЦП-adc5
ADCSRA=0b10001111; // бит 7 - разрешить, бит 0..2 частота преобразования, 3 бит - разрешить прерывание
Voltmetr (); //измеряем бортовое напряжение
ADC_bort = Srednee_znahenie_ADC ; //присваеваем значение АЦП борт сети
}
//Инициализация входа АЦП для изм датчика бензина
ADMUX=0b00000110; // bit 7,6=1 - внутр. ИОН=2,56в, bit 3,2,1,0 канал АЦП-adc6
ADCSRA=0b10001111; // бит 7 - разрешить, бит 0..2 частота преобразования, 3 бит - разрешить прерывание
Voltmetr ();
//ADC_dathika_benzzz = (Srednee_znahenie_ADC *1000)/ADC_bort ;
a = ADC_dathika_benzzz - ((Srednee_znahenie_ADC *1000)/ADC_bort);
//////////////////////////////// if (a<=0) a = a * -1;
if (a == 0) Vsr=Vsr+ADC_dathika_benzzz ;
else p--;
// Vsr=Vsr+ADC_dathika_benz_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, ..), то способ