S

PIC Timer прерывания

41 сообщение в этой теме

Здравствуйте, у меня вопрос, может кто знает. Мне нужно сделать прерывания на один раз на 1 секунду.

прерывания на каждую секунду, работает должным образом;

 

char led = 0; 
main(void)
{
	... 

(вместо while(1), поставил	while(!led))
while(!led) T1CONbits.TON = 0;

}
void __attribute__ ((interrupt, no_auto_psv)) _T1Interrupt( void )
{
 	led = 1;
	LATAbits.LATA0 = 1 - LATAbits.LATA0;
	IFS0bits.T1IF = 0;
}

 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

попробуйте еще раз сформулировать вопрос....

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Простите за мой русский

Я хотел сделать прерывания только на один раз. Я сконфигурировал таймер на 1 секунду, после каждой секунды включаетса светодиод, сечйас. Но я  желаю чтоба он включался только один рас , после того, как одну секунду прошлого, a потом выключить прерывание.  Когда прошло именно одна  секунда, светодиод включится и прерывания  остоновилось .

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ничего не понял. Нарисуйте ручкой на листе бумаги диаграмму работы светодиода.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 минут назад, StasRadeon сказал:

Я хотел сделать прерывания только на один раз.

ну так что мешает запретить прерывание от таймера по истечении 1секунда в самом прерывании? или выключить таймер?

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Прерывание делается , но очень быстро, не через одной секунды включаются лед, а через нескколько микросекунд , это значит что он сразу идиот в вечный цикл, это когда я  зделал так :

(вместо while(1), поставил	while(!led))
while(!led) T1CONbits.TON = 0;

а когда while (1) , он работает как прежде , через каждой одной секунду включается светодиод.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 часов назад, StasRadeon сказал:

Прерывание делается , но очень быстро, не через одной секунды

просто не правильно настроен таймер. В МК несколько таймеров, есть 8-битные, есть 16... Плюс в зависимости от тактовой частоты МК у него максимальное время срабатывания разное. Скачайте, например, pic timer calculator

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

сдается мне вы не совсем понимаете как работает прерывание и таймеры.

1. при стандартной частоте 4МГц невозможно получить время переполнение таймера1 более 0,524288с

2. в обработчике прерывания отсутствует проверка флага от таймер1, МК может входить в прерывание по другим прерываниям , какие из них разрешены/запрещены в вашем коде не видно.

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я работаю сейчас с dspic33fj128mc802 . я хочю читать 8000 значения от ацп в секунду, это значит 1/8000 = 125us преаривание.  Timer3 сконфигурирован чтобы делал преаривание каждые 125us. но я получаю около 3000 значения.  может кто то посмотреть на код и скажет где я ошибся.

Oscillator Configuration with PLL activ : 40Mhz

Timer 3 Interrupt : 125 us

ADC : 10 bit mode ;

UART Baudrate  : 128.000

          Databits:8

          Stop bits: 1

Voice.rar

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

как это Timer 3 Interrupt : 125 us

соотносится с

Цитата

void initTmr3()
{
    TMR3 = 0x0000;                    // Clear TMR3
    PR3=49;//49;//99;
    IFS0bits.T3IF = 0;                // Clear Timer 3 Interrupt Flag
    IEC0bits.T3IE = 0;                // Clear Timer 3 interrupt enable bit
    T3CONbits.TON=1;
}

?????

и еще вы уверены что по дефолту компилятор воспринимает числа как десятичные????

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

правильно -> PR3=4999;

FCY = FOSC/2 = 40 Mhz
T = PR3 * 1 / (FCY / Prescaler)


FOSC = 80 MHz
T = 1 s                        => PR3 ≈ 4999
Prescaler = 256

Таймер 3 устанавливается чтоба перезапустить преобразование АЦП  через каждые 125 us

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, StasRadeon сказал:

Prescaler = 256

где это видно?

 

Только что, StasRadeon сказал:

T = 1 s                        => PR3 ≈ 4999

ну а у тебя что в коде????

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Правильно , я когда поставил код забыл что менял PR3 = 49; извените .

Изменено пользователем StasRadeon
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Т.е. всё работает ? 
 

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Работает , но неправильно, не знаю где смотреть, в чём я ошибся.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Правильно , так :

FCY = FOSC/2 = 40 Mhz
T = PR3 * 1 / (FCY / Prescaler)


FOSC = 80 MHz
T = 1 s                        => PR3 ≈ 4999
Prescaler = 1:1

 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

:wall:

каким образом период  Т =1s

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

правильно заметили ,
T = 0,125 us ;

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну так в чем проблема?

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я просто сечйас работал на тот элемент , чтобъ зделать одно прерывания через одной секунды и всё, для тово чтобы посмотреть сколько преобозовании будет от ацп и попутался .

Проблема в том , по моим расчетом, я должон принимать в hyperterminal (serial) , около 8000 преобозовании от ацп в одной секунды , но я получаю около 3000

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что то я не пойму, откуда Вы такие цифры берёте ?

Частота периферии (аля тактовая для таймера) = 40 МГц.
По Вашим цифрам :
40000000/256(prescaler) = 156250 Гц (частота инкремента таймера)
156250 Гц / 5000(PR2+1) = 31.25
В итоге, мы получили 31,25 Гц на выходе таймера. Причём тут 8 КГц ? 

 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
9 часов назад, StasRadeon сказал:

правильно заметили ,
T = 0,125 us ;

А как это у Вас так все наивно?

Получаете данные с периодом в 125 мкс (если конечно исправили PR3), а передаете через UART с рейтом в 9600, то есть два байта (одно слово) за 2 мс.

:lol:

Даже если Вы включите DMA, то на 8000 отсчетов его не хватит. В этом контроллере двухпортовая память DMA занимает только 1024 слова.

 

 

Изменено пользователем my504
2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 минут назад, my504 сказал:

Итого время преобразования ПО МИНИМУМУ: 13*76=988 мкс

0.988мкс,,, или нет?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да именно так, но я сначала не посмотрел код, а потому исправил ответ. Товарисч имеет каждые 125 мкс два байта и тут же в ISR по АЦП шлет их у УАРТ с рейтом в 9600...

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ха, а слона то и не заметили :lol:
Я, почему то, подумал, что он ежесекундно передаёт то, что насчитал. Т.к. в первом посте что-то про секунду проскакивало...

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу