Измерить длину импульса

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Измерить длину импульса

Сообщение Gisteresis »

Не очень понял вопроса.
Чтобы не выводить по одной букве, там есть функция sprintf, вы сами же пишите об этом.
Эта функция выводит на экран текст по формату (параметр функции). (честно говоря только теорию знаю, пока не довелось использовать)

Как записать в программе.
Перевести в секунды.
Для этого создаем доп переменную например
int A;
В коде пишем
A=[число в микросекундах или в чем там у вас] / 1000;
Так же создаем переменную для литров
float L;
Пишем
L=0,0025/(1/A);
(Я правильно понял 1/A?)
Реклама
kk042fjv
Грызет канифоль
Сообщения: 261
Зарегистрирован: Ср авг 01, 2012 10:45:42

Re: Измерить длину импульса

Сообщение kk042fjv »

Чтобы не выводить по одной букве, там есть функция sprintf,[/quote]

пробовал так сделать:

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

unsigned char buf[20];

snprintf(buf,20, " %.01d", PulseClocks);
lcd_gotoxy(0,0);
lcd_puts(buf);
На экране высветилось %.01d

А чтоб перевести в секунды так получится?(я правильно понял)

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

int A;

A=PulseClocks / 1000000;
Реклама
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Измерить длину импульса

Сообщение Gisteresis »

http://mega-avr.ucoz.ru/publ/function_s ... o/1-1-0-11

Попробуйте для начала формат попроще сделать, может он его не понял.

PulseClocks какого типа у вас? Int?

Да, вы поняли правильно. (насчет орфографии. А насчет математики не знаю, какая там у вас формула. Но, да, чтобы перевести из микросекунд в секунды, очевидно нужно поделить на миллон.)
kk042fjv
Грызет канифоль
Сообщения: 261
Зарегистрирован: Ср авг 01, 2012 10:45:42

Re: Измерить длину импульса

Сообщение kk042fjv »

Gisteresis писал(а): PulseClocks какого типа у вас? Int?
unsigned long PulseClocks;
Реклама
Эиком - электронные компоненты и радиодетали
kk042fjv
Грызет канифоль
Сообщения: 261
Зарегистрирован: Ср авг 01, 2012 10:45:42

Re: Измерить длину импульса

Сообщение kk042fjv »

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

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

unsigned char OverflowC;//счётчик переполнений для таймера 1
unsigned int EdgeR, EdgeF;//время переднего фронта и заднего фронта
unsigned long PulseClocks;//количество тактовых импульсов внутри импульса на входе ICP

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
                OverflowC++;//инкрементируется количество переполнений  
}

interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
    //Блок для измерения длительности импульса
    if(PINB.0) //если на входе захвата 1 (передний фронт ПОЛОЖИТЕЛЬНОГО импульса)
    {
        EdgeR = (unsigned int)ICR1L+((unsigned int)ICR1H << 8);           //запоминаем значениие счётчика 
        TCCR1B &= ~(1<<ICES1);  //устанавливаем прерывание по спадающему фронту импульса
		OverflowC = 0;          //обнуляем количество переполнений счётчика
	}
	else                        //если на входе захвата 0 (задний фронт ПОЛОЖИТЕЛЬНОГО импульса) 
	{
	    EdgeF = (unsigned int)ICR1L+((unsigned int)ICR1H << 8);           //запоминаем значение счётчика
		TCCR1B |= (1<<ICES1);   //устанавливаем прерывание по нарастающему фронту импульса
		PulseClocks = (unsigned long)EdgeF - (unsigned long)EdgeR + ((unsigned long)OverflowC << 16);//вычисляем длительность импульса
        }
}

void main(void)
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: On
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x82;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

TIMSK=0x24;

lcd_init(16);
lcd_putsf("BK v1");
delay_ms(1500);
lcd_clear();

#asm("sei")

while (1)
      {
        lcd_gotoxy(1,1);
        lcd_putchar((PulseClocks/1000)+0x30);
        lcd_putchar(((PulseClocks%1000)/100)+0x30);                 
        lcd_putchar(((PulseClocks%100)/10)+0x30);
        lcd_putchar(((PulseClocks%100)%10)+0x30);
        lcd_putchar(0x20);
        lcd_putchar('u');
        lcd_putchar('s');
        delay_ms(500);
      }
}
Реклама
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Измерить длину импульса

Сообщение Gisteresis »

Ну чего там? Заработало?
kk042fjv писал(а):На экране высветилось %.01d
Если на экране появилась надпись такая же как написан у вас формат, это значит, что функция не смогла понять запись формата аргумента.

Если ничего не помогает, попробуйте перейти на более простые функции. SNprintf замените на более типовую Sprintf или просто printf.
Реклама
kk042fjv
Грызет канифоль
Сообщения: 261
Зарегистрирован: Ср авг 01, 2012 10:45:42

Re: Измерить длину импульса

Сообщение kk042fjv »

Gisteresis писал(а):Ну чего там? Заработало?
Никак не получается
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Измерить длину импульса

Сообщение Gisteresis »

kk042fjv писал(а):lcd_putchar((PulseClocks/1000)+0x30);
lcd_putchar(((PulseClocks%1000)/100)+0x30);
lcd_putchar(((PulseClocks%100)/10)+0x30);
lcd_putchar(((PulseClocks%100)%10)+0x30);
lcd_putchar(0x20);
lcd_putchar('u');
lcd_putchar('s');
В первых четырех строках у вас получается число, а функция принимает в качестве аргумента char (символ из таблицы символов).
Для правильного отображения необходимо полученное число преобразовать в строку. Ну или хотя бы в символ, этим занимаются функции itoa, ltoa. (По крайней мере так на ПК, повторяю для AVR такого еще не писал, но думаю не должно быть больших отличий).
Очень удобно в вашем случае формировать именно строку.
Примерно так:
sprintf(буфер строки, "%u%u%u", ((PulseClocks%1000)/100), ((PulseClocks%100)/10), (PulseClocks%10));
Но такие пляски удобны при работе с сегментными индикаторами, в вашем случае гораздо удобнее формировать строку напрямую:
sprintf(буфер строки, "%u", PulseClocks);

Далее буфер посылаем в LCD.

За правильность написания не ручаюсь, давно не использовал.
kk042fjv
Грызет канифоль
Сообщения: 261
Зарегистрирован: Ср авг 01, 2012 10:45:42

Re: Измерить длину импульса

Сообщение kk042fjv »

Gisteresis писал(а):
Примерно так:
sprintf(буфер строки, "%u%u%u", ((PulseClocks%1000)/100), ((PulseClocks%100)/10), (PulseClocks%10));
Но такие пляски удобны при работе с сегментными индикаторами, в вашем случае гораздо удобнее формировать строку напрямую:
sprintf(буфер строки, "%u", PulseClocks);
Вроде что то стало получаться, первую часть я высчитал.

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

  snprintf(buf,20, "%d", PulseClocks);
          lcd_gotoxy(0,0);
            lcd_puts(buf);
            
        A = 0.0025/(1000000/PulseClocks);
          snprintf(buf,20, "%.6f", A);
          lcd_gotoxy(0,1);
            lcd_puts(buf);
            
        B = (A*29)*3600;    
            snprintf(buf,20, "%.3f »/Аac", B);
              lcd_gotoxy(0,2);
                lcd_puts(buf);
Так и не понял где была ошибка.
Вам спасибо огромное за помощь, без Вас бы не смог, так же oleg110592 хорошо помог.
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Измерить длину импульса

Сообщение Gisteresis »

:beer: :solder:

Еще пишут, что не все компиляторы нормально переваривают snprintf.

Если хотите благодарить плюсуйте или минусуйте, посты, карму... что считаете нужным.
Котэ любит плюсы :tea:
Ответить

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