0% found this document useful (0 votes)
166 views5 pages

Pic 18f452 Implementation of Digital Filters

This document contains code for an adaptive noise cancelling algorithm implemented on a PIC microcontroller. It uses a least mean squares (LMS) approach with 4 tap filters to estimate and subtract noise from a signal. The key steps are: 1. It samples an input channel for the noise and signal periodically using timers and ADC interrupts. 2. It calculates estimates of the noise in the signal by multiplying stored noise samples by adaptive filter weights. 3. It calculates the error between the estimated noise and actual signal and updates the filter weights using the LMS algorithm. 4. The updated weights are then used on the next sample to improve the noise estimation and cancellation.

Uploaded by

ishakubalami
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
166 views5 pages

Pic 18f452 Implementation of Digital Filters

This document contains code for an adaptive noise cancelling algorithm implemented on a PIC microcontroller. It uses a least mean squares (LMS) approach with 4 tap filters to estimate and subtract noise from a signal. The key steps are: 1. It samples an input channel for the noise and signal periodically using timers and ADC interrupts. 2. It calculates estimates of the noise in the signal by multiplying stored noise samples by adaptive filter weights. 3. It calculates the error between the estimated noise and actual signal and updates the filter weights using the LMS algorithm. 4. The updated weights are then used on the next sample to improve the noise estimation and cancellation.

Uploaded by

ishakubalami
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

#include <18f452.

h>
#use delay(clock = 40000000)
#fuses H4,PUT,NOWDT
#include <lmslib.h>
#include <lmslib.c>
#include <clcd.c>
// Globals......................................................................
...............\\
const int filter_length = 4;
int buf[filter_length] = {0}; // Store ADC Values ....................\\
int signal,noise,EOB,B OB,tptr,buf_count;
int out,i,outs;
// LMS vari ables...............................................................
.............\\
split_float fout, *fptr;
split w0,w1,w2,w3;
split n0,n1,n2,n3;
split es0,es1,es2,es3;
split up0,up1,up2,up3;
split s, eta, err, error, * ptr;
#INT_TIMER2
void t2_isr() {
T2CON = 0x06;
// Restart Timer
// Sample channel 0 for noise
ADCON0 = 0x81;
// Set ADC Channel 0
es0.real = 0; es0.frach = 0; es0.fracl = 0; es0.sign
es1.real = 0; es1.frach = 0; es1.fracl = 0; es1.sign
es2.real = 0; es2.frach = 0; es2.fracl = 0; es2.sign
es3.real = 0; es3.frach = 0; es3.fracl = 0; es3.sign
up0.real = 0; up0.frach = 0; up0.fracl = 0; up0.sign
up1.real = 0; up1.frach = 0; up1.fracl = 0; up1.sign
up2.real = 0; up2.frach = 0; up2.fracl = 0; up2.sign
up3.real = 0; up3.frach = 0; up3.fracl = 0; up3.sign
err.real = 0; err.frach = 0; err.fracl = 0; err.sign

=
=
=
=
=
=
=
=
=

0;
0;
0;
0;
0;
0;
0;
0;
0;

delay_us(6);
ADCON0 = 0x85;
// Start ADC Conversion
while(bit_test(ADCON0,2));
noise = ADRESH;
// Read ADC Value
ADCON0 = 0x89;
// Set ADC Channel 1
// Buffer Noise Values and convert to floats
buf_count = filter_length;
FSR1L = tptr;
FSR2L = &n0.sign;
#asm
// Add the latest ADC value to the buffer
movf EOB,0
// Move to W Register
cpfseq FSR1L
// Check if ptr is at EOB
bra neq
movff noise,INDF1
//ptr has reached EOB: insert value
movff BOB,FSR1L
//Reset pointer to begining of Buffer
bra
end
neq:
movff noise,POSTDEC1 //Put data in Buffer and advance ptr

end:
// Unload ADC Value from Buffer and poppulate n0..nN
unl:
movf
BOB,0
cpfseq FSR1L
bra
aneq
movff EOB,FSR1L
//
movff INDF1,out
bra
aend
aneq:
movff
PREINC1,out
aend:

// Move to W Register
// Check if ptr is at BOB
Pointer is at BOB.. Warp Pointer to EOB
// Extract Data
// Extract Data from Buffer

// Store popped value into n0


movlw
0x80
cpfslt
out
// Skip next inst if (f) < (W)
bra
n0pos
movlw
0x7f
bsf
STATUS,0
subfwb
out,W
// W-f-B -> W
clrf
INDF2
incf
POSTINC2
movff
WREG,POSTINC2
clrf
POSTINC2
bra
dne
n0pos:
movlw
0x7f
subwf
out,W
// f - W -> W
clrf
POSTINC2
movff
WREG,POSTINC2
clrf
POSTINC2
dne:
decfsz
buf_count
bra
unl
#endasm
tptr = FSR1L;
// Sample Channel 1 for Signal
ADCON0 = 0x8d;
while(bit_test(ADCON0,2));
signal = ADRESH;

// Start ADC Conversion


// Read ADC Value

if (signal>=127) {
signal = signal-127;
s.frach = signal;
s.fracl = signal;
s.real = 0;
s.sign = 0;
}
else {
signal = 128-signal;
s.frach = signal;
s.fracl = signal;
s.real = 0;
s.sign = 1;
}
// Calculate estimate using...... //' esN = wN * nN;'

FSR0L = &w0.sign; FSR1L = &n0.si gn; FSR2L = &es0.sign;


FSR0L = &w1.sign; FSR1L = &n1.si gn; FSR2L = &es1.sign;
FSR0L = &w2.sign; FSR1L = &n2.si gn; FSR2L = &es2.sign;
FSR0L = &w3.sign; FSR1L = &n3.si gn; FSR2L = &es3.sign;
// Change Sign of Es timates......//'es0 = -es0;'
es0.sign ^= 1;
es1.sign ^= 1;
es2.sign ^= 1;
es3.sign ^= 1;

mul();
mul();
mul();
mul();

// Calculate Error...............//' error = s + es0..esN;'


FSR0L = &s.sign; FSR1L = &es0.sign; FSR2L = &error.sign; add();
FSR0L = &error.sign; FSR1L = &es1.s ign; FSR2L = &error.sign; add();
FSR0L = &error.sign; FSR1L = &es2.s ign; FSR2L = &error.sign; add();
FSR0L = &error.sign; FSR1L = &es3.s ign; FSR2L = &error.sign; add();
// Modulate Error using learning constant.......//' err = error*eta;'
FSR0L = &error.sign; FSR1L = &eta .sign; FSR2L = &err.sign; mul();
FSR0L
FSR0L
FSR0L
FSR0L

// Calculate Weig ht Updates.......//' up0 = err


&err.sign; FSR1L = &n0.si gn; FSR2L = &up0.sign;
&err.sign; FSR1L = &n1.si gn; FSR2L = &up1.sign;
&err.sign; FSR1L = &n2.si gn; FSR2L = &up2.sign;
&err.sign; FSR1L = &n3.si gn; FSR2L = &up3.sign;

=
=
=
=

// Apply updates to weights.......//' wN = wN + upN;'


FSR0L = &w0.sign; FSR1L = &up0.sign; FSR2L = &w0.sign;
FSR0L = &w1.sign; FSR1L = &up1.sign; FSR2L = &w1.sign;
FSR0L = &w2.sign; FSR1L = &up2.sign; FSR2L = &w2.sign;
FSR0L = &w3.sign; FSR1L = &up3.sign; FSR2L = &w3.sign;
// Change Sign of Esti mates......//'es0 = -es0;'
if(error.frach > 80) error.frach = 80;
if(error.sign)
outs = 127 - error.frach;
else
outs = error.frach + 127;
PORTD = outs;
}
void main() {
// Setup Ports and Peripherals
set_tris_d(0);
lcd_init();
// Set sampling rate of 8000 Hz
T2CON = 0x06;
PR2 = 76;
// Setup ADC for conversion
ADCON0 = 0x85;

// Start ADC:

* n0..nN;'
mul();
mul();
mul();
mul();
add();
add();
add();
add();

ADCON1 = 0x02;

// Right Justified Result, All Analog

// Enable Timer in terrupts for sampling.


enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
// Initialize LMS variables
ptr = &w0; fix8x16(0.0,ptr);
ptr = &w1; fix8x16(0.0,ptr);
ptr = &w2; fix8x16(0.0,ptr);
ptr = &w3; fix8x16(0.0,ptr);
ptr = &es0; fix8x16(0.0,ptr);
ptr = &es1; fix8x16(0.0,ptr);
ptr = &es2; fix8x16(0.0,ptr);
ptr = &es3; fix8x16(0.0,ptr);
ptr = &up0; fix8x16(0.0,ptr);
ptr = &up1; fix8x16(0.0,ptr);
ptr = &up2; fix8x16(0.0,ptr);
ptr = &up3; fix8x16(0.0,ptr);
ptr = &err; fix8x16(0.0,ptr);
ptr = &eta; fix8x16(0.1,ptr);
ptr = &error; fix8x16(0.0,ptr);
// Initialize buffer pointers for LMS
EOB = &buf[0];
BOB = &buf[filter_length-1];
tptr = BOB;
while(1) {
}
}
struct lcd_pin_map
boolean
boolean
boolean
boolean
int
} lcd;

{
rs;
unused1;
unused2;
enable;
data : 4;

#byte lcd = 0xf82

// This structure is overlayed


// on to an I/O port to gain
// access to the LCD pins.
//
//
//
// This puts the entire structure
// on to port C (at address 7)

byte CONST LCD_INIT_STRING[4] = {0x28, 0xc, 1, 6};


byte CONST LCD_LINE_ADDRESSES[4] = {0x00, 0x40, 0x14, 0x54};
// Sends a single nibble to the LCD.
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;

}
// Sends a whole byte to the LCD by making use of the Send nibble function
// The first parameter address decided whet her the byte is an instruction or dat
a
void lcd_send_byte( byte address, byte n ) {
delay_ms(3);
lcd.rs = 0;
delay_us(1);
lcd.rs = address;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
// Initializes the LCD display..
void lcd_init() {
byte i;
set_tris_c(0);
lcd.rs = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
// Sets the cursor on the screen where the character is to be printed.
void lcd_gotoxy( byte x, byte y) {
byte address;
address=lcd_line_addresses[y]+x;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( byte c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
case '\b'
default
}
}

break;
: lcd_send_byte(0,0x10); break;
: lcd_send_byte(1,c);
break;

You might also like