PDA

View Full Version : 18F4680 PWM 2 different frequencies



Macgman2000
- 13th October 2011, 23:44
Hello,

I am using a 18F4680 to set 4 servos to center position (in main loop), also running Hardware PWM @ 38Khz, and trying to module the 38Khz @ 1ms on / 1ms off toggle. I tried setting up an interrupt but this seems to hose my main loop.

1). what code is required to set up an interrupt on this chip body?
2). is there an easier way like modulating the output of the 38Khz signal to give burst 1ms on / 1ms off output?

My code is below, it works for outputting 4 servo control signals in the main loop, and hardware PWM output. I commented out the interrupt code because there is a problem with it. Basically what I wanted it to do is output a 1Khz continuous toggle via interrupt on an output pin.

Best Regards,
Nick


'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : Nicholas Amireh] *
'* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 8/5/2010 *
'* Version : 1.0 *
'* Notes : 18F4680 *
'* : use MPASM to compile *
'************************************************* ***************
INCLUDE "Modedefs.Bas"
DEFINE OSC 20

' DEFINE INTHAND myint

; The 18F family utilizes port latches to set/reset all I/O. Using portX = 1
; or portX = 0 to re/set a port will not work. This nomenclature is only good
; for reading port status. To alter port status use LATX = 1 or LATX = 0.


; Set port direction and turn off unused peripherals
CMCON = 7 ' shut offcomparators
TRISA = %00000000 ' Set PORTA to input "1" or output "0"
TRISB = %00000000 ' set portB to output "0" or input "1"
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000

ADCON1 = %00001111 ' bit 0 ~ bit 3 sets ports as digital I/O. 1 = digital, 0 = analog
ADCON0 = %00000000 ' bit 0 disables A/D converter module.
ECCP1CON = %00000000 ' bit 0 ~ bit 3 turns off capture/compare/PWM

' Initialize Interrupts
'T1CON = %00100000 ' stop TMR1
'PIR1.0 = 0 ' clear bit 0 TMR1 interrupt flag
'TMR1H = $00 ' load timer 1 and 2 with 00, max of 65,535 * 8 prescaler before interrupt
'TMR1L = $00 '
'INTCON = $C0 ' enable global GIE and peripheral PEIE interrupts
'T1CON = %00110001 ' start TMR1
'PIE1 = $01 ' Enable TMR1 overflow interrupt



centM con 1500 ;motor stop
forM con 2000 ;motor forward
revM con 1000 ;motor reverse
trim1 con 100
trim2 con 100
trim3 con 100
trim4 con 100

Sensors var byte
portcc var LATC.0
poro var byte
duty var byte

; initialize power on state of ports
LATD = 0 ' force latches on portD to low
LATA = 0
LATB = 0
LATC = 0

' asm
'myint
' bsf _portcc ;diagnostic to measure frequency and duration of interrupt
' call _timee ; if signal is lost put everything in fail safe position

' retfie ; Return from interrupt
'endasm

'timee:
' LATC.0 = 0
' endif

'return
ECCP1CON = %11001100 ' bit 0 ~ bit 3 turns off capture/compare/PWM
T2CON = %00010100 ' Turn on Timer2, Prescale=4
PR2 = 128 ' Set PR2 to get 5KHz PWM out

duty = 64
ECCPR1L = DUTY
ECCP1CON.4 = duty.0
ECCP1CON.5 = duty.1


Mainloop:
Sensors = portA & %00011111

select case sensors

case %00000000 ; all motors stop
portbb = %00001111
pauseus CentM
portbb = %00000000


case %00000001 ; go forward
portbb = %00001111
pauseus form
portbb = %00000000


case %00000010 ; go reverse
portbb = %00001111
pauseus revm
portbb = %00000000


case %00000100
; wheel assingnment portbb = X X X X RL RR FL FR
portbb = %00000011 ; go left
pauseus revm
portbb = %00000000

portbb = %00001100
pauseus form
portbb = %00000000


case %00001000 ; go right
portbb = %00000011
pauseus form
portbb = %00000000

portbb = %00001100
pauseus revm
portbb = %00000000


case %00010000 ; spin in place
portbb = %00000101
pauseus form
portbb = %00000000

portbb = %00001010
pauseus revm
portbb = %00000000


end select

pause 16





goto mainloop

Macgman2000
- 14th October 2011, 16:55
I went through the data sheet but I seem to be missing something. I can't get the interrupt to work. Code enclosed.


'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : Nicholas Amireh] *
'* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 8/5/2010 *
'* Version : 1.0 *
'* Notes : 18F4680 *
'* : use MPASM to compile *
'************************************************* ***************
INCLUDE "Modedefs.Bas"
DEFINE OSC 20

' DEFINE INTHAND myint

; The 18F family utilizes port latches to set/reset all I/O. Using portX = 1
; or portX = 0 to re/set a port will not work. This nomenclature is only good
; for reading port status. To alter port status use LATX = 1 or LATX = 0.


; Set port direction and turn off unused peripherals
CMCON = 7 ' shut offcomparators
TRISA = %00000000 ' Set PORTA to input "1" or output "0"
TRISB = %00000000 ' set portB to output "0" or input "1"
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000

ADCON1 = %00001111 ' bit 0 ~ bit 3 sets ports as digital I/O. 1 = digital, 0 = analog
ADCON0 = %00000000 ' bit 0 disables A/D converter module.
ECCP1CON = %00000000 ' bit 0 ~ bit 3 turns off capture/compare/PWM
T2CON = %00000101 ' %00000100 = TMR2 ON 1:1 pre-scale
' %00000101 = TMR2 ON 1:4 pre-scale
' %00000110 = TMR2 ON 1:16 pre-scale

' Initialize Interrupts
TMR1H = $FE ' load timer 1 and 2 with 00, max of 65,535 * 8 prescaler before interrupt
TMR1L = $00
RCON = %00011011
INTCON = %10100000 ; bit 5 enables/disables timer1 interrupt
INTCON2 = %10000100
INTCON3 = %00000000
PIE1 = %00000001
IPR1 = %00000001



centM con 1500 ;motor stop
forM con 2000 ;motor forward
revM con 1000 ;motor reverse
trim1 con 100
trim2 con 100
trim3 con 100
trim4 con 100

Sensors var byte
duty var byte
W_TEMP var BYTE bank0 system
status_temp var BYTE
bsr_temp var byte

portcc var LATC.0
portbb var LATB

; initialize power on state of ports
LATD = 0 ' force latches on portD to low
LATA = 0
LATB = 0
LATC = 0
goto intro
asm
myint
movwf W_TEMP
movff STATUS, _status_temp
movff BSR, _bsr_temp

movlw 0x01
xorwf LATC,f ; toggle

movff _bsr_temp, BSR
movf W_TEMP, w
movff _status_temp, STATUS
retfie ; Return from interrupt
endasm

intro:
ECCP1CON = %11001100 ' bit 0 ~ bit 3 turns off capture/compare/PWM
T2CON = %00010100 ' Turn on Timer2, Prescale=4
PR2 = 128 ' Set PR2 to get 5KHz PWM out

duty = 64
ECCPR1L = DUTY
ECCP1CON.4 = duty.0
ECCP1CON.5 = duty.1


Mainloop:
Sensors = portA & %00011111

select case sensors

case %00000000 ; all motors stop
portbb = %00001111
pauseus CentM
portbb = %00000000


case %00000001 ; go forward
portbb = %00001111
pauseus form
portbb = %00000000


case %00000010 ; go reverse
portbb = %00001111
pauseus revm
portbb = %00000000


case %00000100
; wheel assingnment portbb = X X X X RL RR FL FR
portbb = %00000011 ; go left
pauseus revm
portbb = %00000000

portbb = %00001100
pauseus form
portbb = %00000000


case %00001000 ; go right
portbb = %00000011
pauseus form
portbb = %00000000

portbb = %00001100
pauseus revm
portbb = %00000000


case %00010000 ; spin in place
portbb = %00000101
pauseus form
portbb = %00000000

portbb = %00001010
pauseus revm
portbb = %00000000


end select

pause 16

goto mainloop

Demon
- 14th October 2011, 17:42
I know little of interrupts, but the first place I would start is here:

http://www.picbasic.co.uk/forum/showthread.php?t=3251

Robert

Macgman2000
- 14th October 2011, 19:37
Thanks Robert for pointing me to the thread. I am extremely frustrated with this chip body. It is too many layers of interwoven configurations. I mean a simple G%D D&^N interrupt is a chore....sigh. I am stuck trying to get this to work....


Nick