|
Не работает с float, mega16 |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 32)
|
Apr 27 2006, 14:30
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Цитата X = -(log((0.0025*Y)/4.959)/0.029) А также основание логарифма - натуральный, десятичный и диапазон Y, при котором тестирование происходило  А может тяжелый вес для AVR. Советую упростить, хотя так X=-(log(((int)(Y/4)*10000.)/0.143811 Это на первый взгляд, может кто еще проще предложит. Можно, например, константу 0.143811 (это 4.959*0.029) под знак логарифма внести и объединить с 10000.
|
|
|
|
|
Apr 28 2006, 04:00
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
Код следующий:
//Mega16 //iar EW AVR 4.12
#include <iom16.h> #include <ioavr.h> #include <inavr.h> #include <stdlib.h> #include <math.h>
#define NUM_IZM 128
//#define _N0 0x03 //#define _N1 0x9f //#define _N2 0x25 //#define _N3 0x0d //#define _N4 0x99 //#define _N5 0x49 //#define _N6 0x41 //#define _N7 0x1f //#define _N8 0x01 //#define _N9 0x09
// 1-st digit 0x10 // 2-nd digit 0x08 // 3-rd digit 0x04 // 4-th digit 0x02 // 5-th digit 0x01
//fuses 8MHz CKSEL3=0 CKSEL2=1 CKSEL1=0 CKSEL0=0 // SUT1=1 SUT0=0 65ms startup
__flash unsigned char Nums[]={0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
#pragma vector = TIMER2_OVF_vect __interrupt void TIMER2_OVF(void);
#pragma vector = TIMER2_COMP_vect __interrupt void TIMER2_COMP(void);
unsigned char print[5]; unsigned char num=0, di=0; unsigned int i=0; unsigned int temp=0, gc=0; //float temperature=0.0;
void init(void); void long2char(unsigned int); unsigned int ADCread(void);
//long int ADCread(void);
void main(void) { init(); di=0; while(1) { temp = ADCread(); gc=(unsigned int)((log(((temp*0.0025)-0.1438)/4.959))/0.029); long2char(gc); } }
unsigned int ADCread(void) { unsigned long ADC=0, tempADC=0; unsigned char i=0; while (i < NUM_IZM) // Усреднение по NUM_IZM замерам { // VCC ref and ADCx ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0); //Начинаем одиночное преобразование // ADLAR=0 -> ADCH ------98 ADCL 76543210 ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC)); // ADCSRA |= (1<<ADSC); // ADLAR=1 -> ADCH 98765432 ADCL 10------ // while(!(ADCSRA & (1 << ADIF))); //Ждем окончания преобразования ADCSRA |= (1<<ADIF); //Сбрасываем флаг tempADC = ADCL; tempADC += (ADCH<<8); ADC +=tempADC; i++; } ADC /= NUM_IZM; return ((unsigned int)ADC); }
#pragma vector = TIMER2_OVF_vect __interrupt void TIMER2_OVF(void) { di++; if (di>=5) { di=0; // i++; } }
#pragma vector = TIMER2_COMP_vect __interrupt void TIMER2_COMP(void) { PORTB = 0x1f^(1<<di); PORTC = Nums[print[di]]; }
void long2char(unsigned int input_num) { unsigned char ni=5; while (ni>0) { print[ni-1]=div(input_num,10).rem; input_num /=10; ni--; } }
#pragma inline=forced void init (void) { //port setup using portb & portc
PORTC = (1<<PORTC7) | (1<<PORTC6) | (1<<PORTC5) | (1<<PORTC4) | (1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0); DDRC = (1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0); PORTB = (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0); DDRB = (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
TCCR2 = (0<<FOC2) | (0<<WGM20) | (0<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (1<<CS20); TIFR = (1<<OCF2) | (1<<TOV2); //clear TIMSK = (1<<OCIE2) | (1<<TOIE2); //enable interrupt
TCNT2 = 0; OCR2 = 0x7f;
//ADC init //internal 2.56v with external capacitor at AREF pin //ADC0 single ended ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
ADCSRA = (1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (1<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC)); //wait for end conversion ADCSRA=ADCSRA; //clear ADCSRA __enable_interrupt();
}
|
|
|
|
|
May 2 2006, 06:51
|
Знающий
   
Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32

|
Цитата(Serg_greS) а на float я стал грешить после того, как сделал переменную gc типа float : Предлагаю операнды во float-point арифметике всё же приводить к правильному типу. В данном случае это будет выглядеть так: gc = 120.0 - ((float)(0x3ff-temp))*0.48;
--------------------
Главная линия этого опуса ясна мне насквозь!
|
|
|
|
|
May 3 2006, 06:18
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
подскажите в чем проблема при вычислении, если вот эту часть Цитата temp = ADCread(); gc=(unsigned int)((log(((temp*0.0025)-0.1438)/4.959))/0.029); long2char(gc); заменить на : ADCread(); if (temp<37) temp=37; gc=(unsigned int)(22499365 - 22473186*(powf(temp,0.00015))); long2char(gc); А то выяснилось, что такая функция намного лучше приводит значения полученные с АЦП к тем значениям, которым они соответствуют. В AVR Studio вся арифметика проходит гладко и без сбоев: с АЦП 965 --> gc=3002 с АЦП 0 --> 37 --> gc=14002 в реальном железе индикаторы не горят, хотя нули должны гореть всегда. и еще: в свойствах проекта CSTACK=0x256 RSTACK=128 надо ли их уменьшить/увеличить?
Сообщение отредактировал Serg_greS - May 3 2006, 06:32
|
|
|
|
|
May 3 2006, 09:15
|
Знающий
   
Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32

|
Цитата(Serg_greS @ May 3 2006, 12:07)  Подскажите почему не работает такая конструкция: gc=(temp*0.5); или gc=(temp*(float)0.5); тогда как gc=(temp/2); работает? Потому что temp - целое. Почитайте учебник по Си Кернигана-Ритчи или подобный, там хорошо изложено про преобразования типов в арифметике. Применительно к данной конкретной ситуации - сделайте, как я советовал парой постов ранее. То есть, gc=((float)temp*0.5);
--------------------
Главная линия этого опуса ясна мне насквозь!
|
|
|
|
|
May 3 2006, 13:14
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
2 vet Цитата gc=((float)temp*0.5); так тоже не работает в железке не работает даже так: float gc=0.0; ... gc=((float)temp*(float)0.5); или gc=((float)temp*0.5); temp=(unsigned int)gc; long2char(temp); ... , а в симуляторе AVR Studio пожалуйста любой вариант правильно исполняется. 2 topkin Цитата gc - какой тип данных? даже перебрав все варианты в AVR Studio все работает, в железке нет.
|
|
|
|
|
May 4 2006, 04:03
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
2 WHALE Цитата Имхо,что-то с выводом на ALC.У тебя динамическая индикация,а работа с флоат жрет намного больше времени.Поковыряй код там ALC - это имеется в виду АЛУ? и насчет индикации: пробовал запрещать все прерывания перед началом вычислений, а после вычисления разрешать (т.к. индикация осуществляется из прерывания), все равно не помогает. Таже ситуация в AVR Studio работает и работает правильно, а в железке нет. 2 Old1 Цитата Может быть дело в оптимизации? Когда для AVRStudio проект компилировали, был включен профиль debug и настройки оптимизации по умолчанию? т.е без оптимизации? А потом переключаемся в release, автоматически устанавливается максимальный уровень оптимизации по размеру, компилим hex-файл и ... не работает... Такое бывает... Попробуйте при создании файла для заливки в контроллер отключить оптимизацию. Так как раз без оптимизаций всяких и компиллирую в Debug варианте. Может это какая то особенность IAR`а v4.12 в evaluation варианте???? - косячная работа с float в реальном железе???
Сообщение отредактировал Serg_greS - May 4 2006, 04:04
|
|
|
|
|
May 4 2006, 05:48
|
Местный
  
Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589

|
Цитата(Serg_greS @ May 4 2006, 08:03)  Так как раз без оптимизаций всяких и компиллирую в Debug варианте. А шьете тоже Debug вариант? Помоему надо шить Release и все заработает.
--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
|
|
|
|
|
May 4 2006, 07:55
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(Serg_greS @ May 4 2006, 07:03)  2 WHALE Цитата Имхо,что-то с выводом на ALC.У тебя динамическая индикация,а работа с флоат жрет намного больше времени.Поковыряй код там ALC - это имеется в виду АЛУ? и насчет индикации: пробовал запрещать все прерывания перед началом вычислений, а после вычисления разрешать (т.к. индикация осуществляется из прерывания), все равно не помогает. Таже ситуация в AVR Studio работает и работает правильно, а в железке нет. 2 Old1 Цитата Может быть дело в оптимизации? Когда для AVRStudio проект компилировали, был включен профиль debug и настройки оптимизации по умолчанию? т.е без оптимизации? А потом переключаемся в release, автоматически устанавливается максимальный уровень оптимизации по размеру, компилим hex-файл и ... не работает... Такое бывает... Попробуйте при создании файла для заливки в контроллер отключить оптимизацию. Так как раз без оптимизаций всяких и компиллирую в Debug варианте. Может это какая то особенность IAR`а v4.12 в evaluation варианте???? - косячная работа с float в реальном железе??? Я ради интереса запустил код в JTAGICE+M16 (правда без оптимизации), так как ни странно код выполняется: формула вычисляется и с log() и c pow() , массив print[] заполняется, перекодировка работает, перекодированные данные в PORTC выбрасываются, разряды в PORTB двигаются, все это компилирую в том же IAR 4.12 и код гоняю в C-SPY... Проверьте все ли в порядке с динамической индикацией:временно отключите вычисление формул и запишите в переменную gc число (правдоподобное), если работает, проверьте вычисляется ли формула: на свободный пин контроллеоа повесьте светодиод и зажигайте/гасите его после вычисления формулы, или просто дрыгайте этим пином, а смотрите осциллографом (заодно и время вычисления увидите)...
|
|
|
|
|
May 4 2006, 10:59
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
2 Old1 Цитата Я ради интереса запустил код в JTAGICE+M16 Добавил светодиод на PORTD7, зажигаю его на 5 сек после init() и на время вычислений + ~0.6 сек. Так вот какая интересная штука получается: если в gc записать число и даже умножить его там на 0.5 все отображается, но только такое впечатление, что это выражение вычисляет компилятор, а в проц зашивается константа. А если вычислять gc=(temp*0.5); или gc=(di*0.5); или gc=((float)temp*0.5); или gc=(unsigned int)((float)temp*0.5); то светодиод не загорается даже после init(); (как будто проц висит и даже не проходит инициализация) Может у меня какая-то мега битая? ATMEGA16 16PI 0539J Old1 не могли бы Вы прислать свой .hex файл, который работает у вас
Сообщение отредактировал Serg_greS - May 4 2006, 11:00
|
|
|
|
|
May 4 2006, 19:50
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(Serg_greS @ May 4 2006, 13:59)  ... Добавил светодиод на PORTD7, зажигаю его на 5 сек после init() и на время вычислений + ~0.6 сек. Так вот какая интересная штука получается: если в gc записать число и даже умножить его там на 0.5 все отображается, но только такое впечатление, что это выражение вычисляет компилятор, а в проц зашивается константа. Так оно и есть. Цитата А если вычислять gc=(temp*0.5); или gc=(di*0.5); или gc=((float)temp*0.5); или gc=(unsigned int)((float)temp*0.5); то светодиод не загорается даже после init(); (как будто проц висит и даже не проходит инициализация) Может у меня какая-то мега битая? ATMEGA16 16PI 0539J Маловероятно... Цитата Old1 не могли бы Вы прислать свой .hex файл, который работает у вас Нет проблем, завтра на работе скомпилирую hex и прикреплю к посту. Я код гонял в ИАРовском C-SPY+ JTAGICE, там используется UBROF формат (если я правильно понял )...
|
|
|
|
|
May 5 2006, 07:26
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
2 Serg_greS Цитата(Old1 @ May 4 2006, 22:50)  Нет проблем, завтра на работе скомпилирую hex и прикреплю к посту... Вот выкладываю файл с прошивкой, и на всякий случай исходник, который компилировал. Прошивайте. Для информации, основные настройки проекта: cpu - mega16; memory model - small; CSTACK - 0x80; RSTACK - 32; language- C;optimizations- high/size; output format - intel-extended. FUSы - заводские.
Прикрепленные файлы
hex_c.rar ( 5.35 килобайт )
Кол-во скачиваний: 23
|
|
|
|
|
May 5 2006, 08:40
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
Цитата Вот выкладываю файл с прошивкой, и на всякий случай исходник, который компилировал. Спасибо что откликнулись, но только похоже что напрасно Не работает молчит не дышит. А Jtag в фузах у меня выключен, т.к. он на порте С и светится только часть сегментов при использовании gc=temp;, все остальные восстановил по умолчанию (у меня стоял внутренний генератор на 8МГц. Пробовал также и Jtag включить (т.е. все фузы по умолчанию)) - эффект тотже. Пробовал откомпиллировать присланный исходник с теми же параметрами проекта, не работает, но с чудесами у Вас hex кончается адресом 668, у меня d20, т.е. больше на n-е количество байт. Уже не знаю на что и думать  . Тупик какой-то, или проц всетаки с брачком.
|
|
|
|
|
May 5 2006, 09:29
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(Serg_greS @ May 5 2006, 11:40)  Цитата Вот выкладываю файл с прошивкой, и на всякий случай исходник, который компилировал. Спасибо что откликнулись, но только похоже что напрасно Не работает молчит не дышит. А Jtag в фузах у меня выключен, т.к. он на порте С и светится только часть сегментов при использовании gc=temp;, все остальные восстановил по умолчанию (у меня стоял внутренний генератор на 8МГц. Пробовал также и Jtag включить (т.е. все фузы по умолчанию)) - эффект тотже. Пробовал откомпиллировать присланный исходник с теми же параметрами проекта, не работает, но с чудесами у Вас hex кончается адресом 668, у меня d20, т.е. больше на n-е количество байт. Уже не знаю на что и думать  . Тупик какой-то, или проц всетаки с брачком. Странно все это... Что за адрес 668? В моем hex последний адрес вообще-то 0хCDD... Чем прошиваете контроллер? При прошивке верификация проходит без проблем? После прошивки пробовали читать флеш и сравнивать с исходным файлом?...
|
|
|
|
|
May 5 2006, 12:47
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
Цитата Чем прошиваете прошиваю с помощью http://avr.nikolaew.org/progr.htmверификация проходит без проблем
Сообщение отредактировал Serg_greS - May 5 2006, 12:48
|
|
|
|
|
May 5 2006, 18:42
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(Serg_greS @ May 5 2006, 15:47)  Цитата Чем прошиваете прошиваю с помощью http://avr.nikolaew.org/progr.htmверификация проходит без проблем Появилась мысль: если программирование и верификация FLASH проходит без проблем, код в симуляторе работает (и не в симуляторе у меня - тоже), у вас в железке работает,но только до тех пор пока в коде не появляются вычисления с плавающей точкой (при которых требуется больше оперативной памяти), то может быть в вашем контроллере какая либо область SRAM битая. Чтобы проверить ИМХО самый простой вариант взять другую М16 (если она есть), прошить и сравнить результаты, если же ее в наличии нет, тогда ради спортивного интереса и в целях самообразования стоит написать прогу для самотестирования SRAM (что-то вроде: записал байт в ячейку SRAM, прочитал, сравнил, и так по возможности проверить всю SRAM), залить ее в контроллер и посмотреть, что будет. Тут на форуме не так давно даже тема обсуждалась по поводу способов самотестирования AVR, поищите ознакомьтесь, может пригодится.
|
|
|
|
|
May 6 2006, 03:58
|

Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 13-01-05
Из: Москва
Пользователь №: 1 922

|
Цитата но только до тех пор пока в коде не появляются вычисления Цитата Добавил светодиод на PORTD7, зажигаю его на 5 сек после init() и на время вычислений + ~0.6 сек. Так вот какая интересная штука получается: если в gc записать число и даже умножить его там на 0.5 все отображается, но только такое впечатление, что это выражение вычисляет компилятор, а в проц зашивается константа. А если вычислять gc=(temp*0.5); или gc=(di*0.5); или gc=((float)temp*0.5); или gc=(unsigned int)((float)temp*0.5); то светодиод не загорается даже после init(); ведь после init(); не загорается тоже, а ведь до вычислений с плавающей точкой не дошли еще. а насчет самотестирования мысль хорошая, займусь этим.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|