From PIC16F690 to PIC18F26K20 + The big function!

thatoneguy

Joined Feb 19, 2009
6,359
Now, can you repost my template with correct spacings and all the above so i can see...it will help more

Thanks so much!!!
I clipped it to 65 columns, added start/end blocks, and renamed some of them. I probably missed some, been awake too long.

Copy and paste into your editor to save.

Rich (BB code):
;****************************************************************;
;    Filename  16F690-template.asm                              *
;    Author:                                                    *
;    Date Created:                                              *
;    Date Modified: 01/14/2012                                  *
;    Target MCU:  16F690                                        *
;    Title:                                                     *
;    Version:                                                   *
;****************************************************************
;    Description:                                               *
;                                                               *
;                                                               *
;                                                               *
;****************************************************************
;    Module:                                                    *
;                                                               *
;    Usage :                                                    *
;                                                               * 
;                                                               *
;                                                               *
;    Input :                                                    * 
;    Output:                                                    *
;****************************************************************
;    16F690 DIP Package Layout Details                          * 
;****************************************************************
;    Vdd                 Pin 1    ICSPVdd
;    Vss                 Pin 20   ICSPVss
;    Port A0     ICSP    Pin 19   ICSPDAT
;    Port A1     ICSP    Pin 18   ICSPCLK
;    Port A2             Pin 17
;    Port A3     ICSP    Pin 4    ICSPVPP/MCLR
;    Port A4             Pin 3
;    Port A5             Pin 2
;
;
;    Port C0             Pin 16
;    Port C1             Pin 15
;    Port C2             Pin 14
;    Port C3             Pin 7
;    Port C4             Pin 6
;    Port C5             Pin 5
;    Port C6             Pin 8
;    Port C7             Pin 9
;

;****************************************************************
;    Header file section                                        *
;****************************************************************

list p=16F690                 ; Inform assembler of PIC
#include <p16F690.inc>        ; default header for chosen PIC

errorlevel -302, -207         ; Ignore annoying warnings
radix    dec

;****************************************************************
;  config fuses                                                 *
;****************************************************************

__config  _FCMEN_OFF& _IESO_OFF& _MCLRE_OFF& _WDT_OFF& _INTOSCIO
;
;  _FCMEN_OFF           ; -- fail safe clock monitor enable off
;  _IESO_OFF            ; -- int/ext switch over enable off
;  _BOR_ON              ; default, brown out reset on
;  _CPD_OFF             ; default, data eeprom protection off
;  _CP_OFF              ; default, program code protection off
;  _MCLR_OFF            ; -- use MCLR pin as digital input
;  _PWRTE_OFF           ; default, power up timer off
;  _WDT_OFF             ; -- watch dog timer off
;  _INTOSCIO            ; -- internal osc, RA6 and RA7 I/O


;****************************************************************
;    Constants definition section                               *
;****************************************************************

#define       ;
#define       ;

;****************************************************************
;    Variable definition section                                *
;****************************************************************

Cblock 0x20    ; start of general purpose registers



endc

;  use "shared" memory common to all banks for isr context vars
;Bank 0 0x070 - 0x07F (16 bytes -- copied into banks 1-3)

cblock    0x70
cs_W                         ;context saving register for w
cs_STATUS                    ;context saving register for STATUS
endc


;***************************************************************
;                Reset vector                                  *
;***************************************************************

Org 0x0000                   ; reset vector / start
nop                          ; required for ICD
goto Init                    ; Jump to main program

;***************************************************************
;    Interrupt Service Routine                                 *
;***************************************************************
Org 0x0004                   ; Interrupt jump Address
; ***Save context***

isr
movwf     cs_W               ; save W register
swapf     STATUS, w          ;
movwf     cs_STATUS          ; save STATUS register
clrf      STATUS             ; force bank 0, IRP 0
;***************************************************************
;    Interrupt processing                                      *
;***************************************************************
; --- test interrupts here ---


;***Restore context and return

isr_end
swapf     cs_STATUS, w       ;
movwf     STATUS             ; restore STATUS
swapf     cs_W, f            ;
swapf     cs_W, w            ; restore w
retfie





goto      isr_end

;***************************************************************
;                 END Interrupt section                        *
;***************************************************************

;***************************************************************
;                   Peripheral Initialization                  *
;***************************************************************

Init

;    ADC setup

;banksel ANSEL           ;
;clrf    ANSEL           ; turn off analogue pin functions
;clrf    ANSELH

;  I/O port initialization



;  setup INTOSC for -MHz INTERNAL/EXTERNAL CLOCK



; configure TMR0 -- set for X ms time, base at X MHZ




; register variables initialization
;***************************************************************
;              Initialization Complete                         *
;***************************************************************

goto main



;***************************************************************
;                   Main program                               *
;***************************************************************


main



goto main

;***************************************************************
;                End of Main Program                           *
;***************************************************************

;***************************************************************
;                Subroutines  section                          *
;***************************************************************
; --- Insert subroutines below this line ---                   *



;***************************************************************
;                End of Subroutines                            *
;***************************************************************

;***************************************************************
;**      --- state machine title here (optional)  ---         **
;***************************************************************
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**          --- describe state machine here ---              **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;**                                                           **
;***************************************************************


end
;***************************************************************
;*********************THIS IS THE END!!!!***********************
;***************************************************************
 
Last edited:

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Just a curiosity question!

Is it possible to interface an external memory (SRAM I think!) With the PIC18F26K20??

And can someone please address my post #20?

Thanks!
 

MMcLaren

Joined Feb 14, 2010
861
One more thing, the package type (SPDIP) of the PIC chip is the one that sits well on breadboard, right!?
Sorry... I thought you may have posted that question by mistake since the SPDIP package dimensions are shown on page 429 of the PIC18F2XK20/4XK20 datasheet (DS41303G)...
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I said it was just for curiosity!!

Ok can someone PLEASE repond to my post #20!? Coz I ordered the wrong package type (QFN) first and don't want no mistake this time around...

Thanks!
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Sorry... I thought you may have posted that question by mistake since the SPDIP package dimensions are shown on page 429 of the PIC18F2XK20/4XK20 datasheet (DS41303G)...
I have seen it in the datasheet...I just wana make sure I'm correct!!

Thx!
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Hey guys!

I think I'm going to put it in 2 posts so you don't get annoyed!

Function description:

I would like to implement three functions as a single one:
(1) Filter function à(2) multiply function à (3) accumulator function

function1: The filter function is a 4th order chebyshev type 2 digital bandpass filter by cascading two 2nd order filters using ‘Direct form II transposed’ difference equation implementation.

Note: a 2nd order IIR direct form II transposed is of the form:
y(n) = b(1)*x(n) + b(2)*x(n-1) + b(3)*x(n-2) - a(2)*y(n-1) – a(3)*y(n-2)

where b(1), b(2), b(3), a(2), a(3) are coefficients, to be determined, that specify the type of the filter, x(n) is the current sample, x(n-1) and x(n-2) are previous samples. y(n) is the output for the current sample, y(n-1) and y(n-2) are the output of x(n-1) and x(n-2) respectively.

Now for a 4th order filter (the one I’m interested in), we’ll have:

y1(n) = b11*x1(n) + b12*x1(n-1) + b13*x1(n-2) – a11*y1(n-1) – a12*y1(n-2)
y2(n) = b21*x2(n) + b22*x2(n-1) + b23*x2(n-2) – a21*y2(n-1) – a22*y2(n-2)

function2: the multiply function, simply multiply the output of function1 with the gain (yout = g*y2)

function3: the accumulator function squares the output of function2 (yout*yout) then accumulates it and after accumulating a number of samples, stores it as a point, we have something like this:

s = 0;
s += yout*yout;

for instance, given 2000 samples and assume we want to accumulate 200 samples per point à after 2000 samples we will have an array of 10 points. And if we have for instance 7 filters (the overall function), we will have 7*10 points = 70 points

End of function description

My frequency range of interest is: 0Hz -2000Hz. Now why I needed a fast MCU? Because I’m going to implement a number of bandpass filter having different passband frequencies…

For instance: 150hz- 400hz, 400hz-650hz, 650hz-900hz, 900hz-1150hz,1150hz-1400hz, 1400hz-1650hz, 1650hz-1900hz and a sample should pass through all these filters fast enough before a new sample comes from ADC!!! As ima sample it at double the highest frequency, the processing time should then be less than 1/4khz = 250us!

Well depending on the time one filter function takes to execute, I will adjust the number of filter functions and might adjust the interval between each filter function so that a sample has enough time to be processed by those filters before the next new sample comes.

Thank so much for your comments!!
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Now the first thing I did was to generate the coefficients for the filter using Matlab!
Here’s how I did it (assuming the interval 150 Hz-400 Hz):

150/2000 = 0.075
400/2000 = 0.2

>>[B1,A1] = cheby2(2,40,[0.075 0.2]);
>>[sos1,g1] = tf2sos(B1,A1,'up','inf');
>>scaleco1 = round(sos1.*256);
>>scaleco1 = scaleco1./256;
>>scaleg1 = round(g1*256);
>>scaleg1 = scaleg1/256;
>>[B1,A1] = sos2tf(scaleco1,scaleg1);

>> sos1

sos1 =

0.0659 -0.0969 0.0659 1.0000 -1.7987 0.9593
9.7580 -19.1412 9.7580 1.0000 -1.8318 0.9631

The above are the coefficient in the form:

sosn = [ b11 b12 b13 1.0000 a11 a12
b21 b22 b23 1.0000 a21 a22]

Here’s my algorithm for the function1:

Step 1: create an array of size 10 x 2-byte in RAM to store the above 10 coefficients of the filter;
Step 2: write a macro (I think) so I can do the following:

1. Working out the first filter (2nd order)

- multiply each coefficient with its corresponding sample:

b11*x, x = x1(n), the current sample
b12*x1 (n-1)
b13*x1 (n-2)
– a11*y1 (n-1)
– a12*y1 (n-2)

Initially, x1(n-1) = x1(n-2) = y1(n-1) = y1(n-2) = 0

- Accumulate the product (adding them):
[b11*x1(n)] + [b12*x1(n-1)] + [b13*x1(n-2) ] + [– a11*y1(n-1)] + [ – a12*y1(n-2)] and store them as y (output of first filter)


- Update the samples:

x1(n-2) = x1(n-1)
x1(n-1) = x
y1 (n-2) = y1 (n-1)
y1 (n-1) = y (output of 2nd order filter)

2. working the second filter to form a 4th order filter

- multiply each coefficient of second filter with its corresponding sample:

b21*y, y = output of first filter
b22*y2 (n-1)
b23*y2 (n-2)
– a21*z (n-1)
– a22*z (n-2)

For convenience, I call ‘z’ the output of second filter, y2 simply refers to input to the second filter (which are outputs of first filter). And initially, y2(n-1) = y2(n-2) = z(n-1) = z(n-2).

- Update the samples:

y2(n-2) = y2(n-1)
y2(n-1) = y
z (n-2) = z(n-1)
z (n-1) = z (output of 4nd order filter)

- Accumulate the product (adding them):
[b21*y] + [b22*y2(n-1)] + [b23*y2(n-2) ] + [– a21*z(n-1)] + [ – a22*z(n-2)] and store them as ‘z’ (output of second filter)

End of algorithm.

I think the macro can just do the following:
Output = 0;
Output += sample*coefficient

where sample and coefficient are of 2-byte size and output 24-bit size, I think! And we can just load the coefficients from RAM to registers and load sample to register and call the macro to do its thing, right?

I think I can stop here for now AND I have some questions but wanted to explain first what I’m trying to achieve…

- The coefficients that I intend to store in RAM should be stored in WHAT part of the data memory map?? Access RAM (I think so) or I can choose any bank I want?

As for the macro I intend to implement, Can someone give me an algorithm for it? so I can try to code it and you can correct me…I can see there’s 16-bit multiplication and addition involved at the same time…I also think I’ll have to use the hardware multiplier of PIC18F26K20
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,334
I also think I’ll have to use the hardware multiplier of PIC18F26K20[/SIZE][/FONT]
Yes, I think so too...

BTW, is this for your speech recognition system? If so, consider the following:

You will still have AC waveforms coming out of each of those filters. It's rather difficult to try to match one AC waveform to another, much less looking for multiple matches across a range of frequencies! Additionally, I think matching amplitude alone is not going to be sufficient. You may also need phase information.

Why not run an FFT across a fixed period of your data? You don't even need to compute all frequencies, just those of interest.

Then you can pattern match the phase/amplitude info against templates for various words.

I've never done this before, but if I were to do it, that's the approach I would try first.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Thanks Joeyd999 for your reply!

I have never done this before too...But i can't do anything else...I want to make this thing work...I think you guyz may have noticed that...

But one step at the time...i have to start somewhere... and this is my start...

I believe 100% with the help of AAC I can make this work using simple method...

Yes We Can...
 
Last edited:

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Come on guyz dont let me down...

ohk at least answer my question about storing constants (coefficient) in a RAM... i mean i want to create an array of 10 elements, each element should be 2 byte and how to assign values to each element???

i think i can try to write code if you guide me...

Also where to put that array?? i asked but no answer...in Acces RAM or what?
 

thatoneguy

Joined Feb 19, 2009
6,359
Yes, I think so too...

BTW, is this for your speech recognition system? If so, consider the following:

You will still have AC waveforms coming out of each of those filters. It's rather difficult to try to match one AC waveform to another, much less looking for multiple matches across a range of frequencies! Additionally, I think matching amplitude alone is not going to be sufficient. You may also need phase information.

Why not run an FFT across a fixed period of your data? You don't even need to compute all frequencies, just those of interest.

Then you can pattern match the phase/amplitude info against templates for various words.

I've never done this before, but if I were to do it, that's the approach I would try first.
I'm with this sentiment.

Attempting to match amplitudes of a spoken word WOULD be "The hard way"

An FFT of each "command" you want it to respond to would be much quicker than going through a train of analog.

When you add filters, you are out of the PIC mid-range controllers and into the dsPIC controllers (16 bit, w/SIMD* instructions, designed for this stuff)

*Single Instruction Multiple Data

Compare trying to figure out what a word was by looking at the squiggly trace on a scope, versus looking at a sonograph.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I know I have to involve pointer, indirect addressing...FSR0, FSR1...decrement/increment instruction....ima post my code in a few hours...5:10am and I still awake...lol
 

joeyd999

Joined Jun 6, 2011
6,334
Come on guyz dont let me down...

ohk at least answer my question about storing constants (coefficient) in a RAM... i mean i want to create an array of 10 elements, each element should be 2 byte and how to assign values to each element???

i think i can try to write code if you guide me...

Also where to put that array?? i asked but no answer...in Acces RAM or what?
Eric, where you put the data doesn't matter. Access RAM looks just like banked RAM, except you have less of it.

For efficient access, you'll be using one or more of the FSRs to address your arrays, so you won't even be using the access bit.

Really, it makes no matter whatsoever!
 

thatoneguy

Joined Feb 19, 2009
6,359
@ thatoneguy: can you please adress my post #35 before I post my code for that?
You can store it in the registers of disabled peripherals if you are tight on RAM, you can use standard RAM as well, do you need 20 words, or 20 bytes of data to store? Either can be handled in standard RAM.
 
Top