Страница 1 из 1

Вопрос по LCD

Добавлено: Чт мар 26, 2015 19:26:21
sirha
Подскажите пожалуйста почему не выводит на LCD переменную S ?

:(

именно с дробными числами нет арифметики( , на дисплее 0 вместо числа

подаю импульсы на вход INT1 (10 гц)

УЗНАЮ частоту

дальше делю 1 на частоту ,узнаю период (0.1 сек)


а вод умножая его на число 10 получаю на дисплее 0 :( как так


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


#include <mega8.h>
#include <delay.h>


#asm                             
    .equ __lcd_port=0x12 
#endasm 

#include <lcd.h>
#include <stdio.h>
 
 float t;
int i = 0, freq=0,s; 
char lcd_buf[33];
 
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i++;       
}
 
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
 freq=i; 
 i=0; 
 TCNT1H=0x00;
 TCNT1L=0x00;   
}


void main(void)
{
TIMSK=0x10;
TCCR1B=0x05;
OCR1AH=0x1E;
OCR1AL=0x85;
GICR=0x80;
MCUCR=0x0C;
DDRB=0x01;
lcd_init(16);
#asm("sei")
while(1)

{      
   
      
 t=(1/freq);
 s=t*10;


   
   
sprintf(lcd_buf,"%d",s); 

lcd_clear();
lcd_puts(lcd_buf);
delay_ms(20);
                }

}






Re: Вопрос по LCD

Добавлено: Пт мар 27, 2015 08:59:53
eess9
Сделайте явное приведение типов данных:

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

t=(1/(float)freq);
 s=(int)(t*10);

Re: Вопрос по LCD

Добавлено: Пт мар 27, 2015 09:03:59
ARV
не надо делать приведения типов там, где не надо :)))
достаточно всего-навсего использовать правильную константу типа float

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

t=1.0/freq;

Re: Вопрос по LCD

Добавлено: Пт мар 27, 2015 10:20:00
sirha
Спасибо))

все заработало

ARV

А что значит правильную float?

я ведь и так обозначил

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

float t;
работает вот так

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

t=(float)1/freq

Re: Вопрос по LCD

Добавлено: Сб мар 28, 2015 08:35:47
misyachniy
sirha писал(а):Спасибо))
А что значит правильную float?
Компилятор C манипулирует с данными не так как человек.
Для человека 1 и 1,0 одно и то же.
Для компьютера 1 может занимать 1,2,4,8 байт если объявлен как целочисленное.
Для float - 4 байта, для double - 8 байт.

При целочисленном вычислении числа меньше 1 отбрасываются.

В данном конкретном случае обе переменные в правой части целочисленные.
В AVR, по моему, intзанимает два байта.
Компилятор делает целочисленное деление и остаток отбрасывает - получается 0.
Так называемое "антипереполнение".

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

Выражение "1.0" и "(float)1" эквивалентны.

Re: Вопрос по LCD

Добавлено: Сб мар 28, 2015 17:40:14
ARV
я бы не согласился, что 1.0 и (float)1 эквивалентные записи. смысл первой записи в то, что мы задаем константу типа float, а смысл второй несколько иной: мы принудительно преобразовываем константу типа int к типу float. результат действительно одинаковый, но смысл все-таки разный. образно говоря, это как выйти в дверь или выскочить в окно - в обоих случаях окажемся снаружи, однако через дверь как-то все-таки правильнее...

Re: Вопрос по LCD

Добавлено: Сб мар 28, 2015 19:06:29
misyachniy
ARV писал(а):я бы не согласился, что 1.0 и (float)1 эквивалентные записи. смысл первой записи в то, что мы задаем константу типа float, а смысл второй несколько иной: мы принудительно преобразовываем константу типа int к типу float. результат действительно одинаковый, но смысл все-таки разный. образно говоря, это как выйти в дверь или выскочить в окно - в обоих случаях окажемся снаружи, однако через дверь как-то все-таки правильнее...
Согласен "в лоб" и "по лбу" имеют разный смысл ;-)

Re: Вопрос по LCD

Добавлено: Вс мар 29, 2015 00:04:14
sirha
вообщем буду писать 1.0))))

спс :)