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

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

Сообщение Gisteresis »

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

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

Сообщение 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;
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

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

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

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

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

Сообщение kk042fjv »

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

Сообщение 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);
      }
}
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

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

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

Сообщение kk042fjv »

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

Сообщение 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.

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

Сообщение 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 хорошо помог.
Друг Кота
Аватара пользователя
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Сообщение Gisteresis »

:beer: :solder:

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

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

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