I was wondering if the following code could be adapted for use on a PIC16F688. I've started to go through the code converting things, however, it seems that the Timers are different. I also don't know ASM very well either, so I bog down in converting the gpio port to use PORTC. This code was originally written for a PIC12F683: /******************************************************************** * * * * 4x5 Charlieplexed 20 LED Demo with 16 pwm levels per LED * * * * IDE: MPLAB 8.01 (tabs = 4) * * Lang: SourceBoost C v6.87 (Lite/Free version) * * * * * ********************************************************************/ #include #pragma DATA _CONFIG, _FCMEN_OFF & _IESO_OFF & _MCLRE_OFF & _WDT_OFF & _INTOSCIO #pragma CLOCK_FREQ 8000000 // //--< function prototypes >------------------------------------------ //--< variables >---------------------------------------------------- unsigned char led[20]; // LED matrix, pwm values 0..15 unsigned char shadow = 0; // ISR trisio shadow register unsigned char colpos = 1; // ISR gpio column ring counter bit unsigned char ledndx; // ISR led array index, 0..19 unsigned char dcy = 15; // ISR duty cycle counter, 0..15 //--< 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; // digital I/O trisio = 0b00111111; // set all pins to inputs gpio = 0; // set all output latches to '0' // setup 125 usec Timer 2 interrupts (8 MHz clock) pir1 = 0; // clear peripheral interrupt flags pie1 = 0; // clear peripheral interrupt enables 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 = 250-1; // 250 x 500-nsec 'ticks' = 125 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 while(1) { led[0] = led[19] = 15; // led[1] = led[18] = 12; // led[2] = led[17] = 9; // led[3] = led[16] = 7; // led[4] = led[15] = 6; // led[5] = led[14] = 5; // led[6] = led[13] = 4; // led[7] = led[12] = 3; // led[8] = led[11] = 2; // led[9] = led[10] = 1; // } } /********************************************************************/ /* interrupt service routine */ /********************************************************************/ /* */ /* 125 usec Timer2 interrupts, 16 interrupts per column (2 msecs) */ /* for 16 pwm brightness levels, 80 interrupts (10 msecs) for the */ /* complete 5 column update cycle for a 100 Hz refresh rate. */ /* */ /* led array duty cycle parameter values of 0..15 produce actual */ /* duty cycles of0% to 20% per LED in 1.25% (125 usec) steps. */ /* */ /* uses 55-84 cycles or approx 33.6% "overhead" with 8 MHz clock */ /* */ /********************************************************************/ void interrupt() { unsigned char dc0; // row0 (gp0) duty cycle, 0..15 unsigned char dc1; // row1 (gp1) duty cycle, 0..15 unsigned char dc2; // row2 (gp2) duty cycle, 0..15 unsigned char dc3; // row3 (gp4) duty cycle, 0..15 pir1.TMR2IF = 0; // clear timer 2 interrupt flag asm { movf _dcy,W ; duty cycle counter, 0..15 xorwf _dc0,W ; same as row0 LED duty cycle (gp0)? btfsc _status,Z ; no, skip, else bcf _shadow,0 ; clear row0 'on' bit in shadow reg' movf _dcy,W ; xorwf _dc1,W ; same as row1 LED duty cycle (gp1)? btfsc _status,Z ; bcf _shadow,1 ; movf _dcy,W ; xorwf _dc2,W ; same as row2 LED duty cycle (gp2)? btfsc _status,Z ; bcf _shadow,2 ; movf _dcy,W ; xorwf _dc3,W ; same as row3 LED duty cycle (gp4)? btfsc _status,Z ; bcf _shadow,4 ; movf _colpos,W ; 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 // bsf _status,RP0 ; compiler is doing this for me movwf _trisio ; update the column LEDs // bcf _status,RP0 ; compiler is doing this for me incf _dcy,F ; increment duty cycle counter btfss _dcy,4 ; all 16 pwm steps? yes, skip, else goto isrexit ; exit isr ; ; setup for next column ; nextcol: clrf _dcy ; reset duty cycle counter bcf _status,C ; rlf _colpos,F ; shift column bit mask btfsc _colpos,3 ; is it the gp3 bit? no, skip, else goto nextcol ; shift again to the gp4 position btfss _colpos,6 ; all 5 columns scanned? goto prepcol ; no, branch, else ; ; reset key variables if end of complete 5 column update ; movlw 0b00000001 ; movwf _colpos ; reset colpos bit movlw _led ; movwf _ledndx ; reset ledndx = &led[col 0 row 0] ; ; setup shadow, GPIO output pattern, and load PWM counters ; prepcol: movlw 0b00010111 ; movwf _shadow ; reset shadow (all output bits "on") movf _colpos,W ; movwf _gpio ; portb = colpos, only 1 bit high movf _ledndx,W ; movwf _fsr ; fsr = &led[col,0] movf _indf,W ; movwf _dc0 ; set row0 (gp0) pwm, 0..15 incf _fsr,F ; fsr = &led[col,1] movf _indf,W ; movwf _dc1 ; set row1 (gp1) pwm, 0..15 incf _fsr,F ; fsr = &led[col,2] movf _indf,W ; movwf _dc2 ; set row2 (gp2) pwm, 0..15 incf _fsr,F ; fsr = &led[col,3] movf _indf,W ; movwf _dc3 ; set row3 (gp4) pwm, 0..15 incf _fsr,W ; movwf _ledndx ; save array index isrexit: } } -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist