| Микроконтролери и електроника 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 ред по ред, с идеята да са атомични инструкции...
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 прекъсвания | |||||||||
Може би няма връзка, но все пак - в един друг компилатор категорично е забранено в прекъсване да пъхаш горната команда. Причината е, че ако извън прекъсването ползваш компилаторския __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 прекъсвания | |||||||||
Компилатора прави подпрограмата, обработваща прекъсването, да си запазва и възстановява всички използвани регистри, а не всички въобще. Ако от нея викаш други подпрограми вече е под въпрос какво точно прави, ама не помня да съм имал някакви драми от това точно като се ровичках последно с 24-ка. |
||||||||||
| Автор: | speedblue [ Вто Авг 25, 2015 7:38 pm ] | |||||||||
| Заглавие: | Re: PIC24HJ и С30 - IC и UART прекъсвания | |||||||||
А този __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/ |
|