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


