CodeVision AVR в вопросах и ответах
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
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
В смысле "Да, указана"?Telek писал(а):Да работает.
Поскольку задержки в 1-wire есть и по 5 микросекунд (200КГц всего), то на таких клоках нужно переписывать ф-ции - 5uS = 1 NOP.Telek писал(а):...или самому переписывать функции обмена, или ...
И дело даже не в том, что датчик чего-то не поймет, а в том, что м/к начнет слушать шину уже после того, как датчик успеет выдать на неё половину ответа.
P.S. Что значат слова "повышать частоту микропроцессора на время обмена с датчиком"?
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
Во-первых это работает только на некоторых тиньках, во-вторых - новая частота устаканивается не сразу... не проще сразу выбрать нужную частоту (переписав функции на NOP'ы вместо DELAY'ев) и экономить энергию только Idle'ом?Telek писал(а):на время когда обмен с датчиком не нужен, и проц ... находится в полуспячке типа Idle ...
Yellow Tiger писал(а):Во-первых это работает только на некоторых тиньках, во-вторых - новая частота устаканивается не сразу... не проще сразу выбрать нужную частоту (переписав функции на NOP'ы вместо DELAY'ев) и экономить энергию только Idle'ом?Telek писал(а):на время когда обмен с датчиком не нужен, и проц ... находится в полуспячке типа Idle ...
Я посмотрел датащиты на 2313. В Идле при 1МГц внутренний генератор(ниже уже с датчиком траблы) - потребление около 0.4мА, а при частоте 128кГц внутренний генератор- уже 0.025мА(все указываю для 5в... при меньших напряжениях - меньше, но график линейный и пропорции будут примерно одинаковые)... т.е. батареек хватит примерно до 16 раз дольше в идиальных условиях(но даже увеличение срока службы от одного комплекта в 5-6раз -это уже гут)
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Помогите понять что не так?
Вот функция которую я написал чтобы принимала данные
Но у меня есть подозрение, что она не всегда работает...
Вот функция которую я написал чтобы принимала данные
Код: Выделить всё
unsigned char ReadUSI(void)
{
USISR=0x40;
while( !USISR.6 )
USICR.0=1;
return USIDR;
}
Но у меня есть подозрение, что она не всегда работает...
Нашел одну проблему... пытаюсь понять как решить ее.. может кто посоветует?
Передаю данные по USART интерфейсу данные передаются... НО если передаваемое число равно "0" он не передает его
В Датащите приведен такой пример:
Моя реализация в CodeVisionAVR:
Листинг
Передаю данные по 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 писал(а):Как вы определили что не передает ?
Просто, вставил последовательность цифр (я ее знал) на Компе по Пору начал получать данне приходят все кроме Нулей.
Думал ошибка тогда в цикле отправлял цифры от 0 до 200 все приходят кроме "0"
(Хммм, а может вы правы и у меня на компе программа интерфейса занимается самопроизвольном и выкидывает 0 коды)
Здравствуйте. Ситуация такая. До этого писал на ассемблере. Сейчас понадобилось использовать датчик температуры 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 выдаёт ноль. Пробовал на ассемблере с датчиком поработать. Не получилось. Ну вот. Кто-нибудь может сталкивался с одной из моих проблем?:)
#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 выдаёт ноль. Пробовал на ассемблере с датчиком поработать. Не получилось. Ну вот. Кто-нибудь может сталкивался с одной из моих проблем?:)
Тут это. Оказалось, что датчик припаяли вверх ногами. GND к 5 вольтам подключили, а питание к земле. Сейчас буду перепаивать. Но всё-таки с тем, что после формирования файла прошивки в CodeVision на ножках висит 1 вольт, вместо положенных примерно пяти, нужно разбираться. Не бывало ни у кого такого?
Очень часто бывает у не читавших "Устройство микроконтроллера AVR" на русском языке.алёша писал(а): Не бывало ни у кого такого?
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Если в датчике сигнальный вход имеет пару защитных диодов, то при таком включении, которое избрал ты, эти диоды оказались открыты, и один из них коротил выход контроллера на землю. На открытом диоде падает как раз около вольта (там не совсем диод, но сейчас это не суть).алёша писал(а):Оказалось, что датчик припаяли вверх ногами. GND к 5 вольтам подключили, а питание к земле. ... Но всё-таки ... после ... CodeVision на ножках висит 1 вольт, вместо положенных примерно пяти,...
А теперь мой вопрос - как могло такое быть, чтобы эти диоды, включенные в проводящем направлении, не коротили выход в том случае, когда единичка выводилась в порт кодом, писанным на ассемблере? Что-то тут не так...
Код визард CVAVR создает переменную char getchar(void){} - это символ,поступающий на UART.Это вот для этого кода подходит- Мне нужно сделать действие при поступлении определенной строки на вход,а не символа,что то типа вместо getchar() конечно должно быть что то другое.Подскажите,как это сделать.
И еще- если нужно послать АТ команду на сотовый,например этот-,то мешают кавычки рядом с буквой е, выдает ошибку, как быть в такой ситуации, в АТ командах этих кавычек очень много .
Код: Выделить всё
if(getchar()=='7')PORTB.0=1;Код: Выделить всё
if(getchar()=="RING")PORTB.0=1;И еще- если нужно послать АТ команду на сотовый,например этот-
Код: Выделить всё
putsf("at+ckpd="e" ");- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17