Tuesday, May 24, 2011
Controlling a nokia5110 lcd with software SPI on a pic16f84a
My newest project has been implementing a software SPI routine so that my pic (which lacks hardware SPI) can communicate with a cheap nokia 84x48 graphical lcd (later I will show how I wired it up). I've written subroutines in assembly for setting x,y address of the lcd's ram as well as sending data or commands for initialization (8bit, but could be easily modified to work with 9bit color lcd protocols I've seen). I plan on using a look up table to store standard character hex data so that I can make things easier for myself in upcoming projects. I know that my code is pretty inefficient so I plan on fixing it a little later (but not bad for just reading the datasheet and a few hours of coding). I just have the mcu writing "Hello World!" and drawing a video game character sprite at the bottom (I converted the image by hand, but I could easily write a program to do that for me). This is just the beginning, I plan on using this, as well as everything else I've been working on in my projects to come. I plan on adding the ability to animate/scroll text and images and will update the site with the code once I get the chance. I also plan on describing the SPI protocol and lcd commands in detail. For now I will post the code to just write "Hello World" and draw a sprite.
Start BSF 03h,5 ;switch from bank 0 to 1
MOVLW b'00000000' ;Out RB to output
MOVWF 06h
MOVLW b'00000' ;Out RA to output
MOVWF 05h
BCF 03h,5 ;switch from bank 1 to 0
;RB0=sclk
;RB1=sda
;RB2=D_C
;RB3=Sce
;RB4=reset
;RB5=disp pwr
Begin
bsf 06h,3 ;disable serial
bsf 06h,5 ;power on display
nop
bcf 06h,4 ;reset
nop
bsf 06h,4 ;release from reset
; sel extended instruction set (h=1)
movlw b'00100001'
movwf 0Ch
call spi_command
; set Vop (Contrast)
movlw b'10111001'
movwf 0Ch
call spi_command
; sel normal instruction set (h=0)
movlw b'00100000'
movwf 0Ch
call spi_command
; display normal mode
movlw b'00001100'
movwf 0Ch
call spi_command
;---------------------------
; draw H
movlw b'01111111'
movwf 0Ch
call spi_data
movlw b'00001000'
movwf 0Ch
call spi_data
movlw b'00001000'
movwf 0Ch
call spi_data
movlw b'00001000'
movwf 0Ch
call spi_data
movlw b'01111111'
movwf 0Ch
call spi_data
call _space
; draw e
movlw b'00001110'
movwf 0Ch
call spi_data
movlw b'00010101'
movwf 0Ch
call spi_data
movlw b'00010101'
movwf 0Ch
call spi_data
movlw b'00010101'
movwf 0Ch
call spi_data
movlw b'00001100'
movwf 0Ch
call spi_data
call _space
; draw l
movlw b'00000000'
movwf 0Ch
call spi_data
movlw b'01000001'
movwf 0Ch
call spi_data
movlw b'01111111'
movwf 0Ch
call spi_data
movlw b'00000001'
movwf 0Ch
call spi_data
movlw b'00000000'
movwf 0Ch
call spi_data
call _space
; draw l
movlw b'00000000'
movwf 0Ch
call spi_data
movlw b'01000001'
movwf 0Ch
call spi_data
movlw b'01111111'
movwf 0Ch
call spi_data
movlw b'00000001'
movwf 0Ch
call spi_data
movlw b'00000000'
movwf 0Ch
call spi_data
call _space
; draw o
movlw b'00001110'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00001110'
movwf 0Ch
call spi_data
call _space
; goto y=1,x=0
movlw b'00000001'
movwf 0Ch
movlw b'00000000'
movwf 0Dh
call setxy
; draw W
movlw b'01111110'
movwf 0Ch
call spi_data
movlw b'00000001'
movwf 0Ch
call spi_data
movlw b'00001110'
movwf 0Ch
call spi_data
movlw b'00000001'
movwf 0Ch
call spi_data
movlw b'01111110'
movwf 0Ch
call spi_data
call _space
; draw o
movlw b'00001110'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00001110'
movwf 0Ch
call spi_data
call _space
; draw r
movlw b'00011111'
movwf 0Ch
call spi_data
movlw b'00001000'
movwf 0Ch
call spi_data
movlw b'00010000'
movwf 0Ch
call spi_data
movlw b'00010000'
movwf 0Ch
call spi_data
movlw b'00001000'
movwf 0Ch
call spi_data
call _space
; draw l
movlw b'00000000'
movwf 0Ch
call spi_data
movlw b'01000001'
movwf 0Ch
call spi_data
movlw b'01111111'
movwf 0Ch
call spi_data
movlw b'00000001'
movwf 0Ch
call spi_data
movlw b'00000000'
movwf 0Ch
call spi_data
call _space
; draw d
movlw b'00001110'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00010001'
movwf 0Ch
call spi_data
movlw b'00001001'
movwf 0Ch
call spi_data
movlw b'01111111'
movwf 0Ch
call spi_data
call _space
; draw !
movlw b'01111101'
movwf 0Ch
call spi_data
;---------------------------
; goto y=5,x=0
movlw b'00000101'
movwf 0Ch
movlw b'00000000'
movwf 0Dh
call setxy
;draw image block 4
movlw b'10000111';1
movwf 0Ch
call spi_data
movlw b'11111101';2
movwf 0Ch
call spi_data
movlw b'10000001';3
movwf 0Ch
call spi_data
movlw b'01100001';4
movwf 0Ch
call spi_data
movlw b'00010001';5
movwf 0Ch
call spi_data
movlw b'11001001';6
movwf 0Ch
call spi_data
movlw b'00100101';7
movwf 0Ch
call spi_data
movlw b'00100101';8
movwf 0Ch
call spi_data
movlw b'11100001';9
movwf 0Ch
call spi_data
movlw b'00011001';10
movwf 0Ch
call spi_data
movlw b'00000101';11
movwf 0Ch
call spi_data
movlw b'00000011';12
movwf 0Ch
call spi_data
movlw b'00000011';13
movwf 0Ch
call spi_data
movlw b'00000001';14
movwf 0Ch
call spi_data
movlw b'00111001';15
movwf 0Ch
call spi_data
movlw b'11101101';16
movwf 0Ch
call spi_data
movlw b'00000111';17
movwf 0Ch
call spi_data
; goto y=4,x=0
movlw b'00000100'
movwf 0Ch
movlw b'00000000'
movwf 0Dh
call setxy
;draw image block 3
movlw b'00000111';1
movwf 0Ch
call spi_data
movlw b'00111100';2
movwf 0Ch
call spi_data
movlw b'01100100';3
movwf 0Ch
call spi_data
movlw b'01010011';4
movwf 0Ch
call spi_data
movlw b'11110000';5
movwf 0Ch
call spi_data
movlw b'00111000';6
movwf 0Ch
call spi_data
movlw b'11111001';7
movwf 0Ch
call spi_data
movlw b'11111011';8
movwf 0Ch
call spi_data
movlw b'10010011';9
movwf 0Ch
call spi_data
movlw b'11110100';10
movwf 0Ch
call spi_data
movlw b'11110100';11
movwf 0Ch
call spi_data
movlw b'01110100';12
movwf 0Ch
call spi_data
movlw b'01110000';13
movwf 0Ch
call spi_data
movlw b'00010000';14
movwf 0Ch
call spi_data
movlw b'00100100';15
movwf 0Ch
call spi_data
movlw b'10011111';16
movwf 0Ch
call spi_data
movlw b'11010000';17
movwf 0Ch
call spi_data
movlw b'01110000';18
movwf 0Ch
call spi_data
; goto y=3,x=0
movlw b'00000011'
movwf 0Ch
movlw b'00000000'
movwf 0Dh
call setxy
;draw image block 2
movlw b'00011100';1
movwf 0Ch
call spi_data
movlw b'00010110';2
movwf 0Ch
call spi_data
movlw b'00010010';3
movwf 0Ch
call spi_data
movlw b'00010010';4
movwf 0Ch
call spi_data
movlw b'00010011';5
movwf 0Ch
call spi_data
movlw b'00010001';6
movwf 0Ch
call spi_data
movlw b'00110001';7
movwf 0Ch
call spi_data
movlw b'00100000';8
movwf 0Ch
call spi_data
movlw b'01100000';9
movwf 0Ch
call spi_data
movlw b'01000000';10
movwf 0Ch
call spi_data
movlw b'11000000';11
movwf 0Ch
call spi_data
movlw b'10000000';12
movwf 0Ch
call spi_data
movlw b'00000000';13
movwf 0Ch
call spi_data
movlw b'00000010';14
movwf 0Ch
call spi_data
movlw b'00011111';15
movwf 0Ch
call spi_data
movlw b'01110001';16
movwf 0Ch
call spi_data
movlw b'11000000';17
movwf 0Ch
call spi_data
; goto y=2,x=12
movlw b'00000010'
movwf 0Ch
movlw b'00001100'
movwf 0Dh
call setxy
;draw image block 1
movlw b'00000001';12
movwf 0Ch
call spi_data
movlw b'00000001';13
movwf 0Ch
call spi_data
movlw b'00000011';14
movwf 0Ch
call spi_data
movlw b'00000010';15
movwf 0Ch
call spi_data
movlw b'00000010';16
movwf 0Ch
call spi_data
movlw b'00000011';17
movwf 0Ch
call spi_data
a goto a
;----------------------------
spi_command
bcf 06h,3 ;start serial transmission
bcf 06h,2 ;D_C=0
btfss 0Ch,7
goto c1
call one
goto c1n
c1 call zero
c1n btfss 0Ch,6
goto c2
call one
goto c2n
c2 call zero
c2n btfss 0Ch,5
goto c3
call one
goto c3n
c3 call zero
c3n btfss 0Ch,4
goto c4
call one
goto c4n
c4 call zero
c4n btfss 0Ch,3
goto c5
call one
goto c5n
c5 call zero
c5n btfss 0Ch,2
goto c6
call one
goto c6n
c6 call zero
c6n btfss 0Ch,1
goto c7
call one
goto c7n
c7 call zero
c7n btfss 0Ch,0
goto cd
call one
goto cdn
cd call zero
cdn bcf 06h,0
bsf 06h,3 ;end serial transmission
return
spi_data
bcf 06h,3 ;start serial transmission
bsf 06h,2 ;D_C=1
btfss 0Ch,0
goto b1
call one
goto b1n
b1 call zero
b1n btfss 0Ch,1
goto b2
call one
goto b2n
b2 call zero
b2n btfss 0Ch,2
goto b3
call one
goto b3n
b3 call zero
b3n btfss 0Ch,3
goto b4
call one
goto b4n
b4 call zero
b4n btfss 0Ch,4
goto b5
call one
goto b5n
b5 call zero
b5n btfss 0Ch,5
goto b6
call one
goto b6n
b6 call zero
b6n btfss 0Ch,6
goto b7
call one
goto b7n
b7 call zero
b7n btfss 0Ch,7
goto d
call one
goto dn
d call zero
dn bcf 06h,0
bsf 06h,3 ;end serial transmission
return
zero
bcf 06h,0
bcf 06h,1 ;0
bsf 06h,0 ;sclk pulse
return
one
bcf 06h,0
bsf 06h,1 ;1
bsf 06h,0 ;sclk pulse
return
_space ;send byte='00000000', draw space
movlw b'00000000'
movwf 0Ch
call spi_data
return
setxy
bsf 0Ch,6
call spi_command
bsf 0Dh,7
movf 0Dh,0
movwf 0Ch
call spi_command
return
end
Tuesday, May 10, 2011
Capacitive Touch Sensor for pic16F84A (no special hardware required)
Here is my newest project I've been working on. I'll get more details up when I have the time. In the mean while enjoy the video.
//return current;
}
Update: Sorry its been awhile since my last update. I've been busy with work and my other projects. The capacitive sensing input is really simple because everything is done in software. Here's my hand drawn schematic for the input stage generalized so that any mcu can be used (For some reason I haven't yet installed a schematic program on my netbook and I don't feel like booting up my other laptop).
It's amazing that all you really need is a single gpio and a resistor (the capacitance is provided by the traces on the breadboard). The ten megaohm resistor allows the discharge rate for the stray capacitance to be slowed down enough for the uC to measure. The uC just continually charges up this capacitance, puts the pin into high impedance by making it an input, and then counts until it measures the "capacitor" is discharged. This count can then be analyzed to determine if the pin has been pressed or not (the count increases if the button is pressed because your finger adds to the stray capacitance in parallel which increases the discharge time). That's pretty much all that's necessary other than some fancy algorithms for error proofing detection.
Update 2: I've finally gotten around to porting my capacitive touch sensing code to C. The code should work for most PICs and can be easily modified to change pin assignments and whatnot to work on any other chip you might need. Below you will find the function freqcapsense. All you need to do is call it and it will sense whether RA0 is being touch or not. I've included averaging multiple samples and an adjustable threshold in order to tweak the sensitivity and accuracy for any given setup. You can have it return a 1 or 0 for touch status or by commenting out the if else statement at the end and uncommenting the return current statement it will return the raw period value it is reading from the pin. Enjoy.
int freqcapsense(){
unsigned int avg;
unsigned int current=0;
unsigned int thresh=29;
unsigned int avg;
unsigned int current=0;
unsigned int thresh=29;
unsigned int trials=10;
while(trials>0){
TRISA=0b0;
RA0=1;
delay();
TRISA=0b1;
while(RA0==1){current++;}
trials--;
avg=(avg+current)/2;
}
while(trials>0){
TRISA=0b0;
RA0=1;
delay();
TRISA=0b1;
while(RA0==1){current++;}
trials--;
avg=(avg+current)/2;
}
if((current-avg)>thresh){return 1;}
else{return 0;}
else{return 0;}
//return current;
}
Saturday, January 22, 2011
Interfacing a SNES controller and 16x2 LCD to the PIC16f84A
I threw together this demo this morning after finding two snes controllers last night for $1.90 each at a thrift store.
Controller after I meticulously cleaned it.
Next I researched online a bit to find out how to read the button presses (this pdf helped: http://www.parallax.com/dl/docs/prod/prop/hydra-ch6all-v1.0.pdf). The controller uses a active low 16bit wide shift register (last 4bits are always high). Read the pdf for the specifics of pulsing the latch and clock. All that needs to be hooked up is +5v, gnd, Clock, Latch, and Data (the pinout can be found here: http://pinouts.ru/Game/snescontroller_pinout.shtml). I used solid core copper wire that was folded over once to thicken it enough to hold when inserted in the connector socket since I didn't have a proper connector.
Perfect for prototyping.
Next I wired up the breadboard. The first part was the power supply which consists of a AA battery and a max756 to step it up to the 5v needed by the controller, lcd, and pic.
Indicator led and switch to turn on the power.
Next I wired up the PIC16f84A with an external RC clock and icsp header.
Finally I wired the controller (to port A) and lcd (to port B) up and started coding.
The lcd printing button presses.
The code basically initializes the lcd and then continually polls the controller and when a certain button is pressed sends the character to the display. This way the display types the button presses and when you want to clear the screen you just press start or select.
For now I will post the code below (in assembly, and sorry about the formatting, it looked much nicer in mplab) and will upload a schematic and video of it in action when I get some time.
Note: The code provided below is not optimized and is rather messy. Remember that I am not responsible if you try and make this and it doesn't work or ends up blowing up. This was just meant as a proof of concept and a neat morning wake up exercise for me.
UPDATE:
Sorry its been awhile, I've been busy at school, but here is the schematic. Note that I left out the step up converter circuitry.
Code:
;Shawn Maxwell ;
;1/22/11 ;
;LCD SNES ;
;;;;;;;;;;;;;;;;;
;Writes SNES key presses to HD44780 compatable LCD in 4bit mode
COUNT1 equ 08h ;delay constants
COUNT2 equ 09h
Start BSF 03h,5 ;switch from bank 0 to 1
MOVLW b'00000000' ;Out RB to output
MOVWF 06h
MOVLW b'11100' ;Out RA0,1 to output, RA2-4 to input
MOVWF 05h
BCF 03h,5 ;switch from bank 1 to 0
;RS = RB0, EN = RB1, D4-D7 = RB2-RB5
;CLK = RA0, Latch = RA1, Data = RA2
Begin
call LongDelay
call LongDelay
;initialize LCD
movlw b'00001010' ;Out EN high
call Out ;;;;
movlw b'00001000' ;Out to 4 bit operation (note: 1 nibble
operation)
call Out ;;;; ;Out EN low
movlw b'00001010' ;Out EN high
call Out ;;;;
movlw b'00001000' ;Function Out, 8 bit
call Out ;;;; ;Out EN low
movlw b'00100010' ;Out EN high
call Out ;;;;
movlw b'00100000' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Out EN high
call Out ;;;;
movlw b'00000000' ;Display ON, Cursor On, Cursor Blinking
call Out ;;;; ;Out EN low
movlw b'00111110' ;Out EN high
call Out ;;;;
movlw b'00111100' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Out EN high
call Out ;;;;
movlw b'00000000' ;Entry Mode, Increment cursor position, No
display shift
call Out ;;;; ;Out EN low
movlw b'00011010' ;Out EN high
call Out ;;;;
movlw b'00011000' ;2nd nibble
call Out ;;;; ;Out EN low
;initialize SNES controller and read data
SNES
movlw b'00011' ;set Latch, CLK high
movwf 05h
call Delay
movlw b'00001' ;set Latch low
movwf 05h
call Delay
movlw b'00000' ;set CLK low
movwf 05h
call Delay
movlw b'00010' ;pulse Latch high
movwf 05h
call Delay
movwf b'00000'
movwf 05h
btfss 05h,2 ;read B
call buttonB
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Y
call buttonY
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Select
call Clear
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Start
call Clear
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Up
call buttonUp
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Down
call buttonDown
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Left
call buttonLeft
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read Right
call buttonRight
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read A
call buttonA
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read X
call buttonX
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read L
call buttonL
call Delay
call Delay
movlw b'00001' ;Pulse CLK
movwf 05h
call Delay
call Delay
movlw b'00000'
movwf 05h
call Delay
call Delay
btfss 05h,2 ;read R
call buttonR
call Delay
call Delay
goto SNES
;--------------------------------------------
buttonB
movlw b'00010011' ;Out EN,RS high
call Out ;;;;
movlw b'00010001' ;B
call Out ;;;; ;Out EN low
movlw b'00001011' ;Out EN,RS high
call Out ;;;;
movlw b'00001001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonY
movlw b'00010111' ;Out EN,RS high
call Out ;;;;
movlw b'00010101' ;Y
call Out ;;;; ;Out EN low
movlw b'00100111' ;Out EN,RS high
call Out ;;;;
movlw b'00100101' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
Clear
movlw b'00000010' ;Out EN,RS high
call Out ;;;;
movlw b'00000000' ;Clear
call Out ;;;; ;Out EN low
movlw b'00000110' ;Out EN,RS high
call Out ;;;;
movlw b'00000100' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonUp
movlw b'00010111' ;Out EN,RS high
call Out ;;;;
movlw b'00010101' ;Up
call Out ;;;; ;Out EN low
movlw b'00010111' ;Out EN,RS high
call Out ;;;;
movlw b'00010101' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonDown
movlw b'00010011' ;Out EN,RS high
call Out ;;;;
movlw b'00010001' ;Down
call Out ;;;; ;Out EN low
movlw b'00010011' ;Out EN,RS high
call Out ;;;;
movlw b'00010001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonLeft
movlw b'00011111' ;Out EN,RS high
call Out ;;;;
movlw b'00011101' ;Left
call Out ;;;; ;Out EN low
movlw b'00111111' ;Out EN,RS high
call Out ;;;;
movlw b'00111101' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonRight
movlw b'00011111' ;Out EN,RS high
call Out ;;;;
movlw b'00011101' ;Right
call Out ;;;; ;Out EN low
movlw b'00111011' ;Out EN,RS high
call Out ;;;;
movlw b'00111001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonA
movlw b'00010011' ;Out EN,RS high
call Out ;;;;
movlw b'00010001' ;A
call Out ;;;; ;Out EN low
movlw b'00000111' ;Out EN,RS high
call Out ;;;;
movlw b'00000101' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonX
movlw b'00010111' ;Out EN,RS high
call Out ;;;;
movlw b'00010101' ;X
call Out ;;;; ;Out EN low
movlw b'00100011' ;Out EN,RS high
call Out ;;;;
movlw b'00100001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonL
movlw b'00010011' ;Out EN,RS high
call Out ;;;;
movlw b'00010001' ;L
call Out ;;;; ;Out EN low
movlw b'00110011' ;Out EN,RS high
call Out ;;;;
movlw b'00110001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
buttonR
movlw b'00010111' ;Out EN,RS high
call Out ;;;;
movlw b'00010101' ;R
call Out ;;;; ;Out EN low
movlw b'00001011' ;Out EN,RS high
call Out ;;;;
movlw b'00001001' ;2nd nibble
call Out ;;;; ;Out EN low
movlw b'00000010' ;Clear outputs, EN high
movwf 06h
return
Out
movwf 06h
Loop01 decfsz COUNT1,1
goto Loop01
Loop02 decfsz COUNT1,1
goto Loop02
return
Delay
Loop1 decfsz COUNT1,1
goto Loop1
Loop2 decfsz COUNT1,1
goto Loop2
return
LongDelay
loop1 decfsz COUNT1,1
goto loop1
loop2 decfsz COUNT1,1
goto loop2
loop3 decfsz COUNT1,1
goto loop3
loop4 decfsz COUNT1,1
goto loop4
loop5 decfsz COUNT1,1
goto loop5
loop6 decfsz COUNT1,1
goto loop6
loop7 decfsz COUNT1,1
goto loop7
loop8 decfsz COUNT1,1
goto loop8
loop9 decfsz COUNT1,1
goto loop9
loop10 decfsz COUNT1,1
goto loop10
loop11 decfsz COUNT1,1
goto loop11
loop12 decfsz COUNT1,1
goto loop12
loop13 decfsz COUNT1,1
goto loop13
loop14 decfsz COUNT1,1
goto loop14
loop15 decfsz COUNT1,1
goto loop15
loop16 decfsz COUNT1,1
goto loop16
loop17 decfsz COUNT1,1
goto loop17
loop18 decfsz COUNT1,1
goto loop18
loop19 decfsz COUNT1,1
goto loop19
loop20 decfsz COUNT1,1
goto loop20
return
end
Sunday, December 5, 2010
Cheap POV Text Display
I decided to try and build a really cheap POV display in one afternoon using only parts I had on hand. I used a PIC16f84a, five red 3mm leds, a photo-interrupter, scrap aluminum and plastic, an old dvd-r 50 pack case, and finally an old motor. I decided to use a slip ring to transfer power to the rotating electronics. The interesting thing is that I only used one contact that connects to the bottom via a "cat wisker" wire (for Vcc), while using the entire metal motor casing, shaft, and aluminum base as the ground (this simplifies the mechanics a lot). The entire thing is powered by a 3.7V lithium polymer battery. I realize that it is rather ugly, but I consider it a success due to the fact that I completed it in a few hours and had all the parts already on hand. Next time I plan on making a much nicer POV clock/display (have to wait until I get a break from classes). Enjoy.
Headphone Amps
This is my latest headphone amp built this last summer. The casing is your run of the mill Radio Shack project box. I pulled the volume pot and knob from an old broken boom box. Inside is a Chu Moy based off of the Burr Brown OPA2132. The dual power supply is simply resistively divided from the 9V input with caps on each rail. Nothing special except the convenience and size. Sounds pretty good.
Here's my second headphone amp built about two years ago. I used a Radio Shack 4AAA battery case. It uses two lm386 amps (I know they are jellybean chips but at low output currents they still sound pretty good). I added a low pass filter on the input for added bass (I was going through a period where I really liked powerful bass). I've added a max756 to step up the 1.5V to 5V (battery life is pretty good at around 15+ hours). I was planning on adding a digital volume control (ds1802, and hence the two buttons on the side) but ran out of room. My next revision for a pocket amp will be in the same case, but will feature a custom etched smt pcb and digital volume control.
This one was my first headphone amp I ever built (made it freshman year). The case is a recycled plastic hair pin container that I "borrowed" from my mom. It uses the same chip as my desktop amp above, runs off of a nine volt, and has an analog volume control. The power supply splits the single source using a resistive divider and buffers and stabilizes the output with the help of a opamp. Not my best work, but it sounds pretty good and I learned a lot making this.
Subscribe to:
Posts (Atom)


























