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

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

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

Сообщение ARV »

во-первых, это работать не будет

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

        ADCSR |= 0x40;
        data = ADCW;   
во-вторых, вам советовали РАЗДЕЛИТЬ измерение, анализ и вывод. это очень разумные советы. предположим, вы им последовали и сделали ИЗМЕРЕНИЕ в виде функции get_adc() - эта функция вернет вам значение сигнала на входе. тогда ваше "ожидание сигнала" будет заключаться в измерении и проверке уровня в цикле:

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

while(get_adc() < POROG);
, где POROG - это тот уровень, превышение которого означает "приход" сигнала.

дальше уже по задаче: выводите измеренное значение или что-то с ним делаете иное... например, если надо выводить только ОБНОВЛЕНИЕ уровня сигнала, то делаете такое в цикле

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

v1 = get_adc();
if(v1 != v){
   // тут выводите v1
   v = v1;
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Не с той вы стороны, ребята, подходите к объяснению. Прежде чем выяснять, как это будет выглядеть в коде, стоит определиться, как это будет выглядеть в голове. Нужно взять бумагу и нарисовать схему будущего алгоритма. Для этого придуманы ( пояснение для начинающих :) ) очень простые условные значки. Сразу как на ладони видно: что за чем следует, что будет , если ... и т.п. Конечно, с приходом опыта такие схемы в голове автоматически возникают и воплощать их в графике не обязательно, хотя для сложных случаев - не возбраняется. А как помогает, когда работаешь с чужой прогой или со своей, прочно забытой !
Вот я накропал.
Изображение
И когда появилась ясность, когда нет ведущих в никуда или приходящих ниоткуда связей - кодирование становится крайне простым, им могут заниматься даже лошади - хоть на АСМе, хоть на Фортране, хоть на ЛИСПе. И не надо будет оглашать форумные окрестности горестными стенаниями : я все делаю правильно, а оно не работает !
Вложения
alg.JPG
(23.16 КБ) 874 скачивания
Изображение
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Jack_A писал(а):Прежде чем выяснять, как это будет выглядеть в коде, стоит определиться, как это будет выглядеть в голове.
Целых 2 страницы пытаемся понять, что у человека в голове - бесполезно ! На вопросы не отвечает, молчит как рыба, только свои мысли сюда выкладывает, как будто тут экстрасенсы собрались.
AVK
Потрогал лапой паяльник
Сообщения: 349
Зарегистрирован: Сб окт 20, 2007 14:12:03

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

Сообщение AVK »

А вот такой прикол.
Есть два положительных числа. Как самым простым способом вычислить разницу между ними?
Ну так то понятно, вычитаем одно из другого и результат берем по модулю. Но чтоб без модуля.
Без подключения math.h
На данный момент я определяю какое число больше и потом вычитаю из большего меньшее.
Мож как попроще можно?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

А куда уж проще. Тут либо

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

if (a > b)
  abs = a - b;
else
  abs = b - a;
либо

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

abs = a - b;
if (abs < 0)
  abs = -abs;
Часто для получения модуля применяют макросы вроде

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

#define ABS(X) ((X) > 0 ? (X) : (-X))
, но это не всегда идеальный вариант (двойное вычисление одного и того же, хотя при оптимизации компилятор может это учитывать).
Реклама
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

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

sub r1,r2
sbrc r1,7
neg r1
6 байт, 3 такта на 8-битные числа. Трудно придумать что-то оптимальнее.
Реклама
AVK
Потрогал лапой паяльник
Сообщения: 349
Зарегистрирован: Сб окт 20, 2007 14:12:03

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

Сообщение AVK »

WiseLord писал(а):А куда уж проще. Тут либо

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

if (a > b)
  abs = a - b;
else
  abs = b - a;
Ну я так и делаю, значит на этом и остановимся.
fatall_error
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Ср сен 01, 2010 07:24:48

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

Сообщение fatall_error »

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

Линия INT0 через кнопку на землю. Выставлено на любое изменение на INT0. (пробовал и на спад)
Соответственно прозвонил все провода. Где обшибка не пойму.

GICR|=0b01000000;
MCUCR=0x01;
MCUCSR=0;
GIFR=0b01000000;

Прерывание срабатывает и само собой в течении времени. Брал щуп от вольтметра подносил к контакту на INT0 - срабатывает. Через кнопку на землю никак.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

GICR|=0b01000000;
MCUCR=0x01;
MCUCSR=0;
GIFR=0b01000000;
Где форматирование? Что за магические числа? Почему они не описаны по-человечески?
Неужели так трудно написать GICR |= (1<<INT0); ? Со всеми остальными строчками поступите аналогично.
Каким образом на выводе должен появляться высокий уровень? Внутренняя подтяжка, внешняя или перекидной контакт?
fatall_error
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Ср сен 01, 2010 07:24:48

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

Сообщение fatall_error »

COKPOWEHEU писал(а):
GICR|=0b01000000;
MCUCR=0x01;
MCUCSR=0;
GIFR=0b01000000;
Где форматирование? Что за магические числа? Почему они не описаны по-человечески?
Неужели так трудно написать GICR |= (1<<INT0); ? Со всеми остальными строчками поступите аналогично.
Каким образом на выводе должен появляться высокий уровень? Внутренняя подтяжка, внешняя или перекидной контакт?

Я конечно не сильно в AVR разбираюсь, только начинаю. Про какую внутреннюю подтяжку Вы спрашиваете?


Расписываю:
MCUCR выставлен на любое измененние состояния INT0
MCUCSR=0; отключил INT2
GIFR = (1<<INTF0)

У меня CVA даже при автоматической компиляции проекта выдает все в шеснадцетиричной форме, поэтому я написал в двоичной.
Что еще расписать чтобы понятнее было?


Чего непонятно пишу говорите, я правда не силен на расписывания, но ответ хочется получить, как ни парадоксально это звучит, так что телепаты помогите )))
Ну ведь SSуко в proteus'e все работает...
Последний раз редактировалось fatall_error Чт дек 17, 2015 21:19:33, всего редактировалось 1 раз.
fatall_error
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Ср сен 01, 2010 07:24:48

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

Сообщение fatall_error »

АГА все заработало, в итоге настройки записаны правильно.
Когда замыкал INT0 просто на землю или +5v ничего не происходило, замети что когда косаюсь пальцем контакта срабатывает прерывание. Посадил резистор между землей и питанием и включил INT0 между резистором и +5v& все работает.
Подскажите пожалуйста эти грабли нормальные или нет?
fatall_error
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Ср сен 01, 2010 07:24:48

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

Сообщение fatall_error »

COKPOWEHEU писал(а):
GICR|=0b01000000;
MCUCR=0x01;
MCUCSR=0;
GIFR=0b01000000;
Где форматирование? Что за магические числа? Почему они не описаны по-человечески?
Неужели так трудно написать GICR |= (1<<INT0); ? Со всеми остальными строчками поступите аналогично.
Каким образом на выводе должен появляться высокий уровень? Внутренняя подтяжка, внешняя или перекидной контакт?


На днях контроллеры Parsec настраивал, когда начал рассказывать как выставлял адреса: 000100 000101 - на меня как на идиота смотрели, так что обзывайтесь что уж я начинаю привыкать. Мне лишь бы помогли...
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

fatall_error писал(а): Я конечно не сильно в AVR разбираюсь, только начинаю. Про какую внутреннюю подтяжку Вы спрашиваете?
В AVR можно программно подключить "резистор" сопротивлением 50-100 кОм между любой линией ввода-вывода и питанием. Это и называется внутренним подтягивающим резистором или подтяжкой. Очень удобно для подключения кнопок - минимум внешних деталей. Но сопротивление великовато, поэтому в реальной схеме возможны ложные срабатывания и стоит ставить внешние резисторы. Он включается когда выставлены DDRx=0; PORTx=1;
fatall_error писал(а): У меня CVA даже при автоматической компиляции проекта выдает все в шеснадцетиричной форме, поэтому я написал в двоичной.
Что еще расписать чтобы понятнее было?
Вот поэтому автогенераторы кода - зло. Вместо кода получается нечитаемая каша. Как будто так сложно заглянуть в даташит и выставить нужные биты вручную. Вообще, везде, где используются отдельные биты, лучше их расписывать битовыми операциями и сдвигами. Разумеется, это не относится к регистрам данных - UDR, SPDR и т.п. - там по смыслу, обычно десятичное или шестнадцатеричное число.
В данном случае хорошо было бы расписать:

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

GICR |= (1<<INT0); // разрешаем прерывание INT0
// в оригинале почему-то (1<<ICS00), что недопустимо для INT0
MCUCR = (1<<ICS01);  // прерывание INT0 по спаду
MCUCSR = 0;
GIFR = 0b01000000; // сбрасываем флаг прерывания
Да, вместе с комментариями - как минимум это покажет, что вы разбираетесь что делаете. Ну и покажет, чего хотели добиться. Только не надо оставлять комментарии в стиле КО - они бесполезны.
fatall_error писал(а): Кстати подключил INT0 в разрез между +5 и землей(через резистор) срабатывает прерывание, но выкидывает (прерывание выставил по спаду)
Что значит "выкидывает"? Может в теле прерывания накосячено?
Посадил резистор между землей и питанием и включил INT0 между резистором и +5v& все работает.
Сопротивление вывода в режиме входа крайне велико, поэтому потенциал на нем зависит от чего угодно. Если у=коммутируете на землю и отпускаете кнопку - там остается уровень земли. Если потом замкнете еще раз - ничего не изменится. Тоже самое с питанием. А вот если подтянуть к питанию - при отключенной кнопке на выводе будет лог.1, при замыкании кнопки - лог.0, а при отпускании емкость ввода быстро зарядится через резистор обратно до напряжения питания.
fatall_error
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Ср сен 01, 2010 07:24:48

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

Сообщение fatall_error »

Спасибо большое, что уделили внимание. Действительно все заработало.
Выкидывало потому что в процедуре прерывания я указывал проверку if (PINВ.2==0) тогда выход - соответственно я вылетал из процедуры сразу.

Я бы хотел:

при нажатии кнопки "меню" вызывается прерывание и я хочу чтобы при ее повторном нажатии (уже в процедуре прерывания) я выходил из этой процедуры

Может натолкнете на мысль как бы это реализовать?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Отлавливать фронты сигналов, а не уровни.
Я заводил для этого проверку всех клавиш в бесконечном цикле либо по прерыванию от таймера для защиты от дребезга. Дальше сравнивал их состояние с предыдущим сохраненным состоянием. Если какая-то кнопка была отпущена (лог.1) а стала нажата (лог.0) - обработать ее.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

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

Сообщение dm211 »

Что-то не могу вывести минусовую температуру на семисегментник, на LCD и др. 7-сегм. раньше удавалось без проблем, а тут при минус 1= выводит 255, при -2= 254 и т.д. Не могу понять в чём дело :dont_know: и как это исправить?

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

/*****************************************************
22.12.2015
Chip type               : ATtiny85
AVR Core Clock frequency: 8 MHz
*****************************************************/

#include <tiny85.h>
#include <ds18b20.h>
#include <delay.h>

#define SLK   PORTB.2   // CLK
#define MOSI  PORTB.0   // DIN
#define CS    PORTB.1   // LOAD

unsigned char devices, temper;
unsigned int tik;
unsigned char rom_codes[1][9];

flash char sim(char number){ char temp;
 switch (number) { 
   case 0:   temp = 126; break;
   case 1:   temp = 48;  break;
   case 2:   temp = 109; break;
   case 3:   temp = 121; break;
   case 4:   temp = 51;  break;
   case 5:   temp = 91;  break;
   case 6:   temp = 95;  break;
   case 7:   temp = 112; break;
   case 8:   temp = 127; break;
   case 9:   temp = 123; break;
   case 'F': temp = 71;  break;
   case 'U': temp = 62;  break;
   case 'P': temp = 103; break; 
   case 'H': temp = 55;  break;
   case 'A': temp = 119; break; 
   case 'C': temp = 78;  break;
   case 'E': temp = 79;  break; 
   case '*': temp = 99;  break;
   case '-': temp = 1;   break;
                 }
    return temp; 
}

void write(char data, char adress)
{     unsigned char i;     
  CS=0; #asm("nop")       
       for(i=0;i<8;i++){       
       if(adress & 0x80){ MOSI = 1;}
       else { MOSI = 0; }
         #asm("nop") //shift
         SLK=1;
         #asm("nop")
         SLK=0;  
         adress <<= 1;   
       }      
       
       for(i=0;i<8;i++){        
       if(data & 0x80){ MOSI = 1; }
       else { MOSI = 0; }
         #asm("nop") //shift
         SLK=1;
         #asm("nop")
         SLK=0;  
         data <<= 1;   
       }         
            #asm("nop")
            CS=1;                            
}

// Очистить(погасить) дисплей
void clear(){write(0, 8); write(0, 7); write(0, 8); write(0, 6); write(0, 5); write(0, 4); write(0, 3); write(0, 2); write(0, 1);}            

void indication(){
       write(0, 8);       
       write(0, 7);                                             
       write(0, 6);                             
       write(sim(temper/10%10), 5);
       write(sim(temper%10), 4);        
       write(0, 3);                          
       write(0, 2);
       write(0, 1);
              
       //write(znak1 | DP, 5);  // DP-это точка            
                }

void main(void){
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

DDRB=0x07;

write(1,0x0c);   // on
write(7,0x0b);   // 8 digit 
write(1,0x0f);   // Тест дисплея
delay_ms(100); 
write(0,0x0f);   // Отключить тест
write(5,0x0a);   // Яркость

devices=w1_search(0xf0,rom_codes);
clear(); 

while (1){
      temper=ds18b20_temperature(&rom_codes[0][0]);
      delay_ms(100);
      indication();
      delay_ms(100);                                                     
      }
}
Изображение
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 953
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

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

Сообщение GARMIN »

Всё дело в объявлениях:

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

unsigned char temper;
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

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

Сообщение dm211 »

char temper; и signed char temper; тоже не помогают.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

1)печатайте через printf
2)используйте библиотечные функции abs и fabs для получения положительных чисел
3)изучите как в Си кодируются числа со знаком и составьте правильный алгоритм преобразования
4)и наконец из школьной математики:
если n<0 то
n*(-1) > 0
Останется только дорисовать минус.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

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

Сообщение dm211 »

Полстраницы кода зачем я давал-хз :dont_know: ... если цифра 255 < нуля, то оно минус адин я пробовал,но не катит..
Конкретный ответ нужен, именно такой. :write:
Ответить

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