PDA

View Full Version : Problem using ASM instruction



ewandeur
- 28th March 2008, 16:49
Hello !

I'm using a PIC12F675 to emulate a IR remote control, using a ASM routine to create 38Khz - 40 Khz pulses extracted from a microchip app.note (Keith Curtis AN91094).
The program compiles with no problem, but didn't work at all.

I've tried many code variations, but it still didn't work, poor me!!
Is there some trick with the compiler? setup or something?

Did someone use only PB instead of using ASM subroutines?

Please HELP!!!!

There is my last try...

@ DEVICE pic12F675
@ DEVICE PIC12F675, XT_OSC
@ DEVICE pic12F675, WDT_ON
@ DEVICE pic12F675, PWRT_ON
@ DEVICE pic12F675, MCLR_OFF
@ DEVICE pic12F675, BOD_ON
' Internal Oscillator
' Enable watch dog timer
' Enable power up timer
' Disable MCLR pin
' Enable brown out detect



DEFINE OSC 3

TRISIO.0 = 0 ' set GPIO.0 as output
TRISIO.1 = 1 ' set GPIO.0 as input
TRISIO.2 = 1 ' set GPIO.0 as input

CMCON = 7 ' turn off analog comparator
ADCON0.0 = 0
ADCON0.1 = 0
ADCON0.2 = 0
OPTION_REG.7 = 0
VRCON = 0
ANSEL = 0

'// Setup IR bit widths / carrier cycle times
Header CON 96 '// Header = (96 * 25uS) = 2.4mS burst
Zero CON 24 '// Zero = (24 * 25uS) = 0.6mS burst
One CON 48 '// One = (48 * 25uS) = 1.2mS burst

'// Define variables
Cycles VAR BYTE '// Holds number of 40KHz carrier cycles
i var byte

Loop:

if gpio.1 = 1 then
cycles = header
gosub pulse
cycles = zero
gosub dark

cycles = zero
gosub pulse
cycles = zero
gosub dark
endif

if gpio.2 = 1 then
cycles = header
gosub pulse
cycles = zero
gosub dark

cycles = one
gosub pulse

endif


Pulse: '// Emits # of 38.461 kHz bursts held in variable Cycles
for i = 1 to cycles
ASM ;// with auto delay between bursts
bsf GPIO, 0 ;// 1uS, LED=on [need 25uS total
goto $+1 ;// 3uS (2uS per goto $+1)
goto $+1 ;// 5uS
goto $+1 ;// 7uS
goto $+1 ;// 9uS
goto $+1 ;// 11uS
goto $+1 ;// 13uS
bcf GPIO, 0 ;// 14uS, LED=off
decfsz _Cycles,F ;// 24uS
goto $+1 ;// 16uS
goto $+1 ;// 18uS
goto $+1 ;// 20uS
goto $+1 ;// 22uS
retlw 0 ;// 23uS (Testing condition????)
ENDASM
next i

return

Dark:
for i = 1 to cycles
ASM ;// with auto delay between bursts
bcf GPIO, 0 ;// 1uS, LED=on [need 25uS total
goto $+1 ;// 3uS (2uS per goto $+1)
goto $+1 ;// 5uS
goto $+1 ;// 7uS
goto $+1 ;// 9uS
goto $+1 ;// 11uS
goto $+1 ;// 13uS
goto $+1 ;// 13uS
goto $+1 ;// 13uS
goto $+1 ;// 16uS
goto $+1 ;// 18uS
goto $+1 ;// 20uS
goto $+1 ;// 20uS
ENDASM
next i

return

mister_e
- 28th March 2008, 16:52
the main problem lies in your config settings. Your current setting imply you're using an external <4-8MHz crystal.

just change XT_OSC to INTRC_OSC_NOCLKOUT

are you sure of the AN number? any link to it?

EDIT: there's also something you want to make sure of... when you use BCF/BSF, you have to make sure you're in the right BANK unless you may just set/clear another register. Under each of your 2 ASM line, just add CHK?RP GPIO and see if it do something better. And for safety sake, change Cycles VAR BYTE to Cycles VAR BYTE BANK0.

ewandeur
- 28th March 2008, 16:57
Tks for your quick response Mr e!

But I am really using an external 3.56... MHZ xtal.
It will work if I change my code to use internal OSC instead of external Xtal ?

mister_e
- 28th March 2008, 17:38
Well there's a few mistake in your code anyways...

First, you check for a High level for your push-button... fine, but you enable the internal pull-up... thus this 'should' always consider that there's one push button pressed.

Next, you never loop in your code.. there's on missing GOTO LOOP.. this results in stack underflow.

Assuming your push button are connected between, gnd and the I/O and GND, using the internal weak-pull-ups, i would bet the following will work




@ DEVICE PIC12F675, XT_OSC
@ DEVICE pic12F675, WDT_ON
@ DEVICE pic12F675, PWRT_ON
@ DEVICE pic12F675, MCLR_OFF
@ DEVICE pic12F675, BOD_ON

DEFINE OSC 3

TRISIO.0 = 0 ' set GPIO.0 as output
TRISIO.1 = 1 ' set GPIO.0 as input
TRISIO.2 = 1 ' set GPIO.0 as input

CMCON = 7 ' turn off analog comparator
ADCON0.0 = 0
ADCON0.1 = 0
ADCON0.2 = 0
OPTION_REG.7 = 0
VRCON = 0
ANSEL = 0

'// Setup IR bit widths / carrier cycle times
Header CON 96 '// Header = (96 * 25uS) = 2.4mS burst
Zero CON 24 '// Zero = (24 * 25uS) = 0.6mS burst
One CON 48 '// One = (48 * 25uS) = 1.2mS burst

'// Define variables
Cycles VAR BYTE BANK0 '// Holds number of 40KHz carrier cycles
i var byte

Loop:
if gpio.1 = 0 then
cycles = header
gosub pulse
cycles = zero
gosub dark

cycles = zero
gosub pulse
cycles = zero
gosub dark
endif

if gpio.2 = 0 then
cycles = header
gosub pulse
cycles = zero
gosub dark

cycles = one
gosub pulse

endif

GOTO LOOP

Pulse: '// Emits # of 38.461 kHz bursts held in variable Cycles
for i = 1 to cycles
ASM ;// with auto delay between bursts
;bsf GPIO, 0 ;// 1uS, LED=on [need 25uS total
MOVE?CT 1, GPIO,0
goto $+1 ;// 3uS (2uS per goto $+1)
goto $+1 ;// 5uS
goto $+1 ;// 7uS
goto $+1 ;// 9uS
goto $+1 ;// 11uS
goto $+1 ;// 13uS
bcf GPIO, 0 ;// 14uS, LED=off
decfsz _Cycles,F ;// 24uS
goto $+1 ;// 16uS
goto $+1 ;// 18uS
goto $+1 ;// 20uS
goto $+1 ;// 22uS
ENDASM
next i

return

Dark:
for i = 1 to cycles
ASM ;// with auto delay between bursts
;bcf GPIO, 0 ;// 1uS, LED=on [need 25uS total
MOVE?CT 0,GPIO,0
goto $+1 ;// 3uS (2uS per goto $+1)
goto $+1 ;// 5uS
goto $+1 ;// 7uS
goto $+1 ;// 9uS
goto $+1 ;// 11uS
goto $+1 ;// 13uS
goto $+1 ;// 13uS
goto $+1 ;// 13uS
goto $+1 ;// 16uS
goto $+1 ;// 18uS
goto $+1 ;// 20uS
goto $+1 ;// 20uS
ENDASM
next i

return

I may feel some incoming timing problem(s)

ewandeur
- 3rd April 2008, 14:20
I didn`t have much time to test the solution the last days...
But finally I did, and it works great!!!

Many Tks Mr E.

Ps. I have to did some modifications regarding Pulse and Dark times as you mencioned.

mister_e
- 3rd April 2008, 15:26
http://www.mister-e.org/Pics/Awesome
Thanks for your report.