Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

avr code to code for PIC

Status
Not open for further replies.
That'll take awhile.... Paging the ROM tables 4 * 255 and there will be a significant frequency drop as the humble pic cannot do register to register addition...

I want to see how fast I can get it on an enhanced pic16...
 
That'll take awhile.... Paging the ROM tables 4 * 255 and there will be a significant frequency drop as the humble pic cannot do register to register addition...

I want to see how fast I can get it on an enhanced pic16...
The AVR version has a 32bit phase accumulator.
Maybe 24bit or even 16bit is enough for a simple DDS generator. That would be faster in a PIC.
In the other thread I posted a link, where PIC16F628 is running 32bit DDS code in a 100kHz interrupt loop.
 
As I first thought.... To use the tables you need a routine to access then... Or at least a mackro.... This will slow down the table access quite a bit... Without the large table code we are up to 16 cycles....
 
As I first thought.... To use the tables you need a routine to access then... Or at least a mackro.... This will slow down the table access quite a bit... Without the large table code we are up to 16 cycles....
Could it be done in 12 cycles for 18F or 11 cycles for enhanced 16F devices?
Code:
;
;  18F
;
dds     movf    phase+0,W       ;
        addwf   accum+0,F       ;
        movf    phase+1,W       ;
        addwfc  accum+1,F       ;
        movf    phase+2,W       ;
        addwfc  TBLPTRL,F       ;
        tblrd*                  ; read sine table data into TABLAT
        movf    TABLAT,W        ; sine table data
        movwf   PORTB           ; update R2R
        bra     dds             ;
Code:
;
;  16F (enhanced)
;
dds     movf    phase+0,W       ;
        addwf   accum+0,F       ;
        movf    phase+1,W       ;
        addwfc  accum+1,F       ;
        movf    phase+2,W       ;
        addwfc  FSR1L,F         ;
        movf    INDF1,W         ; sine table data
        movwf   PORTB           ; update R2R
        bra     dds             ;
Some of the 16F17xx series devices have an 8-bit DAC (R2R type) and op-amp which would eliminate the need for an external R2R and external op-amp.

Cheerful regards, Mike
 
Last edited:
This "naive" version will run in two cycles:

movlw data1
movwf PORTB
movlw data2
movwf PORTB
...
movlw dataN
movwf PORTB

It takes almost twice as much memory, but it's 6 times faster.
 
Could it be done in 12 cycles for 18F or 11 cycles for enhanced 16F devices?
Code:
;
;  18F
;
dds     movf    phase+0,W       ;
        addwf   accum+0,F       ;
        movf    phase+1,W       ;
        addwfc  accum+1,F       ;
        movf    phase+2,W       ;
        addwfc  TBLPTRL,F       ;
        tblrd*                  ; read sine table data into TABLAT
        movf    TABLAT,W        ; sine table data
        movwf   PORTB           ; update R2R
        bra     dds             ;
Code:
;
;  16F (enhanced)
;
dds     movf    phase+0,W       ;
        addwf   accum+0,F       ;
        movf    phase+1,W       ;
        addwfc  accum+1,F       ;
        movf    phase+2,W       ;
        addwfc  FSR1L,F         ;
        movf    INDF1,W         ; sine table data
        movwf   PORTB           ; update R2R
        bra     dds             ;
Some of the 16F17xx series devices have an 8-bit DAC (R2R type) and op-amp which would eliminate the need for an external R2R and external op-amp.

Cheerful regards, Mike

I'm glad you posted Mike..

I was looking through the forum as I knew you posted something similar before..
Does your code allow page boundry crossing?
 
Does your code allow page boundry crossing?

Hi Ian,

Not sure I understand your question. The 18F (16-bit core) devices don't have "pages" as such. In 16F "enhanced mid-range" (14-bit core) devices you can indirectly access data or program memory anywhere in either address space without concern for "page" boundaries in program memory address space.

Regards...
 
Hi Ian,

Not sure I understand your question. The 18F (16-bit core) devices don't have "pages" as such. In 16F "enhanced mid-range" (14-bit core) devices you can indirectly access data or program memory anywhere in either address space without concern for "page" boundaries when accessing program memory.

Regards...
When I try to access the complete 255 values on a pic16f1826, the program goes nuts around item 0xFA... and reboots the micro.. That means it has crossed the page boundary... I must be using idea's from the midrange pics
 
Are you using FSRx for indirect access?

Forgot to mention that for the DDS application the tables (sine, square, saw, triangle, etc.) should be org'd to 256 word boundaries to accomodate the phase accumulator math... Setup TBLPTRH (18F) or FSR1H (enhanced 16F) to point at the correct table before entering the DDS loop.
 
Last edited:
Stupid question here..... How do you load the FSR1H.....


Never mind..... I have loaded it manually.... I see from the datasheet that when accessing Flash memory bit7 has to be set!!
 
Last edited:
Stupid question here..... How do you load the FSR1H.....

Never mind..... I have loaded it manually.... I see from the datasheet that when accessing Flash memory bit7 has to be set!!

The compiler (XC8) or assembler (MPASM) will set FSRx bit 15 for you.

Code:
;
;  setup FSR1 for 'sine' table (assembler knows 'sinetbl' label is
;  in program memory and will will add 0x8000 to the address).
;
        movlw   low(sinetbl)    ; sine table address lo
        movwf   FSR1L           ;
        movlw   high(sinetbl)   ; sine table address hi
        movwf   FSR1H           ; FSR0 = &sinetbl
And here's an excerpt of code generated from an FSR0 = &sine statement in XC8 ( const char sine[] @ 0x0400 = {...} );
Code:
   279                           ;12F1822 Serial Demo.c: 71: FSR0 = &sine[0];
   280  041D  3084                   movlw    132
   281  041E  0020                   movlb    0    ; select bank0
   282  041F  0085                   movwf    5    ;volatile
   283  0420  3000                   movlw    0
   284  0421  0084                   movwf    4    ;volatile
 
Last edited:
For this tiny project I preset the FSR1H to 0x81 ( the table starts at 0x100 )

Then all I need to do is set 1,2, 3 and 4 for each table..... At 16Mhz using a pic16f1826.. I have a 22.815 Khz sine....It will go faster but its starting to break up.... If a small filter is employed it would be quite smooth.

With your code its as fast as the AVR..... Just the serial interface to do now... Cheers Mike...
 
Please show your code, Ian... I'd like to see how you did it... Are you using the built-in 5-bit DAC or an external R2R?
 
Last edited:
With your code its as fast as the AVR..... Just the serial interface to do now... Cheers Mike...
Are you sure? I thought AVR used one clock cycle per instruction cycle where PIC uses four clock cycles per instruction cycle. Isn't a 16-MHz AVR roughly equivalent to a 64-MHz PIC?
 
Last edited:
Please show your code, Ian... I'd like to see how you did it... Are you using the built-in 5-bit DAC or an external R2R?

Its your code!! I have just used the bit you posted... I'm using a crass R2R!!! 1k and 2k resistors..

I'll post the code as soon as I have done the serial interface part... I have to do something to help..LOL
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top