void epprom_convert(uint16_t prob) { sot = prob / 100;// сотни des = (prob / 10) % 10;//десятки edin = prob % 10;//еденицы }
void shkala(uint8_t l) //разложение на разряды шкалы в пятиричной системе счисления { //с занесением во временный ммассив catod[0]=lm1[l]; catod[1]=lm2[l]; catod[2]=lm3[l]; catod[3]=lm4[l]; }
void code(char lever)//пятеричная система переводится на конкретные порты { switch (lever) { case 0: break; case 1: PORTB|=(1<<0); break; case 2: PORTB|=(1<<0)|(1<<4); break; case 3: PORTB|=(1<<0)|(1<<4)|(1<<5); break; case 4: PORTB|=(1<<0)|(1<<4)|(1<<5)|(1<<6); break; case 5: PORTB|=(1<<0)|(1<<4)|(1<<5)|(1<<6)|(1<<7); break; }
}
ISR(TIMER0_OVF_vect)//шкала { //организация отрезка выборки ~500ms c ДС if (p++>1950) { D1=S;//перекладываем насчитаное для дальнейшей обработки S=0;//сбрасываем насчитаное за 0,5сек p=0; D1N=D1N+D1/6; //суммируем пробег метры if (D1N>1000)// если насчитали больше км складываем в конечную копилку { df++; D1N=D1N/100; //тут оставшиеся десятки, а может даже и сотни возвращаем в сумматор } } PORTB&=~((1<<0)|(1<<4)|(1<<5)|(1<<6)|(1<<7));//сбрасываем катоды шкалы PORTD&=~((1<<0)|(1<<1)|(1<<4)|(1<<5));//сбрасываем аноды шкалы PORTD|=(1<<anod[k]); //перебираем аноды code(catod[k]); //выводим значение для каждого анода k++; if (k>3){k=0;} //что бы начать все сначало } void batt_fuel(void) { ADCSRA|=(1<<ADSC); ADMUX^=(1<<0); //меняем канал batt=(batt_8*200)/255;//формула расчета напряжения fuel=(255-fuel_8)/255; inki(batt); //ругается на эту строчку! т.е. на переход в функцию inki ///// Warning 1 implicit declaration of function 'inki' /////Error 3 previous implicit declaration of 'inki' was here shkala(fuel); } // void inki (int D1) // { // // }
void inki(int t) // эффект плавной смены цифр, здесь идет поиск тех цифр, которые надо менять ////Warning 2 conflicting types for 'inki' { uint8_t i;// запомнили новое время для 3 разрядов и заносим в массив tscr[] tscr[0] = t / 100;// сотни tscr[1] = (t / 10) % 10;//десятки tscr[2] = t % 10;//еденицы for (i = 0; (i < 3); i++) // сравнили с тем, что было 6 раз (цикл) if (tscr[i] != out[i]) // узнаём в каком разряде поменялась цифра, массив out[i] содержит текущие значения {fr[i] = 1;} // цифра изменилась создаем массив с индикатором 1 измененных цифр else {fr[i] = 0;} // цифра осталась iocr = 0; }
ISR (TIMER2_OVF_vect) // реализация ШИМ управления яркостью ламп и подсветки { uint8_t i;// переменная i PORTB &=~((1<<1)|(1<<2)|(1<<3)); OCR2 = lev[dig]; // подготавливаемся к выводу следуйщего разряда. таймер по совпадению if (iocr < 25)// плавная смена яркости цифр { if (++ms == 18) // ~38ms { ms = 0; for (i = 0; i < 3; i++) //без 100грамм не разобраться: { if ((fr[i] == 1) || (iocr == 0)) { lev[i] = psc[iocr]; } if (iocr == 12) { out[i] = tscr[i]; } } iocr++; } } }
ISR (TIMER2_COMP_vect) // реализация ШИМ управления яркостью ламп и подсветки { if(dig < 3)// три разряда 0,1,2 digr3-еденицы { PORTC = digit[out[dig]]; // выводим цифру на дешифратор катоды т.е.0-9 digr=dig+1; if (dig==0){if (out[0]!=0){PORTB|=(1<<digr);}}// далее выбор анодов цифр с гашением 0 if (dig==1){if ((out[0]!=0)||(out[1]!=0)){PORTB|=(1<<digr);}} if (dig==2){PORTB|=(1<<digr);} } if (++dig > 3){dig = 0;} }
ISR(ADC_vect) { if((ADMUX & 0xE6)==1) // Если был выбран канал ADC6 BATT { batt_8=ADCH; PORTC|=(1<<4);//зажигаем запятую } else { fuel_8=ADCH; }
}
ISR(INT0_vect) { S++;// здесь складываются импульсы от ДС }
ISR(INT1_vect) { cli(); PORTB=0x00;//тушим всю индикацию для снижения энергопотребления PORTD&=~((1<<0)|(1<<1)|(1<<4)|(1<<5)); PORTC&=~((1<<0)|(1<<1)|(1<<2)|(1<<3)); epprom_convert(df);//раскладываем на разряды if (eeprom_read_byte(&edinicy)!=edin)//если есть изменения, то: { eeprom_write_byte(&edinicy, edin);// сохраняем пробег поразрядно } if (eeprom_read_byte(&desyatki)!=edin) { eeprom_write_byte(&desyatki, des); } if (eeprom_read_byte(&sotny)!=edin) { eeprom_write_byte(&sotny, sot); } if (eeprom_read_byte(&ostatok_probega)!=D1N)//не забываем про остаточек пробега { eeprom_write_byte(&ostatok_probega, D1N); } }
int main(void) { /**********************************настройка портов******************************/ DDRB|=(1<<0)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<1)|(1<<2)|(1<<3); DDRD|=(1<<0)|(1<<1)|(1<<4)|(1<<5)|(1<<3); DDRC|=(1<<0)|(1<<1)|(1<<2)|(1<<3);//к дешифратору /**********************************настройка таймера2 индикация цифр*****************************/ TCCR2 |= (1 << CS20) | (1 << CS21); //предделитель на 32 TIMSK |= (1<<OCIE2) | (1<<TOIE2); /**********************************настройка таймера1 индикация шкалы*****************************/ TCCR0 |= (1<<CS01);// | (1<<CS00); //предделитель на 8 //на 64 TIMSK |= (1<<TOIE0); /**********************************настройка внешнего прерывания INT0*****************************/ MCUCR |= (1<<ISC01); //по убывающему фронту GICR |= (1<<INT0); /**********************************настройка внешнего прерывания INT1*****************************/ //для мониторинга питания, на случай его пропадания записать пробег в eeprom MCUCR |= (1<<ISC11)|(1<<ISC10); //по нарастающему фронту GICR |= (1<<INT1); /**********************************настройка ADC*****************************/ ADMUX |= (1 << REFS0)|(1<<REFS1); // Vref=2,56V ADMUX |= (1 << MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<ADLAR); // Подключаем канал ADC7, 8-bit ADC ADCSRA |= (1 << ADEN) // разрешение АЦП |(1 << ADSC) // запуск преобразования |(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0)|(1<<ADFR) // предделитель на 128 |(1 << ADIE); // разрешение прерывания от АЦП /********************************************************************************/ D1N=eeprom_read_byte(&ostatok_probega);//прочитали остаточек df=(eeprom_read_byte(&sotny)*100)+(eeprom_read_byte(&desyatki)*10)+eeprom_read_byte(&edinicy);//прочитали пробег sei(); while(1)//тестовые формулы и т.д. { sh=(ADCH*100)/1275; ds=D1/10; inki(df); shkala(ds); // inki(batt); ///если ставим здесь переход в функцию inki - ошибок нет! // shkala(fuel); _delay_ms(1000); ADCSRA|=(1<<ADSC); //batt_fuel(); //отображение 3 режима } return 0; }
ругается на переход в функцию inki если ставить на 8 строку снизу ошибок нет, если переход из void batt_fuel(void) два предупреждения и ошибка (места ошибок закоментированы)
ну прочтите и, если не понятно, переведите варнинг и сообщение об ошибке, сразу все станет ясно.
каждая функция должна быть определена до первого обращения к ней. если inki у вас реализована после batt_fuel, поэтому из inki можно обращаться к batt_fuel, а наоборот - нельзя. чтобы решить проблему, надо либо поменять местами реализацию этих функций в коде, либо в самом начале файла описать прототипы всех функций.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
eeprom_write_byte(&edinicy, 0); eeprom_write_byte(&desyatki, 0); eeprom_write_byte(&sotny, 0); eeprom_write_word(&full_p, 55555); здесь например 65535 при считывании eeprom_write_word(&calibration, 458); здесь 9 } sei(); D1N=eeprom_read_word(&ostatok_probega);//прочитали остаточек df=(eeprom_read_byte(&sotny)*100)+(eeprom_read_byte(&desyatki)*10)+eeprom_read_byte(&edinicy);//прочитали и собрали пробег vid=eeprom_read_byte(&vid_); calib_v=eeprom_read_word(&calibration); ul=eeprom_read_byte(&u_l); uf=eeprom_read_byte(&u_f);
while(1) {....... и так далее.....
успевает записать несколько адресов от балды, в последних обычно уже FF либо FFFF в зависимости от размера ячейки. в чем проблема может быть, с 3-4 строчками было все нормально, добавил еще адресов и усе, приплыли..... спустя пару часов...... каким то чудным образом смог правильно записать значения после того как добавил еще два if распределив по 3 записи в каждом if в чем прикол? компилятор или avr studio5? или оперативка в мк кончаетсяее.... хотя в железе вроде не подвисает.
Интересный комментарий... _update_ вместо _write_ - это, естественно, правильно... и структура вместо кучи переменных = однозначно!
Но. Если у автора есть проблема в последовательной записи в ЕЕ через _write_ (что, ничему не противоречит, и имеет право быть), то чем поможет _update_, если этому апдэйту придется также, например, ВСЕ поля структуры перезаписывать? ... и тогда он нарвётся на тот-же глюк через полгода?
Непонятно, что значит - "успевает"? Её (запись) кто-то торопит? Может, питание?...
данная последовательность нужна только при первом включении после сборки, там и упдайт был и врайт результат один. пока было три записи подряд все норм, как только добавил еще, то в порследующих записях после третей-четвертой запись уже не происходит, либо прорисходит с ошибками. данная запись сохраняет без ошибок: Спойлер
Код:
if (eeprom_read_byte(&vid_)>4) { eeprom_write_word(&full_p, 0); eeprom_write_word(&calibration, 275); eeprom_write_byte(&u_l, 219); eeprom_write_byte(&vid_, 1); } if (eeprom_read_word(&ostatok_probega)>3000) { eeprom_write_word(&ostatok_probega, 0); eeprom_write_byte(&u_f, 44); } if (eeprom_read_byte(&sotny)>9) { eeprom_write_byte(&edinicy, 3); eeprom_write_byte(&desyatki, 2); eeprom_write_byte(&sotny, 1); }
передвигал sei(); перед еппром не компилирует и еще сразу же порсле проршивки не включая, считываю еепром там уже значения лежат, программатор TL866А по ICSP. Нашел косяк! это программатор пишет хрень какую то... при программировании если снять галку поддержки питания и программировать при включенном устройстве то все норм, если устройство не включать и программировать с подпиткой МК от программатора то пишет всякую хрень в еепром спасибо всем за внимание вопрос закрываю.
Интересно... а для чего может на Си понадоюится управление регистром SREG ?
Mishany писал(а):
Спойлер
Код:
C Code Example char cSREG; cSREG = SREG; /* store SREG value */ /* disable interrupts during timed sequence */ _CLI(); EECR |= (1<<EEMWE); /* start EEPROM write */ EECR |= (1<<EEWE); SREG = cSREG; /* restore SREG value (I-bit) */
Ах да... вспомнил... я и сам так делал когдато... - например чтобы в нужном месте запомнить состояние прерываний, запретить прерывания, а потом восстановить то запомненное состояние...
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19730 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Если АВРовский компилятор держит регистр R1 нулевым, как он пользуется аппаратным умножителем?
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19730 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Ясно. Нигде не могу найти, как должна выглядеть "грамотная" прога на Сях (на АСМе тоже было бы неплохо).
Ну, что-то вроде универсальной. Чтобы пользователь мог залить её на "любой" МК с "любой" частотой и, например, работать по 1-Wire любой ногой. Т.е. всё по разным файлам, с соответствующими понятными варнингами при компиляции.
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
в свое время я этой темой "увлекался" и, как мне кажется, достиг практически желаемого вами правда, на любую частоту рассчитывать не приходится, т.к. код на Си 1-wire маловероятно будет работать при тактовой от 1 МГц и ниже... но если выше - работает, проверено на 8 и более МГц
поищу по закромам - выложу, если найду
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19730 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Ну, я потому и писал в кавычках "любой".
ARV писал(а):
код на Си 1-wire маловероятно будет работать при тактовой от 1 МГц и ниже...
С АСМовскими вставками наверняка будет. На 1 МГц самое быстрое что требуется это всего-то через 13 тактов считать значение от слэйва. Кстати про скорость и 1-Wire: viewtopic.php?p=2125243#p2125243
ARV писал(а):
поищу по закромам - выложу, если найду
Хорошо бы. А то я поначалу быдлокодил всё в один файл, без возможности какого-либо переноса.
Или просто на словах, что должно быть и чего-как объявлять. Например, подключаемые файлы .h и .c — что в каждом?
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения