PDA

View Full Version : HPWM and 16F628A



Michael
- 13th February 2006, 18:57
After spending the morning looking at the TIMER modules and their associated registers, trying to figure out how I can generate a 38khz square wave for a remote control, I said to myself.....if only Picbasic had a statement that would simplify all of this.

I was just about to give up and ran across HPWM.

It can't be as simple as this can it?...


HWPM 1,127,38000 ?


CCP1 is RB3 on 16F628--Using a 4mhz xtal

Dave
- 13th February 2006, 22:35
Michael, Yes you are correct...

Dave Purola,
N8NTA

Bruce
- 13th February 2006, 23:27
This is in the PBP manual, but, the highest frequency at any osc speed is 32767Hz.

If you need to use the hardware PWM module, then you'll have to set it up manually.

With a 4MHz osc;


TRISB.3 = 0 ' RB.3=PWM output
PR2 = 25 ' Set PWM for approximately 38KHz
CCPR1L = 13 ' Set PWM Duty-Cycle to 50%
CCP1CON = %00001100 ' Mode select = PWM
T2CON = %00000100 ' Timer2 ON + 1:1 prescale
Or you could use any available I/O-pin with something like this;


DEFINE OSC 4

' setup the port pin to use
@ #define IRTX PORTB ; Define port to use for IR out
@ #define PIN 0 ; Define port pin to use for IR out

' Define IR signal bit timing (if needed)
Zero CON 40 ' 40 x 25uS = 1mS
One CON 80 ' 80 x 25uS = 2mS

' declare variables
Cycles VAR BYTE ' number of Cycles to generate

' setup port
PORTB.0 = 0 ' power-up with the LED off
TRISB.0 = 0 ' make the pin an output here
GOTO Main ' jump over IR routine to Main

Pulse: ; Generate "Cycles" number of 40kHz pulses
ASM ; 430 LED
bsf IRTX,PIN ; 1uS, LED=on ; pin ----/\/\/\---|>|---- gnd
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
goto $+1 ; + 2uS = 11uS
goto $+1 ; + 2uS = 13uS
bcf IRTX,PIN ; 1uS, LED=off
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
;nop ; +1uS <-- un-comment for 38kHz
goto $+1 ; + 2uS = 9uS
decfsz _Cycles,f ; + 1uS = 10S
goto _Pulse ; + 2uS = 12uS (13uS + 12uS = 40kHz)
return ; Add 2uS for return to caller
ENDASM

Main: ' Load Cycles & call Pulse. Pause whatever time you need in between

Cycles = Zero
CALL Pulse
PAUSE 1
Cycles = One
CALL Pulse
PAUSE 1
' Etc, etc,,
GOTO Main

END
We have several IR projects all done with the 16F628 in our Micro-Bot projects section here
http://www.rentron.com/Micro-Bot/index.htm you might also find useful.

Here's one example of how to use the 2nd routine. I was goofing with one of those Robo Sapien
robots the other day, and decided to make a simple 8-pin PIC IR transmitter that could attach
to my PC serial port to control the robot. Here's the code.


' Connections for a 12F683
' Pin #8 = gnd
' Pin #1 = Vcc
' GPIO.0 serial input from other controller or PC
' GPIO.1 IR LED drive ----/\/\/\---|>|----gnd (note: use a 940nm IRLED)
' 430 IR LED
' Need more range use a simple NPN or mosfet driver.
' Rest of I/O-pins available for whatever.

@ DEVICE PIC12F683, MCLR_OFF, INTRC_OSC_NOCLKOUT, WDT_OFF, BOD_ON, PWRT_ON
DEFINE OSC 4
DEFINE DEBUG_BAUD 2400
DEFINE DEBUGIN_REG GPIO
DEFINE DEBUGIN_BIT 0
DEFINE DEBUGIN_MODE 0 ' 0 = true mode

@ #DEFINE IRTX GPIO ; Define port to use for IR LED drive
@ #DEFINE PIN 1 ; Define port pin to use for IR LED

BotHdr CON 255 ' Carrier on for 255 + 25 cycles = 280
BotHdr2 CON 25 ' 280 x 25uS = 7mS carrier ON for synch pulse
Bot1 CON 3400 ' 3.4mS carrier off = 1 bit
Bot0 CON 800 ' 800uS carrier off = 0 bit
BotInter CON 38 ' 38 x 25uS = 955uS carrier ON for inter-bit period
Bot CON "B" ' Selects RoboSapien (used for synch byte) not necessary
X VAR BYTE ' Bit index pointer
Cycles var BYTE ' Holds number of 40KHz carrier cycles
Device VAR BYTE ' Holds device select byte
KeyNum VAR BYTE ' Key pressed

OSCCON = %01100000 ' Internal 4MHz osc
ADCON0 = 0 ' A/D off
CMCON0 = 7 ' Comparators off
ANSEL = 0 ' Set all digital
WPU = 0 ' Internal pull-ups = off
OPTION_REG = %10000000 ' Pull-ups = off, GPIO.2 = I/O, prescaler to Timer1
GPIO = %00000000 ' All outputs = 0 on boot
TRISIO = %00111101 ' GPIO,0=data in, GPIO,1=IRLED out, GPIO,2,3,4,5 unused

Main:
DEBUGIN [Device,KeyNum] ' With MSC+ serial terminal program, sending B#135
IF Device = Bot THEN ' will move bot backwards. Full list of commands
GOTO SendCmd ' can be found in lower section.
ENDIF
GOTO Main

SendCmd:
Cycles = BotHdr ' 1st part of synch pulse
CALL Pulse
Cycles = BotHdr2 ' 2nd part of 7mS synch pulse
CALL Pulse

FOR X = 7 to 0 STEP - 1 ' 8-bits per button command
IF KeyNum.0[X] = 1 THEN
PAUSEUS Bot1 ' high for logic 1 bit period
ELSE
PAUSEUS Bot0 ' or low for logic 0 bit period
ENDIF
Cycles = BotInter ' Inter-bit period between data bits
Call Pulse ' During these periods the carier is on
NEXT X
GOTO Main

Pulse: ' Generate "Cycles" number of 40kHz pulses
ASM
bsf IRTX,PIN ; 1uS, LED=on
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
goto $+1 ; + 2uS = 11uS
goto $+1 ; + 2uS = 13uS
bcf IRTX,PIN ; 1uS, LED=off
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
decfsz _Cycles,f ; + 1uS = 10S
goto _Pulse ; + 2uS = 12uS
return ; Add 2uS for return to caller
ENDASM

END

' Send ASCII character B followed by key commands below to
' control your RoboSapien from a PC or another PIC.

' A simple VB example to move RoboSapien forward would be;
' Private Sub Cmd_Forward_Click()
' MSComm1.Output = "B" & Chr$(134)
' End Sub

' Upper red commands
' Right arm up = 129
' Right arm down = 132
' Right arm in = 133
' Right arm out = 130
' Left arm up = 137
' Left arm down = 140
' Left arm in = 141
' Left arm out = 138
' Tilt body right = 131
' Tilt body left = 139

' Red commands - middle & lower controller
' Walk forward = 134
' Walk backward = 135
' Turn left = 136
' Turn right = 128
' Stop = 142
' Rht sensor pgm = 146
' Master command program = 144
' Program / play = 145
' Left sensor program = 147
' Sonic sens pgm = 148

' Green commands - upper controller
' Right hand thump = 161
' Right hand pickup = 164
' Lean backward = 165
' Rht hand throw = 162
' Sleep = 163
' Listen = 171
' Left hand throw = 170
' Lean forward = 173
' Left hand pickup = 172

' Green commands - middle & lower controller
' Right turn step = 160
' Backward step = 167
' Forward step = 166
' Reset = 174
' Left turn step = 178
' Right sensor program execute = 178
' Master command program execute = 176
' Wake up = 177
' Sonic sensor program execute = 180
' Left sensor program execute = 179

' Orange commands - upper controller
' Right hand sweep = 193
' High 5 = 196
' Right hand strike = 197
' Burp = 194
' Right hand strike 2 = 195
' Left hand strike 2 = 203
' Whistle = 202
' Left hand strike = 205
' Talk back = 204
' Left hand sweep = 201

' Orange commands - middle & lower controller
' Right hand strike 3 = 192
' Oops = 199
' Left hand strike 3 = 200
' Roar = 206
' Demo 1 = 210
' All demo = 208
' Power off = 209
' Dance demo = 212
' Demo 2 = 211

Have fun...;o}

Michael
- 14th February 2006, 14:27
Thanks Bruce, I saw that after my post about the maximimum freq.

I wonder why that is with 4 mhz to work with? Especially if it can be set up otherwise?

I was wondering, has there ever been any discussion about PBP being enhanced so it could do all (or some anyway) of all this module and register manipulation at the higher level language of PBP?

My problem is, I don't really use PBP on a frequent basis....but when I do, it all comes back to me pretty quickly because the statements are so user friendly and of course, about as close to "English" as you can get.

I don't know why they couldn't make the modules and registers more in this mode as well. ?

TIMER1 could be a statement with associated (and many, no doubt) options.

etc.

When you need to do something as an occasional user, it's an absolute hell because there really isn't any decent path that is shown in the databook.

You have to go from one page to another just to see what R/W bytes are in play and what bits do what.....it's very scattered and not organized well.

Anyway....just a thought and something for the suggestion box.