Отговори на тема  [ 14 мнения ] 
PIC24HJ и С30 - IC и UART прекъсвания 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение PIC24HJ и С30 - IC и UART прекъсвания
процесора е PIC24HJ128GP206, компилатор C30, 32 MHz Fcy
измервам 4 поредици (дефазирани на 90 градуса) милисекундни импулси, период ~100 - 20 ms
формирани са хубаво с LM339, подвам ги на IC1 до IC4, timebase TMR2
използвам capture и по преден и по заден фронт, прекъсване, проверка в 0 или 1 е входа, запис на стойноста,
пресмятане на продължителността на импулса.
Приоритета на прекъсванията на кепчърите е 5
дотук добре.....

Трябва и да се изпращат измерените стойности по UART ~ 5-10 пъти в секунда.
Правя си прекъсване през 100 мс с таймер 1 (приоритет 1). копирам 4 те измерени unsigned int стойности в локални променливи и printf, %04x .
Откъм PC то има USB-UART MCP2200.

Проблемът е следния:
когато прекъсване на кепчърите се застъпи с изпращане на данни, се объркват една, две, три или и 4 те изпратени стойности.

за да съм сигурен че импулсите са измерени правилно,
в прекъсването по падащ фронт, вдигах пин, пусках TMR5, като в PR5 записвам измерената дтийност, пресъсването на TMR5 сваля пина. 1:1 повторен импулс веднага след измерения.
Осцилоскопа има синхронизация по продължителност на импулс (>, <, = , !=). Различни няма.

пробвах изпращането да не е в прекъсване на таймер а да е в main loop, с __delay_ms(100)
пробвах различни от 9600 baudrates
пробвах да заменя printf с sprintf в масив и после putchar
пробвах със собствена функция която преобразува unsigned int стойностите в ascii
пробвах различни нива на оптимизация

все същото....
Не знам какво се обърква, прекъсването на кепчър модул е около 3 микросекунди.
(гледах го с осцилоскопа - вдигам пин в началото, свалям го при изход от прекъсването)
Не ми се вярва тези микросекундни прекъсвания да разсинхронизират милисекундните байтове на UARTA.
Може би като отиде в прекъсване на IC проца не запазва работните регистри...т.е. ако кепчъра е прекъснал преобразуване unsigned int в ascii, при връщане в регистрите които са използвани има бог знае що ?

Давайте идеи... Не се справям с това 3 ти ден...


Пон Авг 24, 2015 10:12 am
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 17, 2005 5:07 pm
Мнения: 813
Местоположение: Сливен
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
За да си сигурен ,че процесора не променя променливата когато я изпращаш просто си направи дублираща такава , която ще присвоиш преди изпращането по UART-a .
Не знам дали е излишно да говоря да тестваш с глобални static променливи.

_________________
Код:
while(true);


Пон Авг 24, 2015 10:35 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 24, 2005 11:41 pm
Мнения: 1049
Местоположение: Pz
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
Забрани прекъсванията на input compare модулите точно преди printf();
Ако заработи, сам ще се сетиш каква е причината.
Вальо ти е казал същото по друг начин.


Пон Авг 24, 2015 12:15 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
част от кода

volatile unsigned int BT1, BT2, BT3, BT4 ; // измерени и сметнати стойности на продължителности на импулсите в ISR на IC1 - IC4 (по 2us/count)
static unsigned int LB1, LB2, LB3, LB4 ; // тези стойности ще се изпращат по UART, спомагателна променлива
static char DDstr[16] ; // спомагателен масив, байтове ascii на LB1-LB4

.....

void _ISR _T1Interrupt() { // таймер 1 прави прекъсване на 100 мс. пращам стойностите.

LB1=BT1 ;
LB2=BT2 ;
LB3=BT3 ;
LB4=BT4 ;

//sprintf(DDstr, "%04x%04x%04x%04x", LB1, LB2, LB3, LB4) ;
//printf("%04x%04x%04x%04x", LB1, LB2, LB3, LB4) ;
DDstr[0]=LB1>>12 ;
DDstr[1]=(LB1>>8) ; DDstr[1]&=0x0F ;
DDstr[2]=(LB1>>4) ; DDstr[2]&=0x0F ;
DDstr[3]=(LB1) ; DDstr[3]&=0x0F ;

DDstr[4]=LB2>>12 ;
DDstr[5]=(LB2>>8) ; DDstr[5]&=0x0F ;
DDstr[6]=(LB2>>4) ; DDstr[6]&=0x0F ;
DDstr[7]=(LB2) ; DDstr[7]&=0x0F ;

DDstr[8]=LB3>>12 ;
DDstr[9]=(LB3>>8) ; DDstr[9]&=0x0F ;
DDstr[10]=(LB3>>4) ; DDstr[10]&=0x0F ;
DDstr[11]=(LB3) ; DDstr[11]&=0x0F ;

DDstr[12]=LB4>>12 ;
DDstr[13]=(LB4>>8) ; DDstr[13]&=0x0F ;
DDstr[14]=(LB4>>4) ; DDstr[14]&=0x0F ;
DDstr[15]=(LB4) ; DDstr[15]&=0x0F ;

putchar('G') ;
putchar('G') ;
putchar('G') ;
putchar('G') ; // GGGG начало на пакета

for ( i = 0; i < 16; i++ ) { if (DDstr[i]<0xA) DDstr[i]+=0x30 ; else DDstr[i]+=0x37 ; }

for ( i = 0; i < 16; i++ ) { putchar(DDstr[i]) ; __delay_us(10) ; }

printf("QQ \n") ; // край на пакета

_T1IF=0 ;
}

пакети

GGGG09C509C5BBBF09C5QQ
GGGGBBBF09C509C509C5QQ
GGGG09C5BBC009C509C4QQ
GGGG09C509C509C5BBBFQQ
GGGG09C5BBBF09C509C5QQ
GGGG09C509C509C5BBBFQQ
GGGG09C509C5BBBF09C5QQ
GGGGBBBF09C509C409C5QQ
GGGG09C5BBBF09C509C5QQ
GGGG09C409C509C509C5QQ
GGGG09C509C509C509C5QQ
GGGG09C509C509C509C4QQ
GGGG09C509C509C409C5QQ
GGGG09C509C509C509C5QQ
GGGG09C509C509C409C5QQ
GGGG09C309C609C509C5QQ
GGGG09C509C509C409C4QQ

5 ms импулси, 40 ms период


Пон Авг 24, 2015 9:59 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
пробвах всякакъв вариант на променливите.
пробвах да напиша unsigned int to ascii ред по ред, с идеята да са атомични инструкции...

Прикачени файлове:
DS0003.gif
DS0003.gif [ 5.97 KiB | Прегледано 3350 пъти ]


CH2 е входа на компаратора, СН1 е изхода на контролния пин, повторен импулс от TMR5
като задам синхронизация на скопа !=5.00 го чаках две цигари време - не, няма такива.

сигурно целия ми проблем е за "АКАДЕМИЯ"
сигурно пропускам нещо изключително азбучно, но с PIC24 съм работил два пъти, а ми харесаха...


Пон Авг 24, 2015 10:27 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Сря Фев 04, 2015 8:11 pm
Мнения: 610
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
Със симулация или дебъгер да огледаш състоянието след прекъсването или преди изпращането...


Пон Авг 24, 2015 11:05 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 17, 2005 5:07 pm
Мнения: 813
Местоположение: Сливен
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
А сигурен ли си, че кепчъра не се е***ва? Дай му най висок приоритет а uarta го наври в главния main и го пускай след сетване на флагче от T1.

_________________
Код:
while(true);


Вто Авг 25, 2015 12:14 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
UART-а в main loop с флагче от таймер 1 - същата работа...
но се оказва че кепчъра наистина се е-ава... може би.
#define inB1 _RD8 // also IC1
.........
void _ISR _IC1Interrupt() {
__delay_us(1) ; // за да съм сигурен че фронта е минал , BT1r нарастващ фронт - заден, BT1f падащ фронт - преден
if (inB1==1) BT1r=IC1BUF ; else BT1f=IC1BUF ;
if (BT1r>=BT1f) BT1=BT1r-BT1f ; else BT1=(PR2-BT1f) + BT1r ;

if (inB1==1) {_LATF5=1 ; T3CONbits.TON=0 ; PR3=BT1 ; TMR3=0 ; T3CONbits.TCKPS=0b10 ; T3CONbits.TON=1 ; }
// _LATF5=1 - контролния пин, _LATF5=0 от таймер 3. това само за 1 кепчър
// BT1=0x0BC1 ;
_IC1IF=0 ;
}

като им сложа да върнат 0x0BC1 - 0x0BC4 съответно никаква грешка в пакета.

Как тогава да си обясня осцилограмата на контролния пин ???
Няма и няма различни от измерените и после изработени импулси.

или компилатора е оптимизирал и е изхвърлил пресмятанията за BT1 - BT4... Приемайки ги за константи...
volatile unsigned int BT1, BT2, BT3, BT4 ;


Вто Авг 25, 2015 1:22 am
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Нед Фев 25, 2007 1:41 am
Мнения: 276
Местоположение: София
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
User написа:
__delay_us(10) ;

Може би няма връзка, но все пак - в един друг компилатор категорично е забранено в прекъсване да пъхаш горната команда. Причината е, че ако извън прекъсването ползваш компилаторския __delay..... , а прексването викне същата функция повторно настава мазало.

Друго - ако ти се занимава пробвай масива с данни който се получава за пращане да го пращаш чрез прекъсването на самия UART и накрая ще си спре само като прати всичко. Кой го знае какво там му се омазва, някои процесори имат не малко бъгове по UART-овете при някакви странни стечения на обстоятелствата.


Вто Авг 25, 2015 4:29 am
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 17, 2005 5:07 pm
Мнения: 813
Местоположение: Сливен
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
Чакай малко ... много странно ползваш кепчъра ... не знам как е конкретно при този пикльо но доколкото знам кепчъра има настройка за кой фронт да действа ... та ако искаш да мериш период на импулс .. нагласяш си да речем първо да "хваща" на вдигащ фронт .. след това в прекъсването зануляваш таймера и настройваш кепчъра да хване на падащ фронт и при следващото прекъсване четеш резултата на таймера в някоя променлива и те така. тея delay не са ти нужни в прекъсване ... все пак мериш .. нужно е всичко да мине възможно най-бързо .
По неписан закон в прекъсване се слага най-малко времееемък код.

_________________
Код:
while(true);


Вто Авг 25, 2015 8:32 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
Същото и без __delay_us(1) ;
По новите PIC24 са с dedicated timer за всеки IC , OC
Този може да ползва само TMR2 или TMR3 като timebase. За всичките му 8 кепчъри и 8 компеъри.

Гледах го снощи с debuger и breakpoints преди и след всяко прекъсване.
При изход винаги във w0 - w3 има различни стойности от това което е било преди прикъсването.
Понякога и във w8.
Оказва се наистина за академия работата.
Придобил съм погрешната представа че всеки компилатор се грижи за това, да запази текущото състяние а не само
PC и още някой и друг регистър.
(Toва от 8051 derivatives и Keil C51, той всичко си пазеше. (A, B, R0-R7) Ако ползва същата банка прекъсването.
Ако му зададеш да ползва друга банка, само A и B, R0-R7 друга банка няма пролем.)

Сега трябва да направя да запазва работните регистри и да ги връща същите на изход.


Вто Авг 25, 2015 8:49 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Авг 23, 2005 12:02 pm
Мнения: 3070
Местоположение: София
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
User написа:
Придобил съм погрешната представа че всеки компилатор се грижи за това, да запази текущото състяние а не само
PC и още някой и друг регистър.


Компилатора прави подпрограмата, обработваща прекъсването, да си запазва и възстановява всички използвани регистри, а не всички въобще. Ако от нея викаш други подпрограми вече е под въпрос какво точно прави, ама не помня да съм имал някакви драми от това точно като се ровичках последно с 24-ка.


Вто Авг 25, 2015 10:07 am
Профил ICQ
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Нед Фев 25, 2007 1:41 am
Мнения: 276
Местоположение: София
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
Цитат:
for ( i = 0; i < 16; i++ ) {
putchar(DDstr[i]);
__delay_us(10);
}

А този __delay_us(10)?


Вто Авг 25, 2015 7:38 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 10, 2007 3:49 pm
Мнения: 97
Мнение Re: PIC24HJ и С30 - IC и UART прекъсвания
fixed
... глупава грешка в кода при кепчърите. Срамна работа.

void _ISR _IC2Interrupt() {

if (inB2==1) { BT2r=IC2BUF ; if (BT2r>=BT2f) BT2=BT2r-BT2f ; else BT2=(PR2-BT2f) + BT2r ; }
else BT2f=IC2BUF ;

_IC2IF=0 ;
}

благодаря на хората които се опитаха да помогнат.

темата май е за коша.


Сря Авг 26, 2015 2:18 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 14 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 0 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни