реклама на сайте
подробности

 
 
> Согласование переменных разных типов
GoodNews
сообщение Feb 3 2010, 22:22
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Если есть одна переменная у которой тип "char", вторая переменная типа "uint16_t" на которой реализован счётчик. Как их представить в переменной типа "char" для последующей записи в порт LCD?

МК - mega16
Компилятор - AVR-GCC
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
volodya
сообщение Feb 4 2010, 06:36
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344



Цитата(GoodNews @ Feb 4 2010, 00:22) *
Если есть одна переменная у которой тип "char", вторая переменная типа "uint16_t" на которой реализован счётчик. Как их представить в переменной типа "char" для последующей записи в порт LCD?


Стандартное преобразование типов С :

Код
{
   char chValH, chValL;
   uint16 uiCnt;

   chValL = (char) (uiCnt);
   chValH = (char) (uiCnt >> 8);
}


далее далее старшую и младшую часть в порт. Если счетчик обновляется в прерывании то предусмотреть запрет прерывания во время чтения счетчика.


--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть"
"Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 4 2010, 07:44
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(GoodNews @ Feb 4 2010, 01:22) *
Как их представить в переменной типа "char" для последующей записи в порт LCD?
Вам - что, нужно получить последовательность символов, соответствующих значению счетчика? Тогда - функция sprintf. Ну, и поместить эту последовательность в переменную массив char'ов... Как-то так:
Код
uint16_t Cnt;
char Array[10];
sprintf(Array, "%d", Cnt);
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 4 2010, 08:54
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(Палыч @ Feb 4 2010, 09:44) *
Вам - что, нужно получить последовательность символов, соответствующих значению счетчика? Тогда - функция sprintf. Ну, и поместить эту последовательность в переменную массив char'ов... Как-то так:
Код
uint16_t Cnt;
char Array[10];
sprintf(Array, "%d", Cnt);

Я хотел взять некоторое значение, например 125,3876, добавить к нему текст (в а конкретно "MHz"), и всё это отправить в lcd_putdata() в соответствующую строку дисплея (запись в дисплей у меня реализована, выбор строк тоже). Вот функция записи в дисплей:
Код
void lcd_putchar(char data)
{    
        LCD_CTL |= LCD_RS; //Включаем режим обработки данных дисплеем (если бит инвертирован, то - обработка инструкций)
    LCD_PORT = data;
        lcd_strobe();
        LCD_CTL &= ~(LCD_RS|LCD_RW);
}
void lcd_putdata(uint8_t line, char* data)
{
    lcd_select_addr(line);
    while(*data)
    {
        lcd_busy();
        lcd_putchar(*data++);
    }
}
int main(void)
{
///
    lcd_init();
    lcd_putdata(1, "1234567890ABCDEF");
    lcd_putdata(2, "GHIJKLMNOPQRSTUV");
    lcd_putdata(3, "WXYZ!@#$%^&*()_+");
///
.....
}
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 4 2010, 09:05
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(GoodNews @ Feb 4 2010, 11:54) *
Я хотел взять некоторое значение, например 125,3876, добавить к нему текст (в а конкретно "MHz"), и всё это отправить в lcd_putdata() в соответствующую строку дисплея (запись в дисплей у меня реализована, выбор строк тоже).
Ну, так и воспользуйтесь функцией sprintf - это самый простой, но, правда, и самый затратный по памяти способ. Правда, я не понял как Вы из целого значения желаете получить "125,3876"? Если в целой переменной у Вас храниться частота в килогерцах, то более 65535 поместить в неё не удастся...

PS. Для переменной типа uint_t нужно использовать sprintf(Array, "%u", Cnt);
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 4 2010, 09:20
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(Палыч @ Feb 4 2010, 11:05) *
Ну, так и воспользуйтесь функцией sprintf - это самый простой, но, правда, и самый затратный по памяти способ. Правда, я не понял как Вы из целого значения желаете получить "125,3876"? Если в целой переменной у Вас храниться частота в килогерцах, то более 65535 поместить в неё не удастся...

PS. Для переменной типа uint_t нужно использовать sprintf(Array, "%u", Cnt);

Тут скорее надо float, я не подумал как-то. По памяти - я отрабатываю каждый модуль отдельно (LCD, kbd ...), а потом всё будет собрано для mega128.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 4 2010, 09:52
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(GoodNews @ Feb 4 2010, 12:20) *
Тут скорее надо float...
Необязательно. Подключение функции sprintf с поддержкой float "отъест" очень большой кусок памяти. Обычно, выгоднее иметь переменную типа int (unsigned int) или long (unsigned long), а при форматировании разбить на "целую" и "дробную" части. Как-то так:
Код
char Str[11];
unsigned int Fr;// Частота кГц
unsigned int M, K; // МГц и кГц
M= Fr / 1000U;
K= Fr - M * 1000U; // или так K= Fr % 1000U;
sprintf(Str, "%2u,%03u МГц", M, K);
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 4 2010, 13:18
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(GoodNews @ Feb 4 2010, 14:20) *
Тут скорее надо float, я не подумал как-то.
Да, да. Сначала во float преобразовать, а потом sprintf-ом на LCD вывести, и для этого mega на xmega поменять, потому что размера ОЗУ не хватает. sad.gif Вы бы погуглили вначале по теме BCD преобразования и использования fixed point арифметики. На форуме уже раз сто мусолили эти темы.
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 4 2010, 16:12
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(rezident @ Feb 4 2010, 15:18) *
Да, да. Сначала во float преобразовать, а потом sprintf-ом на LCD вывести, и для этого mega на xmega поменять, потому что размера ОЗУ не хватает. sad.gif Вы бы погуглили вначале по теме BCD преобразования и использования fixed point арифметики. На форуме уже раз сто мусолили эти темы.

так планируется в дальнейшем использование mega128, просто mega16 доступнее в плане цены и если убью при прошивке (STK600 можно найти только на eBay), вот поэтому на mega16 испытываю модули по отдельности (lcd и пр.).
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 5 2010, 12:09
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Решил попробовать использовать такой вариант кода (всё-таки float):
Код
char* get_freq(uint32_t Fr, uint8_t type)
{
    static char Str[16];
    static float tmp;
    tmp = Fr / 1000U;
    switch(type)
    {
        case (0): //KHz
            sprintf(Str, "%4.6fKHz", (double)tmp);
            return Str;
            break;
    /*    case (1): //MHz
            sprintf(Str, "%4.6fMHz", (double)tmp);
            return Str;
            break;
    */
    }
    return 0;
}
int main(void)
{
    uint32_t i = 560000;
    lcd_init();
/*...*/
    lcd_putdata(1, get_freq(i, 0));
/*...*/
}

Проблема в sprintf(Str, "%4.6fKHz", (double)tmp), так как в итоге ничего не отображается (просто пустая строка). Почему не хочет показывать, ведь вроде функцию вызвал правильно?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 5 2010, 13:31
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(GoodNews @ Feb 5 2010, 15:09) *
Почему не хочет показывать, ведь вроде функцию вызвал правильно?
Функция printf (и еже с ними) ну очень прожорлива до памяти. Чтобы как-то это обойти, обычно, поставляется несколько вариантов библиотек, в которых от самых "худых" функций (поддерживают только сhar и int) до самых навороченных (это Ваш вариант - поддерживают плавучку). В зависимости от используемой среды разработки нужно как-то указать: какой вариант использовать...

Цитата(GoodNews @ Feb 5 2010, 15:09) *
Решил попробовать использовать такой вариант кода (всё-таки float):
Код
char* get_freq(uint32_t Fr, uint8_t type)
{
    static char Str[16];
    static float tmp;
    tmp = Fr / 1000U;
    /*...*/
}
Такое вычисление tmp - никуда не годится! Правильно записать tmp = Fr / 1000.0;

Цитата(GoodNews @ Feb 5 2010, 15:09) *
Код
sprintf(Str, "%4.6fKHz", (double)tmp);
Преобразование к double - абсолютно лишнее
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 5 2010, 14:02
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(Палыч @ Feb 5 2010, 15:27) *
Функция printf (и еже с ними) ну очень прожорлива до памяти. Чтобы как-то это обойти, обычно, поставляется несколько вариантов библиотек, в которых от самых "худых" функций (поддерживают только сhar и int) до самых навороченных (это Ваш вариант - поддерживают плавучку). В зависимости от используемой среды разработки нужно как-то указать: какой вариант использовать...

Такое вычисление tmp - никуда не годится! Правильно записать tmp = Fr / 1000.0;

smile.gif среда разработки - Vim, набор библиотек - avr-libc, компилятор - avr-gcc, библиотека stdio.h из комплекта avr-libc.

Цитата(Палыч @ Feb 5 2010, 15:31) *
Преобразование к double - абсолютно лишнее

без него ругается, что tmp - float, а %4.6f - double!

Сообщение отредактировал GoodNews - Feb 5 2010, 14:03
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Feb 5 2010, 17:17
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



http://www.avrfreaks.net/index.php?name=PN...;highlight=utoa
http://www.avrfreaks.net/index.php?name=PN...337&start=0
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/
http://qlwlp.blogspot.com/
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 5 2010, 17:48
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(ukpyr @ Feb 5 2010, 19:17) *

спасибо, попытаюсь разобраться. но всё равно не понятно, почему в моём случае не работает именно так, как я написал (и как заставить работать в таком виде...)?
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Feb 5 2010, 19:06
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



Цитата
Проблема в sprintf(Str, "%4.6fKHz", (double)tmp), так как в итоге ничего не отображается (просто пустая строка). Почему не хочет показывать, ведь вроде функцию вызвал правильно?
а что вы передаете в lcd_putdata (что возвращает get_freq) ?
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 18:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01483 секунд с 7
ELECTRONIX ©2004-2016