Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

PIC24HJ и С30 - IC и UART прекъсвания
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=13997
Страница 1 от 1

Автор:  User [ Пон Авг 24, 2015 10:12 am ]
Заглавие:  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 ти ден...

Автор:  valioman [ Пон Авг 24, 2015 10:35 am ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

За да си сигурен ,че процесора не променя променливата когато я изпращаш просто си направи дублираща такава , която ще присвоиш преди изпращането по UART-a .
Не знам дали е излишно да говоря да тестваш с глобални static променливи.

Автор:  Gogo [ Пон Авг 24, 2015 12:15 pm ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

Забрани прекъсванията на input compare модулите точно преди printf();
Ако заработи, сам ще се сетиш каква е причината.
Вальо ти е казал същото по друг начин.

Автор:  User [ Пон Авг 24, 2015 9:59 pm ]
Заглавие:  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 период

Автор:  User [ Пон Авг 24, 2015 10:27 pm ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

пробвах всякакъв вариант на променливите.
пробвах да напиша unsigned int to ascii ред по ред, с идеята да са атомични инструкции...

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


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

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

Автор:  4040 [ Пон Авг 24, 2015 11:05 pm ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

Със симулация или дебъгер да огледаш състоянието след прекъсването или преди изпращането...

Автор:  valioman [ Вто Авг 25, 2015 12:14 am ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

А сигурен ли си, че кепчъра не се е***ва? Дай му най висок приоритет а uarta го наври в главния main и го пускай след сетване на флагче от T1.

Автор:  User [ Вто Авг 25, 2015 1:22 am ]
Заглавие:  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 ;

Автор:  speedblue [ Вто Авг 25, 2015 4:29 am ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

User написа:
__delay_us(10) ;

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

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

Автор:  valioman [ Вто Авг 25, 2015 8:32 am ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

Чакай малко ... много странно ползваш кепчъра ... не знам как е конкретно при този пикльо но доколкото знам кепчъра има настройка за кой фронт да действа ... та ако искаш да мериш период на импулс .. нагласяш си да речем първо да "хваща" на вдигащ фронт .. след това в прекъсването зануляваш таймера и настройваш кепчъра да хване на падащ фронт и при следващото прекъсване четеш резултата на таймера в някоя променлива и те така. тея delay не са ти нужни в прекъсване ... все пак мериш .. нужно е всичко да мине възможно най-бързо .
По неписан закон в прекъсване се слага най-малко времееемък код.

Автор:  User [ Вто Авг 25, 2015 8:49 am ]
Заглавие:  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 друга банка няма пролем.)

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

Автор:  sparkybg [ Вто Авг 25, 2015 10:07 am ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

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


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

Автор:  speedblue [ Вто Авг 25, 2015 7:38 pm ]
Заглавие:  Re: PIC24HJ и С30 - IC и UART прекъсвания

Цитат:
for ( i = 0; i < 16; i++ ) {
putchar(DDstr[i]);
__delay_us(10);
}

А този __delay_us(10)?

Автор:  User [ Сря Авг 26, 2015 2:18 pm ]
Заглавие:  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 ;
}

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

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

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/