Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
20.06.2011, 20:58
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Сообщение от Godzilla82
|
Аналог вышеуказанного.
|
Спасибо! Испробую все варианты.
|
|
|
|
22.06.2011, 21:17
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Godzilla82,
Что-то не получается у меня вставить Ваш код.
Мой код:
Код:
|
iind=i_read();
ur=iind*0.01;
uind=u_read();
uind -=ur;
uindf(uind);
if (settimei‹1500)
iindf(imax);
else
iindf(iind); |
uindf(uind); - я понял, что это вывод на экран?
Перед ней я вставляю uind = display(uind);
Вместо value надо ставить uind?
CodeVisionAVR выдает ошибки на строках:
delta = abs(value-display_data);
else update = 1;
return display_tmp;
Может поможете мне подставить свой код в программу?
С iindf(iind); тоже нужно это делать?
|
|
|
|
23.06.2011, 00:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,445
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Сообщение от Dimitrij
|
Godzilla82,
CodeVisionAVR выдает ошибки на строках:
delta = abs(value-display_data);
else update = 1;
return display_tmp;
Может поможете мне подставить свой код в программу?
С iindf(iind); тоже нужно это делать?
|
да, функция uindf() - выводит значение напряжения на индикаторы.
можно использовать так:
PHP код:
|
uindf(display(uind));
|
Ошибку выдаёт потому, что он не знает, что такое функция abs().
Функция abs() описана в файле math.h. Его и нужно подключить:
PHP код:
|
#include ‹math.h›
|
Функция display() использует глобальную переменную display_tmp. В ней хранится отображаемое значение величины. То есть, её нельзя использовать одновременно для двух величин.
|
|
|
|
23.06.2011, 11:14
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Godzilla82,
delta = abs(uind-display_data); - Error: ch8.c(57): missing '('
time++; - Error: ch8.c(5 : missing '('
switch(time) - Error: ch8.c(59): declaration syntax error
После этого, естественно не находит delta.
И все же, Вместо value надо ставить uind?
|
|
|
|
23.06.2011, 21:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,445
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
У меня есть только исходный код, поэтому я и буду ориентироваться на него:
функция unsigned int read_adc(unsigned char adc_input) возвращает оцифрованное напряжение с указанного канала. Результат лежит в диапазоне [0..1023].
функция unsigned char u_read(void) оцифровывает напряжение. возвращаемое значение [0..255].
функция void uindf(unsigned char ul) переводит входное напряжение ul в массив цифр d[0] - d[2]. Значения из этого массива потом используются при динамической индикации. Число в первом элементе массива d[0] - десятки вольт, d[1] - единицы вольт, d[2] - десятые доли вольта.
код
PHP код:
|
uind=u_read();
uind -=ur;
uindf(uind);
|
первая строчка: в переменную uind заносится оцифрованное напряжение.
вторая строчка: из оцифрованного напряжения отнимается величина ur. То есть, падение напряжения на токоизмерительном резисторе.
третья строчка: в массив d[] переноситя скорректированное значение напряжения.
я вам давал код (в котором забыл описать переменную delta, и ещё по-мелочи):
PHP код:
|
#include ‹math.h›
unsigned int display_tmp_u = 0;
unsigned char time_u = 0;
unsigned int display_u(unsigned int value)
{
unsigned char update = 0;
unsigned int delta;
delta = abs(value-display_tmp_u);
time_u++;
switch(time_u)
{
case 1: if(delta›10) update = 1; // 100 ms
break;
case 2: if(delta›5) update = 1; // 200 ms
break;
case 3: if(delta›3) update = 1; // 300 ms
break;
case 4: if(delta›1) update = 1; // 400 ms
break;
default:
update = 1;
}
if(update) {
display_tmp_u = value;
time_u = 0;
}
return display_tmp_u;
}
|
исходный код надо поменять на:
PHP код:
|
uind=u_read();
uind -=ur;
uindf(display_u(uind));
|
также код
PHP код:
|
for (j=1; j‹100;j++) delay_ms(10);
|
заменить на:
Последний раз редактировалось Godzilla82; 24.06.2011 в 02:33.
|
|
|
|
24.06.2011, 11:04
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Godzilla82
Не думал, что так далеко влезу в программирование.
В CVAVR в библиотеке math.h функции abs нет, а есть в Stdlib.h: unsigned int abs(int x); . Это одно и то же? С этой библиотекой скомпилировалось без ошибок.
Цитата:
|
её нельзя использовать одновременно для двух величин
|
А если создать еще одну функцию, где заменить display_tmp_u на display_tmp_i. Не получится?
И уж коль Вы так дружелюбно отвечаете, еще один вопрос.
Нашел я функцию усреднения замеров АЦП и вставил в исходный текст:
Код:
|
unsigned char i;
unsigned long buf;
// Declare your global variables here
unsigned int u_read (void)
{unsigned long int buf;
unsigned int u;
buf=read_adc(ADCMUX_U);
buf=buf*510;
buf=buf/1024;
u=(unsigned int)buf;
return u;
}
unsigned int i_read(void)
{unsigned long int buf;
unsigned int i;
buf=read_adc(ADCMUX_I);
buf=buf*510;
buf=buf/1024;
i=(unsigned int)buf;
return i;
}
while (1){
buf=0;
for(i=0;i‹6;i++){buf+=u_read();}; //усредняем 6 замеров
#asm("cli");
buf=buf/6;
#asm("sei");
buf=0;
for(i=0;i‹6;i++){buf+=i_read();}; //усредняем 6 замеров
#asm("cli");
buf=buf/6;
#asm("sei");
iind=iset_read();
while (iind!=imax){
imax=iind;
iindf(iind);
settimei=0;
delay_ms(10);
iind=iset_read();
}
iind=i_read();
ur=iind/100;
uind=u_read();
uind -=ur;
delay_ms(100);
uindf(display_u(uind));
if (settimei‹1500)
iindf(imax);
else
iindf(iind);
delay_ms(100);
} |
В AvrStudio читает АЦП 6 раз, а с делением пробовал и на 6, на 4, на 2 - результат одинаковый. А по идее, если в буфер сложил 6 результатов и поделить не на 6, итоговое число будет другое.
В чем моя ошибка?
Последний раз редактировалось Dimitrij; 24.06.2011 в 16:49.
|
|
|
|
24.06.2011, 23:08
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,445
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Сообщение от Dimitrij
|
Godzilla82
Не думал, что так далеко влезу в программирование.
В CVAVR в библиотеке math.h функции abs нет, а есть в Stdlib.h: unsigned int abs(int x); . Это одно и то же? С этой библиотекой скомпилировалось без ошибок.
|
Скомпилировалось - ну и чудесно. У меня версия 1.25.9, там функция в файле math.h.
Сообщение от Dimitrij
|
А если создать еще одну функцию, где заменить display_tmp_u на display_tmp_i. Не получится?
|
Именно так и надо делать. И ещё добавить в описание две переменных display_tmp_i и time_i.
Сообщение от Dimitrij
|
И уж коль Вы так дружелюбно отвечаете, еще один вопрос.
Нашел я функцию усреднения замеров АЦП...
...
В чем моя ошибка?
|
Включите мозги и для себя объясните, что делает каждая строчка. Тогда сразу станет понятно, где ошибка. Обратите внимание, где вы 6 раз считываете АЦП, а также что потом с этой величиной делаете.
|
|
|
|
25.06.2011, 12:51
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Сообщение от Godzilla82
|
Включите мозги и для себя объясните
|
Уменя и так уже мозги набекрень. Не знаю я эту функцию
Код:
|
for(i=0;i‹6;i++){buf+=u_read();}; |
, взял с интернет. Пишут, что это скользящее среднее.
По идее функция unsigned int u_read(void) возвращает значение U.
А что тогда остается в буфере?
{buf+=u_read();} что с чем суммировать?
И в итоге нужно возвратить u_read() , а если я напишу u_read()=buf; , компилятор выдает ошибку Error: ch8.c(255): the expression must be a modifiable lvalue . Объясните, пожалуйста, как правильно сделать?
|
|
|
|
25.06.2011, 14:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,445
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Сообщение от Dimitrij
|
Уменя и так уже мозги набекрень. Не знаю я эту функцию
|
Возьмите описание языка Си и его базовых конструкций для начала. Как же можно что-то понять, не зная, что написано.
for() - оператор цикла
первое выражение в скобках: инициализирующая запись
второе выражение: условие выполнения
третье: действия, выполняющееся в конце каждой итерации
то есть:
Код:
|
for(i=0;i‹6;i++){buf+=u_read();}; |
переменной-счётчику i присваивается значение 0
условие выполнения - пока i меньше 6. А действия - i++. Это означает приращение переменной i на 1.
То есть, первый раз тело цикла (то, что в фигурных скобках) выполнится при i=0, второй раз - i =1 и т.д. Всего 6 раз.
В теле цикла одна запись:
Это означает, что к переменной buf прибавляется значение, возвращаемое функцией u_read().
То есть, делается 6 измерений напряжения и суммируется.
Далее:
PHP код:
|
#asm("cli");
buf=buf/6;
#asm("sei");
|
#asm("cli") - запрет прерываний, #asm("sei") - разрешение прерываний.
В принципе, эти команды здесь не нужны.
Накопленное значение делится на 6. То есть в переменной buf получается среднее арифметическое от 6 измерений.
Это значение и надо использовать. То есть, передавать функции отображения результата.
А раз уж надо, чтобы не мельтишило, то усреднённое значение передаём функции display_u().
PHP код:
|
uindf(display_u(buf));
|
Сами разберитесь, в каком месте это надо вставить, а также выкинуть всё лишнее. Ну и delay_ms(100) должно быть только один раз в конце цикла.
|
|
|
|
26.06.2011, 00:50
|
|
Временная регистрация
Регистрация: 26.02.2005
Сообщений: 78
Сказал спасибо: 15
Сказали Спасибо 16 раз(а) в 16 сообщении(ях)
|
Re: Изменить исходный код программы для ATMEGA8
Godzilla82,
Большое спасибо за доходчивое объяснение! Есть у меня что-то типа описания языка СИ, но писалось оно, я так думаю, для профессионалов.
Все, как будто, получилось. Так ли я все сделал, ничего лишнего?
Смущают меня задержки после каждого цикла.
Код:
|
unsigned int u_read(void)
{unsigned long int buf;
buf=read_adc(ADCMUX_U);
buf *=510;
buf /=ADC_U_DIV;
return buf;
}
unsigned int i_read(void)
{unsigned long int buf1;
buf1=read_adc(ADCMUX_I);
buf1 *=510;
buf1 /=ADC_U_DIV;
return buf1;
}
unsigned int iset_read(void)
{unsigned long int buf2;
buf2=read_adc(ADCMUX_I_SET);
buf2 *=510;
buf2 /=ADC_U_DIV;
return buf2;
}
while (1)
{
iind=buf2;
while (iind!=imax){
imax=iind;
iindf(display_i(iind));
settimei=0;
delay_ms(10);
iind=buf2;
}
iind=buf1;
ur=iind/100;
uind=buf;
uind -=ur;
uindf(display_u(uind));
if (settimei‹1500)
iindf(display_i(imax));
else
iindf(display_i(iind));
buf=0;
for(i=0;i‹6;i++){buf+=u_read();}; //усредняем 6 замеров напряжения
buf=buf/6;
delay_ms(100);
buf1=0;
for(i=0;i‹6;i++){buf1+=i_read();}; //усредняем 6 замеров тока
buf1=buf1/6;
delay_ms(100);
buf2=0;
for(i=0;i‹6;i++){buf2+=iset_read();}; //усредняем 6 замеров тока защиты
buf2=buf2/6;
delay_ms(100);
}; |
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:11.
|
|