Jump to content

Mac

EstablishedMember
  • Content Count

    35
  • Joined

  • Last visited

Everything posted by Mac

  1. Is there a way to duplicate an assembly language macro that I use to store constant strings inline with my code? The putstr() function pulls the return address (the string address in this case) from top-of-stack, sends the string while updating TOS, and returns to the instruction immediately following the inline string. Here's the assembly language version I'm trying to duplicate; putstrg macro string ; in-line rom string call putstr ; inline string print function dt string,0 ; inline string endm ; Here's the inline print string function... /******************************************************************** * * ********************************************************************/ void putstr() // in-line strings (14 words) { strloop: // bank 31 (inserted by compiler) |31 asm movf _tosl,W // copy return address to FSR1 |31 asm movwf _fsr1l // " |31 asm movf _tosh,W // " |31 asm movwf _fsr1h // " |31 asm bsf _fsr1h,7 // set b7 for access to flash |31 asm incf _tosl,F // bump return/string address |31 asm btfsc _status,Z // " |31 asm incf _tosh,F // " |31 asm movf _indf1,W // end-of-string (0x00)? |31 asm btfsc _status,Z // no, skip (send char), else |31 asm return // exit (end-of-string) |31 asm call putwreg() // data passed in wreg |31 asm bra strloop // |31 } Thank you all for your time and kind consideration. Cheerful regards, Mike, K8LH
  2. Unlimited number of constant offsets with + and - operations can be used in assembly operands. What kind of expressions are you looking for? Regards, Pavel Hi Pavel, Hoping for reasonable operand expression evaluation that you would expect from any decent assembler implementation; Cheerful regards, Mike #define tStep 2 // 1-usec (2 cycle) tStep time .... asm { movlw 2*tStep-2 // 2T minus 2 cycles .... movlw 50/4 // 50 cycles/4 cycle loop time }
  3. We still need to compile all the changes. From the top of my head here are some: Support for multiple projects in a workspace Much better debugger (it can evaluate much more complex expression) Support for multiple plugin instances (minimal changes to plugin API) Optional parallel compilation Build server Optional support for big arrays and data objects(bigger that 256 bytes) Support for bit and bool return types Support for PIC16F1x architecture and instruction set Code generation and compile time are mostly unchanged. We work on a new compiler core that will change those. Regards, Pavel Have assembler capabilities been improved (operand expression evaluation) or are they still crippled?
  4. Could you use something like this? char fraction() { fract &= 15; fract *= 10; return(fract>>4|"0"); } whole = reading >> 7; fract = (reading >> 3) & 0xF; if (!positive) { serial_printf('-'); } else { serial_printf('+'); } serial_print_dec(whole); serial_printf('.'); puts(fraction()); // "0625", "1250", etc... puts(fraction()); puts(fraction()); puts(fraction());
  5. Using MPLAB v8.5 IDE and BoostC v6.97 and when I add an instruction using the modulo '%' operator I get the following error; Error: Unresolved external function:'__rem_8_8(unsigned char,unsigned char)' Error: Unresolved external function:'__rem_8_8(unsigned char,unsigned char)' Error: Unresolved external function:'__rem_8_8(unsigned char,unsigned char)' Error: Unresolved external function:'__rem_8_8(unsigned char,unsigned char)' Error: Unresolved external function:'__rem_8_8(unsigned char,unsigned char)' Error: Unresolved external symbol, function:__rem_8_8 What other file should I "include" besides "system.h" at the top of my source file, please? TIA, Mike
  6. Hi David, Your method worked and so I went back and tried again using MPLAB "project wizard" and that worked as well. Thank you for your time and kind consideration. Kind regards, Mike McLaren, K8LH
  7. Hi edeca, Your article is very nice. Only complaint is your program listing with gray text on black background is very difficult to see. I posted a PIC SPBRG Calculator program many years ago on Forum.Microchip that you might find handy for evaluating which BRGH and BRG16 settings produce the best bit rate error; Revised SPBRG Calculator. Kind regards, Mike, K8LH
  8. Using MPLAB 8.50 IDE with BoostC 6.97 (free/lite) and getting the following errors trying to compile a simple program for 16F1936; // // compiler evaluation for "enhanced" mid-range 16F1936 // #include <system.h> #pragma DATA _CONFIG1, _FOSC_INTOSC&_WDTE_OFF&_IESO_OFF&_FCMEN_OFF #pragma DATA _CONFIG2, _PLLEN_OFF&_LVP_OFF #pragma CLOCK_FREQ 16000000 void main() { osccon = 0b01111010; // 16-MHz INTOSC while(1) { // } } MPLAB generates the following dialog; "Failed to load C:\Development\PIC Projects - Boost C\16F1936 test.COF." And here's what I get in the MPLAB "output" window "build" tab; Clean: Deleting intermediary and output files. Clean: Deleted file "C:\Development\PIC Projects - Boost C\16F1936 test.HEX". Clean: Deleted file "C:\Development\PIC Projects - Boost C\16F1936 test.mcs". Clean: Done. Executing: "C:\Program Files\SourceBoost\boostlink_pic.exe" -O1 -v -p "16F1936 test" -t 16F1936 BoostLink Optimizing Linker Version 6.97 http://www.sourceboost.com Copyright(C) 2004-2010 Pavel Baranov Copyright(C) 2004-2010 David Hobday Optimisation level:1 Internal Error: Data Type not found id:0xF0000001: failure BUILD SUCCEEDED: Fri Apr 23 08:27:29 2010 Another 12F683 project compiles fine. What am I doin' wrong? TIA, Regards, Mike
  9. Gentlemen, is there a way to duplicate the function of this cycle accurate fixed delay assembler macro in BoostC, please? ; ; in-line fixed delay macro, 0..1027 cycles, 14 bit core ; clock equ 8; 8-MHz usecs equ clock/2; cycles/usec multiplier tStep equ 1*usecs; 1T "step" time inDlyCy macro delay; generates 0 to 7 instructions local loop if delay > 3 movlw delay/4-1; loop addlw -1; borrow? (4 cycle loop) bc loop; no, branch, else, fall thru' endif if delay%4 >= 2 goto $+1; delay%4 == 2 or delay%4 == 3 endif if delay%4 & 1 nop; delay%4 == 1 or delay%4 == 3 endif endm Here's how I would like to use it in BoostC (below)... asm { bsf STATUS,RP0; bank 1 |B1 movf bdat+0,W; TRISIO = bdat[0]; |B1 movwf TRISIO; |B1 inDlyCy(1*tStep-2); delay 1T minus 2 cycles |B1 movf bdat+1,W; TRISIO = bdat[1]; |B1 movwf TRISIO; |B1 inDlyCy(2*tStep-2); delay 2T minus 2 cycles |B1 bcf STATUS,RP0; bank 0 |B0 } I would just code in the assmebler delays by hand but the the assember is crippled, that is, the compiler doesn't evaluate assembler expressions such as the expression in this assembler operand; movlw (32*tStep-2)/4-1. Thank you in advance for your time and kind consideration. Regards, Mike
  10. I tried to use LOW(0x1000) and HIGH(0x1000) or 4096%256 and 4096/256 assmebler operands after locating my rom character table at 0x1000 in Flash using #pragma DATA directives and still "go joy". It seems that instead of building a good compiler around a full featured assembler that the assembler was more of an after thought. The assembler lacks any operand expression evaluation, won't use the LOW() and HIGH() operators for example, doesn't allow access to address of labels, and the list goes on... By comparison the assembler in Swordfish BASIC is a good example of what the assembler in a HLL should be able to do. Too bad it's BASIC (LOL)...
  11. Just wondering if I've run into another assembler shortcoming? Is there any way to use the address of a const rom char "table" in my assembly code? typedef unsigned char u08; // 8-bit #define r08 const rom unsigned char // // rom character array // r08 font[] = { 0b01110000, // "0" 0b10001000, // 0b10011000, // 0b10101000, // 0b11001000, // 0b10001000, // 0b01110000, // 0b00100000, // "1" 0b01100000, // 0b00100000, // 0b00100000, // 0b00100000, // 0b00100000, // 0b01110000 }; // //--< functions >---------------------------------------------------- void getromchar(u08 charval) // 31 words, 43 cycles { asm // { movlw 7 // tblptr = @romchar + charval * 7 mulwf _charval // movlw 46 // low(_font) <--------------------- ??? addwf _prodl,W // movwf _tblptrl // movlw 0 // high(_font) <--------------------- ??? addwfc _prodh,W // movwf _tblptrh // clrf _tblptru // tblrd*+ // movff _tablat,_display+7 // display[7] = romchar[charval*7+0] tblrd*+ // movff _tablat,_display+15 // display[15] = romchar[charval*7+1] tblrd*+ // movff _tablat,_display+23 // display[23] = romchar[charval*7+2] tblrd*+ // movff _tablat,_display+31 // display[31] = romchar[charval*7+3] tblrd*+ // movff _tablat,_display+39 // display[39] = romchar[charval*7+4] tblrd*+ // movff _tablat,_display+47 // display[47] = romchar[charval*7+5] tblrd*+ // movff _tablat,_display+55 // display[55] = romchar[charval*7+6] } }
  12. Piece of cake: volatile unsigned short ccpr1 @ 0xFBE; ccpr1 = 2400; Regards, Pavel Ah, thank you...
  13. I'm just looking for the same capability that I get with MCC18. Being able to access register pairs as CCPR1, CCPR2, INDF0, and FSR0 seems very clean and intuitive (to me). Kind regards, Mike
  14. I see a definition for 'ccpr1' in the '2620 header file but I can't seem to use it as a 16-bit 'INT'. What am I doin' wrong Gentlemen? unsigned int match = 2400; ..... ccpr1 = match; // <-- error match <<= 1; //
  15. Are there any plans for improving assembler expression evaluation? The following (with arrows) don't work. Kind regards, Mike void mibam_isr() { asm { movf _offset,W // addwf _pcl,F // slot00: movf _preset+0,W // xorwf _latb,F // movlw slot01-slot00 // <--- movwf _offset // retfie 1 // slot01: addlw -10 // <---
  16. Missing encoder steps would be a problem no matter what method you're using, wouldn't it? Mike, K8LH
  17. The easiest way that I know of to determine encoder direction is to exclusive-or the new sample 'A' or 'B' bit with the opposite bit from the previous sample (direction equals 0 or 1). Regards, Mike new = portb & 0x30; // sample A-B pins (RB4-RB5) if(new^old) // if A-B pins have changed { dir = new.4 ^ old.5; // direction = new.A ^ old.B old = new; // update latch your_code_here }
  18. While you gentlemen are talking about the -rb linker option, may I ask if there's a way to tell the linker to use that option from within the source file? Via a #PRAGMA statement perhaps? Kind regards, Mike
  19. I setup the config' words this way on a recent 16F88 LED Clock project; #pragma DATA _CONFIG1, _CCP1_RB0&_LVP_OFF&_MCLR_OFF&_WDT_OFF&_HS_OSC #pragma DATA _CONFIG2, _IESO_OFF & _FCMEN_OFF Regards, Mike, K8LH
  20. The cathodes on LED 0, 5, 10, and 15 must be connected to the GP5 "float" pin in order to satisfy the Charlieplexing signal rules. That is, only one pin can ever be driven high at any time to turn on a single column driver "source" transistor and the other four pins should be driven low to turn on an LED in that column/row or left as a hi-z input to leave the LED off in that column/row. This is why we use an "active high" NPN transistor instead of a more traditional "active low" PNP transistor for the column "source" driver. If you follow the signal paths in the schematic you'll notice that LED 0, 5, 10, and 15 occupy positions in the matrix where the row and column would use the same pin (GP0/GP0, GP1/GP1, etc.). When you connect these LEDs the way you have they will never light. That's why the cathodes of those LEDs are driven by the "float" pin. If you'd like to reduce the size of the matrix from 20 LEDs to 16 LEDs then I would eliminate Q5 and LEDs 16-19 then apply the code changes you listed, but you'll have to leave the GP5 "float" pin connected to LED 0, 5, 10, and 15. If on the other hand you're trying to create a Charlieplexed 4 pin matrix instead of a 5 pin matrix then that would require quite a few more changes to both hardware and software. I should also point out that a 4 pin Charlieplexed matrix will only have 12 LEDs. That is, Number_of_LEDs = N(N-1) where N is the number of pins. Regards, Mike
  21. Glad you got it working. Have fun. Mike, K8LH
  22. Seems to work ok on my prototype but I changed the default state so it starts up with the display running; unsigned char swflags = 8; I tested those changes on a more recent version of the program (64 level PWM) but that really shouldn't make a difference; /******************************************************************** * * * Project: 12F683 LED PWM * * Source: 12F683_LED_PWM.c * * Author: Mike McLaren, K8LH * * Date: 03-Jul-08 * * Revised: 27-Jan-09 * * * * 64 level PWM on a 20 LED Charlieplexed matrix * * * * * * IDE: MPLAB 8.14 (tabs = 4) * * Lang: SourceBoost BoostC v6.91, Lite/Free version * * * * * ********************************************************************/ #include <system.h> #pragma DATA _CONFIG, _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTOSCIO #pragma CLOCK_FREQ 8000000 //--< function prototypes >------------------------------------------ //--< type definitions >--------------------------------------------- typedef unsigned char u08; //--< variables >---------------------------------------------------- u08 led[20]; // led matrix, pwm values 0..63 u08 shadow = 0; // isr, trisio shadow register u08 colpos = 1; // isr, gpio column select bit u08 dcy = 0; // isr, duty cycle counter, 0..64 u08 dc0 = 0; // isr, row 0 (gp0) pwm value, 0..63 u08 dc1 = 0; // isr, row 1 (gp1) pwm value, 0..63 u08 dc2 = 0; // isr, row 2 (gp2) pwm value, 0..63 u08 dc3 = 0; // isr, row 3 (gp4) pwm value, 0..63 u08 addr = (u08) &led; // isr, led array address pointer u08 x, temp; u08 swlatch = 0; // switch state latch u08 swflags = 8; // switch flag bits //--< defines >------------------------------------------------------ #define end_of_period dcy.6 // isr, end of 64 pwm steps #define last_column colpos.5 // isr, end of 5 column update cycle #define run_switch swflags.3 // //--< main >--------------------------------------------------------- void main() { osccon = 0b01110000; // set 8 MHz INTOSC while(!osccon.HTS); // wait 'til oscillator stable cmcon0 = 7; // comparator off, digital I/O ansel = 0; // a2d module off, digital I/O trisio = 0b00111111; // set all pins to inputs gpio = 0; // set all output latches to '0' // setup 50 usec Timer 2 interrupts (8 MHz clock) pir1 = 0; // clear peripheral interrupt flags pie1.TMR2IE = 1; // set Timer 2 interrupt enable bit tmr2 = 0; // clear Timer 2 register t2con = 0b00000100; // '0-------' unimplemented bit // '-0000---' TOUTPS<3:0>, postscale 1 // '-----1--' TMR2ON, turn Timer 2 on // '------00' T2CKPS<1:0>, prescale 1 pr2 = 100-1; // 100 x 500-nsec 'ticks' = 50 usecs intcon = 0b11000000; // '1-------' GIE, enable global ints // '-1------' PEIE, enable peripheral ints // '--0-----' T0IE, TMR0 ints disabled // '---0----' INTE, off // '----0---' GPIE, IOC disabled // '-----000' T0IF/INTF/GPIF flags // simple interface to pwm driver using duty cycle values of 0..63 led[0] = led[19] = 11; // 11 * 0.3125% = 3.4% of 20% max led[1] = led[18] = 7; // 7 * 0.3125% = 2.2% led[2] = led[17] = 5; // 5 * 0.3125% = 1.5% led[3] = led[16] = 4; // 4 * 0.3125% = 1.2% led[4] = led[15] = 3; // 3 * 0.3125% = 0.9% led[5] = led[14] = 2; // 2 * 0.3125% = 0.6% led[6] = led[13] = 1; // 1 * 0.3125% = 0.3% led[7] = led[12] = 0; // led[8] = led[11] = 0; // led[9] = led[10] = 0; // while(run_switch) // while run switch "on" { // simple animation demo temp = led[0]; // while(!last_column); // sync' to 16.25 msec frame rate for(x=0; x<19; x++) // { led[x] = led[x+1]; // } // led[19] = temp; // delay_ms(26); // } } /******************************************************************** * interrupt service routine, display and pwm driver * * * * 50 usec Timer2 interrupts, 65 interrupts/column (3.25 msecs) * * for 64 pwm brightness levels. 325 interrupts (16.25 msecs) in * * a complete 5 column update cycle (61.5 Hz refresh rate). * * * * led array duty cycle parameter values of 0..63 produce actual * * duty cycles of 0% to 20% per LED in 0.3125% (50 usec) steps. * * * * 56 or 58 cycles or approximately 58% "overhead" (8 MHz clock) * * * ********************************************************************/ void interrupt() { pir1.TMR2IF = 0; // clear Timer 2 interrupt flag bit if(!end_of_period) // { if(dc0 == dcy) // if row 0 duty cycle match shadow.0 = 0; // clear shadow bit (gp0) if(dc1 == dcy) // if row 1 duty cycle match shadow.1 = 0; // clear shadow bit (gp1) if(dc2 == dcy) // if row 2 duty cycle match shadow.2 = 0; // clear shadow bit (gp2) if(dc3 == dcy) // if row 3 duty cycle match shadow.4 = 0; // clear shadow bit (gp4) dcy++; // bump duty cycle counter asm { movf _colpos,W // 000001,000010,000100,010000,100000 movwf _gpio // setup output latch, only 1 bit high andwf _shadow,W // is the float bit required? btfss _status,Z // no, skip, else iorlw 0b00100000 // set the 'float' bit iorwf _shadow,W // pick up led bits iorwf _colpos,W // pick up column bit xorlw 0b00111111 // invert all } } else // setup for the next column { dcy = 0; // reset duty cycle counter if(last_column) // if last column (col 5, 16.25 msecs) { addr -= 16; // reset led array address pointer colpos = 1; // reset column select bit to column 0 asm { // comf _gpio,W // sample active lo push button switch andlw 8 // filter out all but GP3 bit xorwf _swlatch,W // changes (press or release) xorwf _swlatch,F // update switch state latch andwf _swlatch,W // filter out "new release" bits xorwf _swflags,F // toggle switch flag bits for main } } else // else, just prep for next column { addr += 4; // bump led array address pointer asm // carry = 0 from addition above { rlf _colpos,F // shift column select bit btfsc _colpos,3 // shift past GP3 if necessary rlf _colpos,F // shift column select bit } } fsr = addr; // setup new column pwm variables dc0 = indf; fsr++; // row 0 (gp0) pwm value, 0..63 dc1 = indf; fsr++; // row 1 (gp1) pwm value, 0..63 dc2 = indf; fsr++; // row 2 (gp2) pwm value, 0..63 dc3 = indf; // row 3 (gp4) pwm value, 0..63 shadow = 0b00010111; // reset shadow, all row bits 'on' } // and turn off display asm { movwf _trisio // update display } }
  23. Ryeg, Not what I would call a "simple example" but here's a 9600 baud half-duplex demo' (with 16 byte circular RX buffer) I did last year with BoostC v6.87 but it seems to have an error during compile in my v6.91 update. I will try to track down the problem. Operation: on detecting the start bit leading edge with IOC (interrupt on change), TMR2 interrupts are enabled and IOC is turned off. After clocking in the eight data bits during TMR2 interrupts and after adding the byte to the 16 byte circular buffer, TMR2 interrupts are disabled and IOC is turned back on. I wasn't thrilled with BoostC ISR 'overhead' in this demo' but then I typically use a higher performance assembly language Half-Duplex or Full-Duplex serial I/O package for the 12F683 (I have versions that use TMR2 or TMR0 when you need TMR2 for something else). Mike /******************************************************************** * * * Project: Serial 12F683 * * Source: Serial_12F683.c * * Author: Mike McLaren, K8LH * * Date: 12-Jul-08 * * Revised: 12-Jul-08 * * * * 12F683 Half Duplex 9600 baud bit-banged serial I/O test * * * * * * IDE: MPLAB 8.01 (tabs = 4) * * Lang: SourceBoost BoostC v6.87, Lite/Free version * * * * * ********************************************************************/ #include <system.h> #pragma DATA _CONFIG, _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTOSCIO #pragma CLOCK_FREQ 8000000 //--< function prototypes >------------------------------------------ //--< typedef and defines >------------------------------------------ typedef unsigned char u08; typedef unsigned int u16; #define TxPin 0 // Tx on GP0 #define RxPin 3 // Rx on GP3 //--< variables >---------------------------------------------------- u08 RxBuff [16]@0xA0; // 16 byte circular Rx buffer, A0..AF u16 TxChar; // Tx character work register u08 RxPull = 0xA0; // circular Rx buffer pull (rd) pointer u08 RxPush = 0xA0; // circular Rx buffer push (wr) pointer u08 RxCount = 0; // Rx bit counter (isr) u08 TxCount = 0; // Tx bit counter (isr, put232) //--< functions >---------------------------------------------------- u08 rdy232() // test for Rx character available { return(RxPull!=RxPush); // 0 = buffer empty, 1 = char available } u08 get232() // pull Rx char from circular buffer { fsr = RxPull; // setup buffer indirect address RxPull = fsr + 1; // increment circular 'pull' pointer RxPull.4 = 0; // pseudo %16 (circular A0..AF range) return indf; // return Rx character } void put232(u08 data) // blocking rs-232 output { while(TxCount|RxCount); // wait while Tx in progress TxChar = 2 * data; // b0 = 0 (start bit), b1..b8 = data TxChar.9 = 1; // b9 = 1 (stop bit), b10..b15 unused TxCount = 10; // tell ISR to send TxChar t2con.TMR2ON = 1; // turn on timer 2 } void put232(rom char *data) // overload function for string data { char n = 0; // char temp; // while(temp = data[n++]) // put232(temp); // } //--< main >--------------------------------------------------------- void main() { osccon = 0b01110000; // set 8 MHz INTOSC while(!osccon.HTS); // wait 'til oscillator stable ansel = 0; // a2d module off, digital I/O cmcon0 = 7; // comparator off, digital I/O gpio = 1<<TxPin; // Tx pin output latch hi trisio = 1<<RxPin; // all outputs except for RxPin ioc = 1<<RxPin; // enable RxPin GP3 interrupt-on-change // setup 104 usec Timer 2 interrupts (8 MHz clock) for 9600 baud pir1 = 0; // clear peripheral interrupt flags pie1.TMR2IE = 1; // set Timer 2 interrupt enable bit tmr2 = 0; // clear Timer 2 register t2con = 0b00000000; // '0-------' unimplemented bit // '-0000---' TOUTPS<3:0>, postscale 1 // '-----0--' TMR2ON, Timer 2 off // '------00' T2CKPS<1:0>, prescale 1 pr2 = 208-1; // 208 x 500-nsec 'ticks' = 104 usecs intcon = 0b11001000; // '1-------' GIE, enable global ints // '-1------' PEIE, enable peripheral ints // '--0-----' T0IE, TMR0 ints disabled // '---0----' INTE, off // '----1---' GPIE, IOC ints enabled // '-----000' T0IF/INTF/GPIF flags delay_ms(100); // put232("\x1B[2J"); // ANSI home cursor, clear screen put232("K8LH 12F683 Half Duplex 9600 Baud Serial I/O Demo\r\n\n"); while(1) { if(rdy232()) // if rx char available put232(get232()); // echo it back } } /******************************************************************** * interrupt service routine * * * ********************************************************************/ void interrupt() { if(intcon.GPIF) { // IOC start bit leading edge interrupt asm { movf _gpio,W // bcf _intcon,GPIF // clear IOC interrupt flag bcf _ioc,RxPin // turn off RxPin interrupt-on-change movlw 10 // setup Rx bit counter var' movwf _RxCount // 10 bits (1 start, 8 data, 1 stop) movlw 156 // 208 - 104 + 52 cycles movwf _tmr2 // 1/2 bit time minus ISR overhead bsf _t2con,TMR2ON // turn on Timer 2 } } else { // Timer 2 interrupt pir1.TMR2IF = 0; // clear Timer 2 interrupt flag bit if(TxCount) { // if Tx in progress asm { // rrf _TxChar+1,F // rrf _TxChar+0,F // C = data bit movf _gpio,W // W = current GPIO andlw 0b00111110 // clr TxPin bit to send a '0' btfsc _status,C // data = 0? yes, skip, else iorlw 0b00000001 // set TxPin bit to send a '1' movwf _gpio // send data bit decf _TxCount,F // btfsc _status,Z // skpnz bcf _t2con,TMR2ON // turn off timer 2 } } if(RxCount) { // if Rx in progress asm { // movf _RxPush,W // circular buffer 'push' pointer movwf _fsr // bcf _status,C // btfsc _gpio,RxPin // bsf _status,C // rrf _indf,F // decfsz _RxCount,F // last bit received? goto exit // no, branch, else rlf _indf,F // get rid of the stop bit incf _RxPush,W // andlw 0xAF // pseudo %16 (circular A0..AF range) xorwf _RxPull,F // buffer full, RxPush+1 == RxPull? btfss _status,Z // yes, skip (ignore new char), else movwf _RxPush // update Rx buffer 'push' pointer xorwf _RxPull,F // fix RxPull pointer bsf _ioc,RxPin // enable RxPin interrupt-on-change bcf _t2con,TMR2ON // turn off timer 2 exit: } } } }
  24. The serial connection (the 2.5mm stereo jack in the picture below) is used for a "Serial Addressable LED Bar/Graph Display" program I wrote. I don't have documentation for that program to share, but, I did post an example BoostC 12F683 bit-bang serial I/O demo' over on the Electro-Tech-Online forum some time ago; BoostC 12F683 Serial I/O Example
×
×
  • Create New...