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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Synergetik
Встал на лапы
Сообщения: 117
Зарегистрирован: Чт фев 28, 2008 23:54:35
Откуда: Воскресенск, МО
Контактная информация:

Сообщение Synergetik »

Можно попробовать такую хитрость:
http://pid.by.ru/z5.htm писал(а):char sign='+'; //датчик дал положительное число
int temp=578; //число с датчика темп. LM75
printf("temp = %c%i.%u C\r\n",sign,temp/10,temp%10);

На терминал ПК будет выведено : temp = 57.8 C

В Вашем случае предварительно дробное число следует умножить на нужную степень числа 10.
Mr.Denis
Прорезались зубы
Сообщения: 220
Зарегистрирован: Пт авг 07, 2009 22:06:49
Откуда: Россия, Москва

Сообщение Mr.Denis »

Сейчас всё сделал заново, в свойствах проекта стоит: (s)printf Features = float, width, precision.
Вот весь код:

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

#include <mega8>
#asm
   .equ __lcd_port=0x12 ;
#endasm
#include <lcd>
#include <stdio>
char lcd[31];
float q;
void main(void)
{
lcd_init(16);
q=2.5;
while (1)
      {
sprintf(lcd, "q=%i",q);
lcd_init(16);
lcd_gotoxy(0, 0); 
lcd_puts(lcd);
      };
}

Этот код выводит как результат: q=0

Хитрость это конечно хорошее, но надо попробовать решить без хитростей! :)
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

с формированием строки разобрался. теперь проблема в отсылке ее в ком порт. код в аттаче, но с этим кодом ком порт режет строки длиннее 12 символов. в чем может быть проблема? настройки: 9600, 8 бит данных, 1 стоповый, контроля четности нет.
Вложения
dialer.rar
(42.29 КБ) 228 скачиваний
Mr.Denis
Прорезались зубы
Сообщения: 220
Зарегистрирован: Пт авг 07, 2009 22:06:49
Откуда: Россия, Москва

Сообщение Mr.Denis »

Это условие: if(strlen(str)==11) выполняется только тогда когда количество символов в переменной str равно 11, и не как иначе.
Я так и не понял, для каких целей нужна эта строка strcat(number,str);?
Что вот эта строка обозначает(strncat(str,s1,1);)?
Если не прав, то поправьте!
Аватара пользователя
Synergetik
Встал на лапы
Сообщения: 117
Зарегистрирован: Чт фев 28, 2008 23:54:35
Откуда: Воскресенск, МО
Контактная информация:

Сообщение Synergetik »

Mr.Denis писал(а):

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

sprintf(lcd, "q=%i",q); 

А почему у Вас в sprintf выводной тип стоит "%i"? Для плавающей точке, по-моему, нужно "%f".
Mr.Denis
Прорезались зубы
Сообщения: 220
Зарегистрирован: Пт авг 07, 2009 22:06:49
Откуда: Россия, Москва

Сообщение Mr.Denis »

Вы были правы действительно нужно %f! Спасибо, теперь буду знать что от этого параметра многое зависит!
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

Mr.Denis писал(а):Это условие: if(strlen(str)==11) выполняется только тогда когда количество символов в переменной str равно 11, и не как иначе.
Я так и не понял, для каких целей нужна эта строка strcat(number,str);?
Что вот эта строка обозначает(strncat(str,s1,1);)?
Если не прав, то поправьте!


Сначала в строке str я формирую набранные цифры, накапливая их функцией strncat по одной, а затем, в строке number я формирую команду вида ATDXXXXXXXXXXX; где XXXXXXXXXXX - набранные цифры...
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

а условие if(strlen(str)==11) надо для того, чтобы выбрать только 11 цифр и начать формировать команду ATDXXXXXXXXXXX;
Mr.Denis
Прорезались зубы
Сообщения: 220
Зарегистрирован: Пт авг 07, 2009 22:06:49
Откуда: Россия, Москва

Сообщение Mr.Denis »

Если мне не изменяет память то, у меня была похожая проблемма!
Я её решал понижением скорости в приемнике.
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

Mr.Denis писал(а):Если мне не изменяет память то, у меня была похожая проблемма!
Я её решал понижением скорости в приемнике.


А я решил проблему увеличением скорости 8)
Mr.Denis
Прорезались зубы
Сообщения: 220
Зарегистрирован: Пт авг 07, 2009 22:06:49
Откуда: Россия, Москва

Сообщение Mr.Denis »

Молодец! А где ты увеличел скорость?
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

в code wizard сделал 19200 :)
Аватара пользователя
zanuda
Родился
Сообщения: 8
Зарегистрирован: Сб авг 08, 2009 20:46:09

Сообщение zanuda »

идем дальше :))

у меня есть кнопка, которая нажимается трубкой телефонной (весь девайс - это обычный дисковый телефон с модулем сим300ц :))) связаны по 232, набор номера и дозвон уже работает).
на этой кнопке (рычаг) висит прерывание int0, которое посылает модулю команду АТА ("снять трубку") при условии что есть входящий звонок (я повесил выходящий сигнал RI модуля на еще один вход мк). то есть сигнал АТА шлется при выполнении двух условий - поступает входящий звонок на модуль (1) и трубка в этот момент поднимается с аппарата (2). это у меня работает уже. как только абоненты соединены - сигнал RI пропадает. а теперь вопрос - как мне сделать так: когда трубка кладется на аппарат при разговоре ("заканчивается" int0) на модуль идет сигнал ATH ("отбой")? нужно чтобы отслеживалось 2 условия: 1 - идет разговор, 2 - пока еще выполняется прерывание.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Помогите,знатоки си,сам никак не могу додуматься- передаю на сотовый модем команду,например, AT+CSQ- возвращает ответ +CSQ:29,0 .Как сделать реакцию по приходящему ответу, типа- if (otvet=="+CSQ:29,0") делать что-то; Cимволы поочередно приходят в регистр UDR.
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

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

dm211 писал(а):Помогите,знатоки си,сам никак не могу додуматься- передаю на сотовый модем команду,например, AT+CSQ- возвращает ответ +CSQ:29,0 .Как сделать реакцию по приходящему ответу, типа- if (otvet=="+CSQ:29,0") делать что-то; Cимволы поочередно приходят в регистр UDR.
А никаких волшебств - накапливать символы в буфере, пока не придет конец строки, потом парсить пришедшую строку, затем действовать, согласно пришедшему ответу. Если парсить влом, то просто сравнивать строку в буфере с ожидаемыми строками, но тогда придется делать слишком много сравнений, типа:

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

if        (!strcmp(buf,"+CREG: 0,0"))  {
    ...
} else if (!strcmp(buf,"+CREG: 0,1"))  {
    ...
} else if (!strcmp(buf,"+CGREG: 0,0")) {
    ...
} else if (!strcmp(buf,"+CGREG: 0,1")) {
    ...
} else {
    ...
}
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Спасибо,но... Если накапливать в буфере,то буфер на сколько символов, ответ всегда разной длины приходит, и если например так написать-ничего не работает: if(buffer=="что-то")...
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Вот код:

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

#define RX_BUFFER_SIZE 100
char rx_buffer[RX_BUFFER_SIZE];
// Прерывание по приему символа в регистр  UDR
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA; //число из UCSRA- это регистр управления и статуса-состояния  USART
data=UDR;     //число из UDR  - это регистр для принимаемых данных.
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) //при безошибочном принятии данных
   {
   rx_buffer[rx_wr_index]=data;         //помещает принятый байт в буфер
   if (++rx_wr_index == RX_BUFFER_SIZE) //если==100
    rx_wr_index=0;                      // обнуляет индекс
   if (++rx_counter == RX_BUFFER_SIZE)  //если буфер переполнился
      {
      rx_counter=0;                     // Обнулить  счетчик принятых байтов в буфере
      rx_buffer_overflow=1;             // Установить флаг переполнения буфера
      };
   };

char getchar(void)
{
char data;
while (rx_counter==0);               //цикл ожидания поступления символа в буфер
data=rx_buffer[rx_rd_index];         //взять символ из буфера и поместить его в data
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0; // увел. индекса буфера на 1 и если результат будет равен размеру буфера - индекс обнуляется
#asm("cli")
--rx_counter;            // вычесть 1 из rx_counter
#asm("sei")
return data;             //функция вернет то что находится в переменной  data
}

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

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

dm211 писал(а):...буфер на сколько символов, ответ всегда разной длины приходит...
Буфер нужен размером N+1, где N - максимальная длина ожидаемой на приеме строки.
dm211 писал(а):так ... ничего не работает: if(buffer=="что-то")...
Разумеется - в Си нет ни строковых типов, ни строковых операций. Эквивалентных действий можно добиться применением strcmp(), как я показывал выше.
dm211 писал(а):Хотелось бы увидеть готовый рабочий код.
А здесь до готового кода - только gets() добавить. :)))
Прерывание помещает приходящие символы в буфер, getch() - достает их оттуда, а gets() - вызывает getch() (помещая результат в строку) пока не получит из неё символ конца строки. И всех делов. Правда, при таком подходе "в лоб" процессор будет впустую молотить все то время (минус время работы прерываний), пока идёт строка, но для первой версии и этого хватит.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

А вот так не проще ли ? :)))

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

int i=0,j=0;
char a[100];
if ((a[i]=='t')&&(a[i+1]=='h')&&(a[i+2]=='e'))

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

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

1. И много слов вы собираетесь таким способом распознавать? Изображение
2. Это такое же сравнение строки, как и strcmp() , только:
- с жестко вшитой в код строкой и
- с циклом, развернутым в линию.
3. Это сработает. Безусловно сработает. Но не только для строки "the", а и для всех строк, содержащих подстроку 'the' - "theorema","thertium","northern", и так далее...
Ответить

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