CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

Igor_67 писал(а):так тоже пробовал, код меньше всего на 0.3 кб, по сравнению с баскомом ваще не рулит. В кодвижне 30, в баскоме 23 - учитывая прерывание и обработку кнопок и ещё запись в еепром!!!
ощущение такое, что вы должны из своего кармана заплатить по доллару за каждый байт программы :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

помогите с таймером разобраться плиз!
есть Atmega8 настроена на внутренний генератор 8mhz
надо запускать прерывание по переполнению нулевого таймера.
Запускать надо к примеру каждый 1kHz
Делаю следующим образом:

//разрешить все прерывания
TIMSK=0x01;

//предделитель
TCC1B=0x02;

//с чем сравнивается
OCR1AH = 0xа4
OCR1AL = 0x01

TCNT1H = 0xfe;
TCNT1L = 0x0с;

вроде бы все?
если считаю avrcalc, получаются данные значения, правильно?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

во-первых, вы говорите о нулевом таймере, а пишите в регистры первого - где-то вкралась очепятка
во-вторых, если вдруг надеетесь на мою помощь (про других не скажу), то я понимаю запись с именами битов, а не хекс-цифры. например, так:
TCCR1B = 1<<CS11;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

ARV писал(а):во-первых, вы говорите о нулевом таймере, а пишите в регистры первого - где-то вкралась очепятка
во-вторых, если вдруг надеетесь на мою помощь (про других не скажу), то я понимаю запись с именами битов, а не хекс-цифры. например, так:
TCCR1B = 1<<CS11;


ну а на кого же мне еще рассчитывать ))))
обшибся, про первый таймер говорю!
чем хекс плохи? или привычка?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

хексы плохи тем, что не дают ни малейшего представления о том, какие биты вы именно устанавливаете. рыться в даташите или заучивать наизусть, какой именно бит какую роль играет - я не намерен :)

между прочим, если вы так же привыкните всегда использовать символьные имена битов в своих программах, а не числа - вы почувствуете, что это намного удобнее.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

ARV писал(а):хексы плохи тем, что не дают ни малейшего представления о том, какие биты вы именно устанавливаете. рыться в даташите или заучивать наизусть, какой именно бит какую роль играет - я не намерен :)

между прочим, если вы так же привыкните всегда использовать символьные имена битов в своих программах, а не числа - вы почувствуете, что это намного удобнее.


буду пробовать, сегодня переделаю и скину...
Аватара пользователя
Man
Встал на лапы
Сообщения: 83
Зарегистрирован: Чт ноя 13, 2008 19:22:03

Сообщение Man »

Возник тут вопрос…
Есть например переменная float c хранящимся в ней числом 58.748 как разбить его на 2 int , тоесть в одну переменную целую часть 58 , вовторую остаток 748 ,еше надобы отделный бит где будет хранится флаг положительного /отрицательного числа ? Пишу в cvavr.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

Man писал(а):Есть например переменная float c хранящимся в ней числом 58.748 как разбить его на 2 int , тоесть в одну переменную целую часть 58 , вовторую остаток 748 ,еше надобы отделный бит где будет хранится флаг положительного /отрицательного числа ? Пишу в cvavr.
В правильном C-компиляторе должно работать следующее

Код: Выделить всё

float fl = 58.748;
int integer_part = fl; // это преобразование по стандарту идёт с отбрасыванием дробной части
int fractional_part = (fl - integer_part) * 1000;
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Man
Встал на лапы
Сообщения: 83
Зарегистрирован: Чт ноя 13, 2008 19:22:03

Сообщение Man »

Спасибо avreal , работает . Но как быть с отрицательными значениями в float с ним непроходим такой способ ?
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

Man писал(а):Спасибо avreal , работает . Но как быть с отрицательными значениями в float с ним непроходим такой способ ?
А почему нет?
Советую поставить какой-нибудь "PC-шный" С-компилятор и на нём проврять всякое разное :-)
Можно очень быстро отмоделировать не зависящие от аппаратуры микроконтроллера куски кода.

Код: Выделить всё

// flo.c
#include <stdio>
#include <stdlib>

int main(int ac, char **av)
{
   while(--ac) {
      char *p = * ++av;
      float f = atof( p );
      int i = f;
      int q = (f-i)*1000;
      printf( "%-10s -> f=%f, i=%3d, q=%3d\n", p, f, i, q);   
   }
   return 0;
}

Код: Выделить всё

>gcc -Os -s flo.c -o flo.exe
>flo 5.37 9.99 -1.11 -2.99
5.37       -> f=5.370000, i=  5, q=369
9.99       -> f=9.990000, i=  9, q=989
-1.11      -> f=-1.110000, i= -1, q=-110
-2.99      -> f=-2.990000, i= -2, q=-990
>
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

Кстати, другой алгоритм работает в итоге так же:

Код: Выделить всё

#include <stdio>
#include <stdlib>

int main(int ac, char **av)
{
   while(--ac) {
      char *p = * ++av;
      float f = atof( p );
      int q = f * 1000;
      int i = q / 1000;
      q -= i * 1000;
      printf( "%-10s -> f=%f, i=%3d, q=%3d\n", p, f, i, q);   
   }
   return 0;
}
Разница с первым в количестве и "качестве" операций.
Первый - два преобразования от плавающего к целому, одно преобразование от целого к плавающему, одно плавающее вычитание и одно плавающее умножение.
Второй - одно плавающее умножение, одно преобразование от плавающего к целому, и по одному целочисленному делению, умножению и вычитанию.
Что будет быстрее работать и что займёт меньше кода - зависит от того, как выписана библиотека конкретного компилятора и что уже использовано в программе.
Например, если в программе целочисленное деление больше нигде не использовалось, только тут, а плавающее умножение и так есть - то второй вариант подошьёт из библиотеки "лишнее" целочиленное деление и программа станет больше.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

P.S. Я так понимаю, это для вывода куда-то на индикацию без использования преобразований плавающих форматов?
Если так, то надо не глядя на знак числа добавить в конце

Код: Выделить всё

q = abs(q);
ну или, что то же самое,

Код: Выделить всё

if(q<0) q = -q;
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Man
Встал на лапы
Сообщения: 83
Зарегистрирован: Чт ноя 13, 2008 19:22:03

Сообщение Man »

Avreal Правельно вы понимаете выводить надо на светодиодный индикатор . А именно попал датчик ds18b20 комне , со стандартными либами cvavr (#include <ds18b20> , #include <stdlib>) все завелось с полпинка , попробал вывести на жк(hd44780) затруднений невызвало , там ненадо было разберать флоат , через void ftoa(float n, unsigned char decimals, char *str) прогнал и в дисплей вывел . Вот со светодиодным индикатором такое непрокатило ему подавай целочислиные значения , ну и канешно отдельно минус вывести надо если он там есть. Ну или попробать в float XX.ZZZ сдвинуть запитаю XXZ.ZZ и вывести целое число ,а на индикаторе уже в нужном месте поставить точку, но вот как это сделать незнаю пока (неприходилось раньше с числами с плавающей точкой работать).
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

Для сегментного проще всего
int i = f * 1000;
вывести i и добавить вручную точку в нужный разряд (хотя могут быть нюансы с гашением лидирующих нулей).
Но для этого нужно знать как устроен вывод на семисегментник, если это закопано внутри cvavr и не описано, то остаётся сделать вывод на 7-сегментник самостоятельно.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Man
Встал на лапы
Сообщения: 83
Зарегистрирован: Чт ноя 13, 2008 19:22:03

Сообщение Man »

Да все уже разобрался может и неочень красиво написано но работает.Так как индикатор 4 разряда то первый разряд умя служит для показания +- , пока температура не выше 99.9 показывается десятая часть когда выше даного значения убирается точка и показывается до максимального 125.

Код: Выделить всё

#asm("sei")
h=1;
devices=w1_search(0xf0,rom_code);
ds18b20_init(&rom_code[i++][0],20,30,DS18B20_12BIT_RES);
i=0;
delay_ms(500);
while (1)
      {
      f=ds18b20_temperature(&rom_code[i][0]);
      if(f<0) {f=-f;c=1;} else{c=0;}
      if(f<99.9)
      {
      a=f;
      b=(f-a)*1000;
      b=b/100;
      a=a*10;
      a=a+b;
      k=1;
      }
      else
      {
      k=0;
      a=f;
      }
      indication=a;
      recoding();
      delay_ms(100);

      };

Завтро семисегментник раздабуду проверю в железе, пока токо протеус...
Вложения
.rar
(19.86 КБ) 257 скачиваний
Аватара пользователя
ValBag
Потрогал лапой паяльник
Сообщения: 326
Зарегистрирован: Сб сен 06, 2008 12:56:13

Сообщение ValBag »

Как отрегулировать положение окна CVAVR на рабочем столе? В cvavr.ini есть установки, определяющие положение, размеры окна, но в отношении положения они не работают.
Установлена на Win 7.
BeerLover
Родился
Сообщения: 3
Зарегистрирован: Пн янв 25, 2010 20:14:52

Сообщение BeerLover »

Вопрос, как можно в CVAVR узнать адрес конца кода. Хочу при прошивке к уже скомпиленной программе добавлять данные. Соответственно к этим данным надо как-то обращаться. После компиляции в ассемблерном листинге CVAVR устанавливает метку:

Код: Выделить всё

;END OF CODE MARKER 
__END_OF_CODE:

Но как в Си-шной программе получить адрес __END_OF_CODE?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

BeerLover писал(а):Вопрос, как можно в CVAVR узнать адрес конца кода. Хочу при прошивке к уже скомпиленной программе добавлять данные. Соответственно к этим данным надо как-то обращаться. После компиляции в ассемблерном листинге CVAVR устанавливает метку:

Код: Выделить всё

;END OF CODE MARKER 
__END_OF_CODE:

Но как в Си-шной программе получить адрес __END_OF_CODE?
наверное, определить указатель extern char *__END_OF_CODE;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
BeerLover
Родился
Сообщения: 3
Зарегистрирован: Пн янв 25, 2010 20:14:52

Сообщение BeerLover »

ARV писал(а):определить указатель extern char *__END_OF_CODE;

За идею спасибо, но оказалось не совсем так. Вот так получилось:

Код: Выделить всё

extern flash char _END_OF_CODE;
char flash *EndOfCode;
EndOfCode = &_END_OF_CODE;
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

BeerLover писал(а):
ARV писал(а):определить указатель extern char *__END_OF_CODE;

За идею спасибо, но оказалось не совсем так. Вот так получилось:

Код: Выделить всё

extern flash char _END_OF_CODE;
char flash *EndOfCode;
EndOfCode = &_END_OF_CODE;
имхо, тогда уж корректнее и проще так:

Код: Выделить всё

extern flash char *__END_OF_CODE;
тогда не потребуется заводить отдельную переменную-указатель для получения адреса - __END_OF_CODE уже будет равна этому адресу.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «AVR»