PIC interrupt / data access not working - Page 1
Forum section: electronics / general

author: Raven Luni
author_rank: Contributor
timestamp: July 23, 2018, 09:10:18 pm
content: Greetings,I'm attempting to make an aquarium light with some neopixels but part of the code refuses to work and it's got me stumped.What it does: Uses a PIC16F88 to drive a strip of 21 neopixels. There are 7 settings, the first 4 are plain white decreasing in brightness, the other 3 are shimmer effects which are achieved by scrolling colours copied from the data memory. This is the part which doesnt work. Everything else works as expected but the 3 later settings do nothing (just appear to be a copies of setting 4)It uses the TMR2 interrupt and polls for a button press on RA0 to change the setting. This works. The neopixel code works (since it displays the solid white values). For some reason its either not copying the data memory contents to the 'screen memory' (pointed at by FSR) or its not calling the display function (f1_main) from the interrupt. I cant find anything wrong with the code there so maybe another set of eyes might spot something. Here is the code (uses my own assembler but shouldnt be too different from mainstream ones):Code:; =======================================; Aquarium Light v0.1; (c) 2018 Peter Hanratty; =======================================include f:\picprog\lib\pic16f88_reg.inc; ---------------------------------------equfunc_count7equpix_numlights21equpix_numbytes63; ---------------------------------------equscreen_addr20hequpix_g70hequpix_r71hequpix_b72hequpix_bits73hequpix_bytes74hequfunc_current75hequfunc_select76hequtemp_s77hequtemp_d78hequtemp_c79hequtemp_b7ah; ---------------------------------------; Reset and interrupt vectorsorg000hgotoinit; ---------------------------------------org004hclrfstatus; Bank 0callf1_mainmovfporta, wmovwftemp_bbtfsstemp_b, 0callchangefuncmovftemp_b, wxorlw01hmovwffunc_selectbcfpir1, 1retfie; =======================================init:; (dont) Set oscillator (HS, 16 MHz)movlw20hmovwfstatus; Bank 1clrfosccon; Init PORTA (digital input)clrfanselmovlwffhmovwftrisa; Init PORTB (input, rb0=output)movlwfehmovwftrisbclrfstatus; Bank 0clrfportb; Enable Interruptmovlwc0h; GIE, PEIEmovwfintconbsfstatus, 5; Bank 1bsfpie1, 1; TMR2IE; Set up TMR2bcfpr2, 7; PR2 = 7fhclrfstatus; Bank 0movlw09h; Pre:4, Post:16, Offmovwft2con; Init first functionclrffunc_currentincffunc_current, fclrffunc_selectcallf1_init; Start TMR2bsft2con, 2gotomain; =======================================changefunc:btfscfunc_select, 0returnincffunc_current, fbtfssfunc_current, 3gotof1_initmovlw1movwffunc_currentgotof1_init; =======================================fillstrip:movlwscreen_addrmovwffsrmovlwpix_numlightsmovwfpix_bytesfillmem:movfpix_g, wmovwfindfincffsr, fmovfpix_r, wmovwfindfincffsr, fmovfpix_b, wmovwfindfincffsr, fdecfszpix_bytes, fgotofillmemreturn; =======================================colshuffle:; shuffle pixels alongmovlw3sublwpix_numbytesmovwftemp_caddlwscreen_addrmovwftemp_saddlw3movwftemp_ddecftemp_s, fdecftemp_d, fmovftemp_d, wmovwffsrmovfindf, wmovwfpix_bdecffsr, fmovfindf, wmovwfpix_rdecffsr, fmovfindf, wmovwfpix_gcolshuffle_loop:movftemp_s, wmovwffsrmovfindf, wmovwftemp_bmovftemp_d, wmovwffsrmovftemp_b, wmovwfindfdecftemp_s, fdecftemp_d, fdecfsztemp_c, fgotocolshuffle_loopmovlwscreen_addrmovwffsrmovfpix_g, wmovwfindfincffsr, fmovfpix_r, wmovwfindfincffsr, fmovfpix_b, wmovwfindfreturn; =======================================showpixels:; Shift out pixel information; Cycles: 19 per pixel + 35movlwscreen_addrmovwffsrmovlwpix_numbytesmovwfpix_bytesshowbyte:movlw8movwfpix_bitsmovfindf, wmovwftemp_sshowbit:btfsctemp_s, 7gotohighbitnopbsfportb, 0bcfportb, 0gotonextbithighbit:bsfportb, 0nopnopbcfportb, 0nextbit:rlftemp_s, fdecfszpix_bits, fgotoshowbitincffsr, fdecfszpix_bytes, fgotoshowbyte;movlw10;movwftemp_s;pixwait:; Delay for screen update;decfsztemp_s, f;gotopixwaitreturn; =======================================f1_init:movffunc_current, wmovwftemp_smovlwffhdecfsztemp_s, fgotof2_initgotof1_4_init; ---------------------------------------f2_init:movlwc0hdecfsztemp_s, fgotof3_initgotof1_4_init; ---------------------------------------f3_init:movlw80hdecfsztemp_s, fgotof4_initgotof1_4_init; ---------------------------------------f4_init:movlw40hdecfsztemp_s, fgotof5_initgotof1_4_init; ---------------------------------------f5_init:clrwdecfsztemp_s, fgotof6_initgotof5_7_init; ---------------------------------------f6_init:addlwpix_numbytesdecfsztemp_s, fgotof7_initgotof5_7_init; ---------------------------------------f7_init:addlwpix_numbytesgotof5_7_init; ---------------------------------------f1_4_init:movwfpix_gmovwfpix_rmovwfpix_bcallfillstripcallshowpixelsreturn; ---------------------------------------f5_7_init:bsfstatus, 6; Bank 2movwfeeadrmovlwscreen_addrmovwffsrmovlwpix_numbytesmovwftemp_cf5_7_copy:bsfstatus, 5; Bank 3bcfeecon1, 7; Point to data memorybsfeecon1, 0; Data memory readbcfstatus, 5; Bank 2movfeedata, wmovwfindfincfeeadr, fincffsr, fdecfsztemp_c, fgotof5_7_copyclrfstatus; Bank 0return; =======================================f1_main:movlw5subwffunc_current, wbtfscstatus, 0return; f1-4 = static light (do nothing)f5_7_main:callshowpixelscallcolshufflereturn; =======================================main:nopgoto main; =======================================

author: Andy Watson
author_rank: Super Contributor
timestamp: July 23, 2018, 09:35:07 pm
content: First thing that appears odd is that you have not saved the "context" in your interrupt routine. Look at section 15.11 of the datasheet. Also, be careful with the "call"s - you have a very limited stack depth with the PICs.

author: Raven Luni
author_rank: Contributor
timestamp: July 23, 2018, 09:38:08 pm
content: All the code is called at the start or from the interrupt - the main loop is empty so no need to preserve anything

author: Raven Luni
author_rank: Contributor
timestamp: July 23, 2018, 10:23:15 pm
content: Could it be the way SUBWF affects the carry bit? I've seen snippets here and there suggesting it might not set it as expected but nothing conclusive. In f1_main I'm checking the current function by subtracting 5 and returning if the carry if set (which I would expect it to be if the current function is 4 or less).

author: Andy Watson
author_rank: Super Contributor
timestamp: July 23, 2018, 10:31:52 pm
content: I'd missed that! Unusual, but it should work.Ok, try this:If I've interpreted this correctly, and I'm not going put any money on it, - line 87 says:Code:movlw 09h ; Pre:4, Post:16, Offmovwf t2conI make that "Pre2, Post 16, Off". This gives you 1024 instruction cycles between interupts - that's pretty tight considering the number of bits that you have to bang-out.

author: Raven Luni
author_rank: Contributor
timestamp: July 23, 2018, 10:47:04 pm
content: Thanks - I'll change that to 4Also confirmed that the problem is with the carry bit - by unplugging the data line and putting it back after a function change (f1-4 should output once only and 5-7 continuously and it turns out to be the opposite so its otherwise all working - just cycling through an array of plain white values)So changingCode:movlw5subwffunc_current, wbtfscstatus, 0returntoCode:movlw251addwffunc_current, wbtfssstatus, 0returnshould hopefully fix that.Trap for young players as Dave would say :p