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

Обсуждаем контроллеры компании Atmel.
Telek
Встал на лапы
Сообщения: 115
Зарегистрирован: Пт май 23, 2008 23:59:37
Откуда: Москва

Сообщение Telek »

функции 1wire на частотах ниже 1МГц работают в CVAVR? Пытаюсь использовать на частоте 0.5 и 0.25МГц - обмен идет с какими-то немереными интервалами. Датчик соответственно ничего не понимает.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Сообщение BCluster »

А на более высоких частотах у вас все работает? С тем же кодом? Прерывание запрещаете перед работой с 1wire?
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Telek писал(а):функции 1wire на частотах ниже 1МГц ... обмен идет с какими-то немереными интервалами.
А в проекте указана частота, на которой работает мелкоконтроллер?
Telek
Встал на лапы
Сообщения: 115
Зарегистрирован: Пт май 23, 2008 23:59:37
Откуда: Москва

Сообщение Telek »

Yellow Tiger писал(а):
Telek писал(а):функции 1wire на частотах ниже 1МГц ... обмен идет с какими-то немереными интервалами.
А в проекте указана частота, на которой работает мелкоконтроллер?


Да работает.

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

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

.MACRO __DELAY_USB
   LDI  R24,LOW(@0)
__DELAY_USB_LOOP:
   DEC  R24
   BRNE __DELAY_USB_LOOP
   .ENDM

При частотах тиже 1МГц, компилятор генерит код, где @0 уже равен 0(количество циклов задержки).
Соответственно далее от этого 0 отнимается 1 (DEC R24) и сравнивается с нулем... в итоге после отнятия 1 получаем 255 и далеше огребаем недетскую задержку в 255 циклов... поэтому датчик смотрит на это дело с широко раскрытыми глазами и не вкуривает что от него хотят.

В общем получается или самому переписывать функции обмена(но запаса по задержкам уже практически нет, т.е. сильно частоту все равно не уронить) или повышать частоту микропроцессора на время обмена с датчиком.
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Telek писал(а):Да работает.
В смысле "Да, указана"?

Telek писал(а):...или самому переписывать функции обмена, или ...
Поскольку задержки в 1-wire есть и по 5 микросекунд (200КГц всего), то на таких клоках нужно переписывать ф-ции - 5uS = 1 NOP.
И дело даже не в том, что датчик чего-то не поймет, а в том, что м/к начнет слушать шину уже после того, как датчик успеет выдать на неё половину ответа. :)

P.S. Что значат слова "повышать частоту микропроцессора на время обмена с датчиком"?
Telek
Встал на лапы
Сообщения: 115
Зарегистрирован: Пт май 23, 2008 23:59:37
Откуда: Москва

Сообщение Telek »

Yellow Tiger писал(а):В смысле "Да, указана"?

Ага


Yellow Tiger писал(а):P.S. Что значат слова "повышать частоту микропроцессора на время обмена с датчиком"?


Т.е. например на время когда обмен с датчиком не нужен, и проц не загружен, или, например, находится в полуспячке типа Idle снижать частоту засылкой значения в предделитель:

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

CLKPR=0x80;
CLKPR=0x0X; где X коэффициент предделителя 

А потом, когда нужен обмен повышать частоту до нормальной... например:

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

CLKPR=0x80;
CLKPR=0x00;

с соответствующими остановками и запуском таймеров на время смены частоты.

Вобщем как-то так видется. Сейчас пытаюсь сделать простой термометр с питанием на батарейках. Так как батарейки нужно беречь - бужу термометр на несколько секунд для показа температуры по кнопке. Захотелось дальше поизвращаться и приделать запоминалку мин/макс значений - а стало быть термометр должен уже сам иногда просыпаться для замеров. Соответственно засыпать он должен уже в режиме Idle(чтобы таймер не спал). А потребление в режим Idle зависит от частоты - соответственно ее нужно максимально снизить, но снижение не позволяет обмениваться с датчиком... поэтому буду мутить в сторону изменения частоты на время измерений или показа температуры. А все остальное -будет микропроцессор будет тупить на малых оборотах и ждать таймера(для замеров) или нажатия кнопки(для показа результатов).
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Telek писал(а):на время когда обмен с датчиком не нужен, и проц ... находится в полуспячке типа Idle ...
Во-первых это работает только на некоторых тиньках, во-вторых - новая частота устаканивается не сразу... не проще сразу выбрать нужную частоту (переписав функции на NOP'ы вместо DELAY'ев) и экономить энергию только Idle'ом? :?
Telek
Встал на лапы
Сообщения: 115
Зарегистрирован: Пт май 23, 2008 23:59:37
Откуда: Москва

Сообщение Telek »

Yellow Tiger писал(а):
Telek писал(а):на время когда обмен с датчиком не нужен, и проц ... находится в полуспячке типа Idle ...
Во-первых это работает только на некоторых тиньках, во-вторых - новая частота устаканивается не сразу... не проще сразу выбрать нужную частоту (переписав функции на NOP'ы вместо DELAY'ев) и экономить энергию только Idle'ом? :?

Я посмотрел датащиты на 2313. В Идле при 1МГц внутренний генератор(ниже уже с датчиком траблы) - потребление около 0.4мА, а при частоте 128кГц внутренний генератор- уже 0.025мА(все указываю для 5в... при меньших напряжениях - меньше, но график линейный и пропорции будут примерно одинаковые)... т.е. батареек хватит примерно до 16 раз дольше в идиальных условиях(но даже увеличение срока службы от одного комплекта в 5-6раз -это уже гут)
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Ну-ну. Охота - пуще неволи. :)))
DeltaQ
Открыл глаза
Сообщения: 45
Зарегистрирован: Чт окт 30, 2008 13:26:18

Сообщение DeltaQ »

Помогите понять что не так?
Вот функция которую я написал чтобы принимала данные

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

unsigned char ReadUSI(void)
{
    USISR=0x40;
    while( !USISR.6 )
       USICR.0=1;
    return USIDR;
}

Но у меня есть подозрение, что она не всегда работает...
DeltaQ
Открыл глаза
Сообщения: 45
Зарегистрирован: Чт окт 30, 2008 13:26:18

Сообщение DeltaQ »

Нашел одну проблему... пытаюсь понять как решить ее.. может кто посоветует?

Передаю данные по USART интерфейсу данные передаются... НО если передаваемое число равно "0" он не передает его :(

В Датащите приведен такой пример:

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

void USART_Transmit( unsigned char data )
{
  /* Wait for empty transmit buffer */
   while ( !( UCSRA & (1<<UDRE)) );
  /* Put data into buffer, sends the data */
   UDR = data;
}


Моя реализация в CodeVisionAVR:

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

void TransUSB(unsigned char Data)
{//Передача данных в USB порт
    while ( !UCSRA.5 );
    UDR = Data;
}


Листинг

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

_TransUSB:
_0x1B:
000080 9b5d   SBIS 0xB,5
000081 cffe   RJMP _0x1B
000082 81e8   LD   R30,Y
000083 b9ec   OUT  0xC,R30
000084 9621   ADIW R28,1
000085 9508   RET
Аватара пользователя
ikarab
Опытный кот
Сообщения: 828
Зарегистрирован: Пн мар 16, 2009 21:40:57
Контактная информация:

Сообщение ikarab »

Как вы определили что не передает ?
DeltaQ
Открыл глаза
Сообщения: 45
Зарегистрирован: Чт окт 30, 2008 13:26:18

Сообщение DeltaQ »

ikarab писал(а):Как вы определили что не передает ?

Просто, вставил последовательность цифр (я ее знал) на Компе по Пору начал получать данне приходят все кроме Нулей.

Думал ошибка тогда в цикле отправлял цифры от 0 до 200 все приходят кроме "0"

(Хммм, а может вы правы и у меня на компе программа интерфейса занимается самопроизвольном и выкидывает 0 коды)
алёша
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Чт апр 30, 2009 17:16:31

Сообщение алёша »

Здравствуйте. Ситуация такая. До этого писал на ассемблере. Сейчас понадобилось использовать датчик температуры DS18b20. Соответственно решил написать прошивку на C. Проблема в следующем. В CodeVision когда записываю единицу в порты, то на некоторых ножках висит не 5 вольт, а примерно 1. Причём когда пишу на ассемблере и прошиваю PonyProg(хотя я и после компиляции в codevision прошиваю понипрогом) то всё нормально, везде где записано 1 там висит пять вольт. Честно сказать, меня это очень удивляет. Дай мне задание сделать так чтобы выводить на ножку 1 вольт вместо пяти, пользуюясь только возможностями самого контроллера, меня бы поставило это в тупик. Хотя кажется та ножка, к которой подключен датчик функционирует нормально. Вот. Ну и соответственно датчик тоже не откликается. Возможно это и связано с тем что некоторые ножки так странно выводят единицу в виде 1 вольта. А если не связано, то хотел бы узнать. в схеме используется внутренний генератор с частотой 1мгц(контроллер соответственно ATmega16). Достаточно ли такой частоты, или нужно подключить внешний резонатор? Вот код(нашёл в инете):



#include <mega16> //библиотека ввода\вывода
#include <delay> //библиотека задержки
#asm //сообщаем куда подключен датчик
.equ __w1_port=0x18; PORTB
.equ __w1_bit=0
#endasm
#asm //сообщаем куда подключён экран
.equ __lcd_port=0x12
#endasm
#include <lcd> //библиотека для LCD
#include <1wire> //библиотека работы с 1Wire
#include <ds18b20> //библиотека для работы с датчиком ds18b20
#include <stdio> //ненаю что за библиотека, но без неё неполучается
char lcd_buffer[33]; //масив с данными для экрана
void main(void)
{
unsigned char devices; //переменная в которой количество присоеденённых датчиков
int temp; //переменная для хранения температуры
lcd_init(16); //инициилизация LCD, и говорим что он на 16 символов
devices=w1_init(); //ищим датчики
while(devices>0) //бесконечный цикл, если датчик подключон
{
temp=ds18b20_temperature(0); //читаем температуру
if (temp>1000){ //если датчик выдаёт больше 1000
temp=4096-temp; //отнимаем от данных 4096
temp=-temp; //и ставим знак "минус"
}
sprintf(lcd_buffer,"t=%i.%u\xdfC",temp,temp%1); //записуемв масив для экрана температуру и всё такое
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd_buffer); //выводим масив на LCD
delay_ms(500); //ждём 500мс
};
}



Соответственно функция w1_init выдаёт ноль. Пробовал на ассемблере с датчиком поработать. Не получилось. Ну вот. Кто-нибудь может сталкивался с одной из моих проблем?:)
алёша
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Чт апр 30, 2009 17:16:31

Сообщение алёша »

Тут это. Оказалось, что датчик припаяли вверх ногами. GND к 5 вольтам подключили, а питание к земле. Сейчас буду перепаивать. Но всё-таки с тем, что после формирования файла прошивки в CodeVision на ножках висит 1 вольт, вместо положенных примерно пяти, нужно разбираться. Не бывало ни у кого такого?
Аватара пользователя
ikarab
Опытный кот
Сообщения: 828
Зарегистрирован: Пн мар 16, 2009 21:40:57
Контактная информация:

Сообщение ikarab »

алёша писал(а): Не бывало ни у кого такого?
Очень часто бывает у не читавших "Устройство микроконтроллера AVR" на русском языке. :lol:
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

алёша писал(а):Оказалось, что датчик припаяли вверх ногами. GND к 5 вольтам подключили, а питание к земле. ... Но всё-таки ... после ... CodeVision на ножках висит 1 вольт, вместо положенных примерно пяти,...
Если в датчике сигнальный вход имеет пару защитных диодов, то при таком включении, которое избрал ты, эти диоды оказались открыты, и один из них коротил выход контроллера на землю. На открытом диоде падает как раз около вольта (там не совсем диод, но сейчас это не суть).
А теперь мой вопрос - как могло такое быть, чтобы эти диоды, включенные в проводящем направлении, не коротили выход в том случае, когда единичка выводилась в порт кодом, писанным на ассемблере? Что-то тут не так... 8) :)))
алёша
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Чт апр 30, 2009 17:16:31

Сообщение алёша »

Спасибо за ответы. Датчик заработал. Все остальные проблемы с CodeVision это исключительно экспоненциальная зависимость кривизны моих рук от координаты на руке:)
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Код визард CVAVR создает переменную char getchar(void){} - это символ,поступающий на UART.Это вот для этого кода подходит-

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

if(getchar()=='7')PORTB.0=1;
Мне нужно сделать действие при поступлении определенной строки на вход,а не символа,что то типа

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

if(getchar()=="RING")PORTB.0=1;
вместо getchar() конечно должно быть что то другое.Подскажите,как это сделать.
И еще- если нужно послать АТ команду на сотовый,например этот-

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

putsf("at+ckpd="e" ");
,то мешают кавычки рядом с буквой е, выдает ошибку, как быть в такой ситуации, в АТ командах этих кавычек очень много .
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

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

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