PDA

View Full Version : first project, and yes, doesn`t work



bogdan
- 26th April 2009, 05:54
I try to build a box for cigarettes.

Parts:
-pic16F913
-mclr reset
-ext int (using DT interrups)
-dumb LCD
-h-bridge+latching solenoid

Unfortunately the LCD show me just "999"...and even the ext interrupts doesn`t work

If you guys have a minute just take a look...see the attachments

Thank you



@ __config _INTOSCIO & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF
'-------
CLEAR 'Clear all ram registers

'MCU CLOCK SOURCE

OSCCON.0 = 0 'int osc is used for sys clock (SCS bit)

OSCCON.6 = 0 'int osc freq 32kHz (IRCF bits)
OSCCON.5 = 0
OSCCON.4 = 0

'PORTS CONFIG
ANSEL=0 'Analog to Digital converter disabled

TRISA = %10000000 'PORTA.7 (T1OSI=XTAL) to inputs

TRISB = %00000001 'PORTB.0 (=external interrupts) to input

TRISC = %00000111 'PORTC.2 to 0 (=1/3 BIAS for LCD) to inputs

''Timer1 CONFIGURATION (part of)

T1CON.1 = 1 'clock for Timer1 is ext (TMR1CS bit)
T1CON.2 = 1 'do not sync with the int clock (T1SYNC bit)
T1CON.3 = 1 'LP oscillator is enabled for Timer1 clock (when INTOSC without CLKO is active) (T1OSCEN bit)

'LCD CONFIGURATION

LCDCON.4 = 1 'enable bias voltage pins (VLCDEN bit)

LCDCON.3 = 1 'clock source LFINTOSC (31kHz/32) (CS bits)
'LCDCON.2 = ?

LCDCON.0 = 1 '1/4 multiplex (all COM used) (LMUX bits)
LCDCON.1 = 1

LCDPS.7 = 0 'waveform type-A (WFT bit)

LCDPS.6 = 0 'bias mode (when LMUX=11) (BIASMD bit)

LCDPS.3 = 0 '1:16 prescaler (31kHz/32/8=121Hz) (LP bits)
LCDPS.2 = 1
LCDPS.1 = 1
LCDPS.0 = 1

LCDSE0.3 = 1 'enable SEG3,4,5,6,8,9 (SE bits)
LCDSE0.4 = 1
LCDSE0.5 = 1
LCDSE0.6 = 1
LCDSE1.0 = 1
LCDSE1.1 = 1

'Clear??? LCDDATA registers see AN1070

LCDCON.6 = 0 'enable the LCD in SLEEP mode (SLPEN bit)

'PIR2.4 = 0 '(why ???) clear LCD Interrupt Flag (LCDIF bit)

'VARIABILES

adr4tmr1LO VAR BYTE 'RAM adr for startup timer1_LOW _BYTE value
adr4tmr1HI VAR BYTE 'for timer1_HIGH _BYTE value

T1 VAR WORD 'temp var for TMR1 startup value
nc var word
nc0 var word 'number of cigarettes (index) at address 0+1
nc2 var word 'at adr 2+3
nc4 var word 'at adr 4+5

LCD VAR WORD 'number on LCD
hundreds VAR BYTE 'temporary LCD var
tens var byte 'temp LCD var
ones var byte 'temp LCD var
'-----
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"

ASM
INT_LIST macro
INT_Handler INT_INT, _open_battery_cover, PBP, yes
endm
INT_CREATE
INT_ENABLE INT_INT
ENDASM

'WRITE TO EEPROM the startup timer1 values DIVIDED by 4 to fit into the 14 bytes (Timer1_startup_value/4)

DATA @48,WORD 12773,WORD 12927,WORD 13080,WORD 13234,WORD 13388,WORD 13541,WORD 13695,WORD 13848
'...not completed...more then 10k characters to upload

'LATCH THE BOX

lock_the_box:
PORTB.1 = 1 'armature out
PAUSE 1
PORTB.1 = 0

'GET THE CIGARETTE INDEX

Interval_Tigari:

READ 0, NC0.LowByte 'read the last cigarette index from EEPROM_location 1
READ 1, NC0.HighByte 'from EEPROM_location 1
READ 2, NC2.LowByte 'from EEPROM_location 2
READ 3, NC2.HighByte 'from EEPROM_location 2
READ 4, NC4.LowByte 'from EEPROM_location 3
READ 5, NC4.HighByte 'from EEPROM_location 3

'IF power down at writing between (nc0.LowByte and nc0.HighByte) or (nc0 and nc2)

if nc4-nc2=0 then
IF nc2-nc0<>0 THEN
nc=nc2+1
goto next_cigarette
ENDIF
endif

'IF power down at writing between (nc2.LowByte and nc2.HighByte)
if nc4-nc2<>0 THEN
IF nc2-nc0<>0 then
nc=nc4+1
goto next_cigarette
ENDIF
endif

'IF power down (or not) at writing anywere else
nc=nc0
'-------
next_cigarette:

if nc = 16383 then 'EEPROM is just 14 bytes
goto get_adr4tmr1
endif
NC = NC+1 'next cigarette

'GET START RAM ADDRESS RANGE FOR TIMER1 STARTUP VALUE BY CIGARETTE INDEX

get_adr4tmr1:

SELECT CASE nc
Case Is < 141 '1st week
adr4tmr1lo=48
Case Is < 255 '2nd week
adr4tmr1lo=64
Case Is < 349 '3rd week
adr4tmr1lo=80
Case Is < 430 '4th week
adr4tmr1lo=96
Case Is < 500 '5th week
adr4tmr1lo=112
Case Is < 563 '6th week
adr4tmr1lo=128
Case Is < 619 '7th week
adr4tmr1lo=144
Case Is < 670 '8th week
adr4tmr1lo=160
Case Is < 717 '9th week
adr4tmr1lo=176
Case Is < 760 '10th week
adr4tmr1lo=192
Case Is < 800 '11th week
adr4tmr1lo=208
Case Is < 837 '12th week
adr4tmr1lo=224
Case Is >=837 '13th week and more
adr4tmr1lo=240
END SELECT

'COUNTDOWN LCD

Countdown:


LCDCON.7 = 1 'enable the LCD module (LCDEN bit)

for hundreds = 9 to 0 step -1
LOOKUP hundreds,[1,0,1,1,0,1,1,1,1,1],LCDDATA10.1
'hundreds seg A (0 to 9)
'...not completed...more then 10k characters to upload
for tens = 9 to 0 step -1
LOOKUP TENS,[1,0,1,1,0,1,1,1,1,1],LCDDATA9.3
'tens seg A (0 to 9)
'...not completed...more then 10k characters to upload
for ones = 9 to 0 step -1
LOOKUP ones,[1,0,1,1,0,1,1,1,1,1],LCDDATA9.5 'ones seg A (0 to 9)
'...not completed...more then 10k characters to upload

LCD=hundreds*100+TENS*10+ONES
'>>>>>>>
'GET START RAM ADDRESS FOR TIMER1 STARTUP VALUE BY LCD VALUE

IF LCD<=999 THEN
IF LCD>=875 THEN
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=874 THEN
IF LCD>=750 THEN
adr4tmr1lo = adr4tmr1lo+2
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=749 THEN
IF LCD>=625 THEN
adr4tmr1lo = adr4tmr1lo+4
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=624 THEN
IF LCD>=500 THEN
adr4tmr1lo = adr4tmr1lo+6
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=499 THEN
IF LCD>=375 THEN
adr4tmr1lo = adr4tmr1lo+8
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=374 THEN
IF LCD>=250 THEN
adr4tmr1lo = adr4tmr1lo+10
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=249 THEN
IF LCD>=125 THEN
adr4tmr1lo = adr4tmr1lo+12
goto Start_Timer1_interrupt
ENDIF
ENDIF

IF LCD<=124 THEN
adr4tmr1lo = adr4tmr1lo+14
ENDIF
'>>>>>>>
Start_Timer1_Interrupt:

READ adr4tmr1lo,T1.LowByte 'Timer1_startup_value/4
adr4tmr1HI=adr4tmr1lo+1
READ adr4tmr1HI,T1.HighByte

T1 = T1*4 'Timer1 REAL startup value

TMR1H = T1.HighByte
TMR1L = T1.LowByte

T1CON.0 = 1 'enable Timer1 (TMR1ON bit)

T1CON.5 = 1 'Timer1 input clock prescale (1:8) (T1CKPS bits)
T1CON.4 = 1

T1CON.6 = 1 'enable Timer1 Gate (T1GE bit)
T1CON.7 = 0 'Timer1 Gate is not inverted (T1GWN bit)

PIE1.0 = 1 'enable overflow int (TMR1IE bit)
INTCON.6 = 1 'enable all unmasked peripheral int (PEIE bit)
INTCON.7 = 1 'enable global int (GIE bit)
@ sleep
@ nop
@ nop
PIR1.0 = 0 'clear Timer1 int flag (TMR1IF bit)
PIE1.0 = 0 'disable overflow int (TMR1IE bit)
T1CON.0 = 0 'disable Timer1 (TMR1ON bit)

next ones
next tens
next hundreds

'UNLOCK THE BOX

unlock_the_box:

WHILE PORTB.0 = 1
'write to lcd OCE "open cover error"
WEND

PORTA.0 = 1 'armature in
PAUSE 1
PORTA.0 = 0

'write the same "nc" value at three locations to fix the power down issue at the writing time
WRITE 1, NC.HighByte 'write to RAM the "nc" LOW BYTE
WRITE 0, NC.LowByte 'the "nc" HIGH BYTE
WRITE 3, NC.HighByte
WRITE 2, NC.LowByte
WRITE 5, NC.HighByte
WRITE 4, NC.LowByte

'turn off the LCD
LCDCON.4 = 0 'disable bias voltage pins (VLCDEN bit)
LCDCON.6 = 1 'disable the LCD in SLEEP mode (SLPEN bit)
LCDCON.7 = 0 'disable the LCD module (LCDEN bit)

END 'wait for MCLR reset

'INTERRUPT WHEN THE BATTERY COVER IS OPEN

open_battery_cover:

PORTB.1 = 1 'armature out
PAUSE 1
PORTB.1 = 0

@ INT_RETURN



3357

3358

bogdan
- 26th April 2009, 05:59
oops


3359

3360

bogdan
- 26th April 2009, 18:33
i add one LED to PORTA.1 and i tryed to blink it using external osc



@ __config _LP_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF
'-----------------------------------------------------------------------------
CLEAR 'Set all ram registers to zero
'-----------------------------------------------------------------------------
'MCU CLOCK SOURCE

OSCCON.0 = 0 'EXTERNAL osc is used for sys clock (SCS bit)
'-----------------------------------------------------------------------------
'PORTS CONFIGURATION

ANSEL=0
TRISA = %10000000 'PORTA.7 (T1OSI=XTAL) to input
TRISB = %00000000
TRISC = %00000000

PORTA=%00000000
PORTB=%00000000
PORTC=%00000000
'--------------------------------------------------------------------------
blink_LED:

PORTA.1 = 1
PAUSE 1
PORTA.1 = 0

GOTO blink_LED


what i`m doing wrong ?

Best regards,
Bogdan

Archangel
- 26th April 2009, 21:05
Hello bogdan,
Had to hunt for the data sheet . . . This chip has comparators on PortA and to use as digital output you have to turn them off with
CMCON0 = 7.
I have not studied it any farther yet.
EDIT: if you are not using this chip to drive a discrete LCD ( one without a controller built in ) disable the LCD control module. I think this will do that for you:
LCDCON = %0100000 ' section 10.1 datasheetDoh! I see you are using it in the first code posted

bogdan
- 26th April 2009, 23:57
First of all, I would like to thank you for your reply

I've tried with CMCON0 = 7...no luck

By the internal osc is blinking (even with the comparators off)

Do you think i should change the values of the caps next to the crystal (22p) ? (....i already tried another crystal and i have the same results)

Thank you

ShaneMichael
- 27th April 2009, 01:33
Hello, I don't know if this has anything to do with your trouble, but I was using DT interupts and changed the T1CON settings. The changes I made messed with the configureations Darrel made in the include file. My post was a few days ago "DT Interrupt and Elapsed Time Running Slow ". It might give you a clue. I'm new at this myself, but that's what my problem was.

Shane

bogdan
- 27th April 2009, 02:05
Hi Shane....i will like to get to the "T1CON settings" part...but, right now i coudn't even make one stupid LED to blink by the external osc (i`m sure i missing something with the ext osc configuration)

I saw in your post (DT Interrupt and Elapsed Time Running Slow) you use internal 8 MHz OSC....what about if you want to use ext osc...how you will change the T1CON settings ?

Thank you for the heads up

Melanie
- 27th April 2009, 07:01
Bogdan, this code you wrote isn't too hot...

blink_LED:

PORTA.1 = 1
PAUSE 1
PORTA.1 = 0

GOTO blink_LED

You're turning your LED on for 1mS and then IMMEDIATELY turning it off again... so your eye will probably see your LED ON all the time, but certainly my eye can't catch a blink where the ON state is 1mS and the OFF state is a couple of uS.

Correct that to something like...

blink_LED:

PORTA.1 = 1
PAUSE 250
PORTA.1 = 0
PAUSE 250

GOTO blink_LED

Also, another mistake you made, you want PORTA.7 to be an INPUT, by stating PORTA=%00000000 you're forcing it to be an OUTPUT, delete that line.

ShaneMichael
- 27th April 2009, 07:42
Another thing I have a question on, you are using a 32khz crystal. I believe PBP defaults to 4 mhz unless something is Defined for OSC speed.

DEFINE OSC 8

for 8Mhz clock.

Without that I don't know if PBP would know what to do?

I don't know that 32 khz can be defined in PBP? Some one else that knows more than me might have some better input?

Shane

Archangel
- 27th April 2009, 07:57
...but, right now i couldn't even make one stupid LED to blink by the external osc (i`m sure i missing something with the ext osc configuration)


External Oscillator ? Are you using an external oscillator ? Or are you using a crystal and caps , or a 3 pin resonator ? I ask, because you mentioned the caps. . . and a crystal with caps / or 3 pin resonator will use a different setting in the config statement from an external oscillator.
EDIT: OK I looked closer at your code and schematic, I think your config should be :


@ __config _LP_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF

The data sheet indicates to use LP_OSC for 32khz
Shane: Osc set by oscon register

ShaneMichael
- 27th April 2009, 17:53
Joe S.

So from the data sheet:

"LP Oscillator mode selects the lowest gain setting of the
internal inverter-amplifier. LP mode current consumption
is the least of the three modes. This mode is designed to
drive only 32.768 kHz tuning-fork type crystals (watch
crystals)."

The OSCON and Config is setting to LP. I was under the impression that PBP needed a "DEFINE OSC" so it know's what speed things are running at?

Is that not the case?

Bogdan: Another thing you might try is using the interal OSC for testing, at least to get a light to blink so you know the Pic is working.

Shane

Archangel
- 27th April 2009, 22:09
Joe S.

So from the data sheet:

"LP Oscillator mode selects the lowest gain setting of the
internal inverter-amplifier. LP mode current consumption
is the least of the three modes. This mode is designed to
drive only 32.768 kHz tuning-fork type crystals (watch
crystals)."

The OSCON and Config is setting to LP. I was under the impression that PBP needed a "DEFINE OSC" so it know's what speed things are running at?

Is that not the case?

Bogdan: Another thing you might try is using the interal OSC for testing, at least to get a light to blink so you know the Pic is working.

ShaneHonestly Shane, I do not know for sure.
As I understand it the define is used to synchronize PBP's timing with the assembler's, but I think it only accepts Integer numbers and then only certain ones. A Good question for the EXPERTS. I will have to read up on this . . .

bogdan
- 28th April 2009, 03:20
I really appreciate your help guys.

Melanie: ...i know, the code wasn't hot at all, you right, the second PAUSE xxx should be there (i miss that), ... about the PORTA=%00000000 you're forcing it to be an OUTPUT i didn' know...Thank You

Shane: ... i tried to blink it by the internal oscillator and is working, but by the ext crystal (32khz) still doesn'work

Joe: ...i don't think i have to use DEFINE, because i already setup the fuse @ __config _LP_OSC

Please let post first the schematic and the code and after that take a look at my questions (please):

schematic:
3369

code:
@ __config _LP_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF
'--------------------------------------------------------------------------
CLEAR 'Set all ram registers to zero
'--------------------------------------------------------------------------
'MCU CLOCK SOURCE

OSCCON.0 = 0 'EXTERNAL osc is used for sys clock (SCS bit)

'--------------------------------------------------------------------------
'PORTS CONFIGURATION

ANSEL=0
TRISA = %10000000 'set PORTA.7 (T1OSI=XTAL) to input
TRISB = %00000000
TRISC = %00000000



PORTB=%00000000
PORTC=$00000000
'--------------------------------------------------------------------------
PORTB.6 = 1 'JUST FOR TEST

blink_LED:
PORTA.1 = 1
PAUSE 250
PORTA.1 = 0
PAUSE 250
GOTO blink_LED

bogdan
- 28th April 2009, 04:01
1 -it will be enough to setup the fuse @ __config _LP_OSC and to setup the programmer (melabs U2 Programmer ) to update by itself the "Configuration From File" ?....or i have to comment the *.inc file also?
3370

2A -how should i setup the TRISA.6 and TRISA.7 when the external crystal is used for sys clock
2B -what about if i will use internal osc (INTOSCIO) for sys clock and the external crystal for Timer1 ?
3371


3 -in the datasheet they say :"LP Oscillator mode selects the lowest gain setting of the internal inverter-amplifier. LP mode current consumption
is the least of the three modes. This mode is best suited to drive resonators with a low drive level specification, for example, tuning fork type crystals."

...they say "A series resistor (RS) may be required for quartz crystals with low drive level."
3372

.... so do you think i should add one resistor there ?

I saw the study case for pic16f690 and ext crystal (
http://ww1.microchip.com/downloads/en/AppNotes/91097A.pdf)... should i go so deep ?

I have alot more questions, but tomorrow i have to go to work guys.

Thank You again for your patience.

Archangel
- 28th April 2009, 04:17
Joe: ...i don't think i have to use DEFINE, because i already setup the fuse @ __config _LP_OSC

That was Shane . . .
Another thing I have a question on, you are using a 32khz crystal. I believe PBP defaults to 4 mhz unless something is Defined for OSC speed.

DEFINE OSC 8

for 8Mhz clock.

Without that I don't know if PBP would know what to do?

I don't know that 32 khz can be defined in PBP? Some one else that knows more than me might have some better input?

Shane

ShaneMichael
- 28th April 2009, 06:13
Do they make a data sheet for dummies? I could use one. So reading the data sheet I noticed this statement:

"6.4 Timer1 Oscillator
A low-power 32.768 kHz crystal oscillator is built-in
between pins OSC1 (input) and OSC2 (amplifier
output). The oscillator is enabled by setting the
T1OSCEN control bit of the T1CON register. The
oscillator will continue to run during Sleep.
The Timer1 oscillator is shared with the system LP
oscillator. Thus, Timer1 can use this mode only when
the primary system clock is derived from the internal
oscillator or when the oscillator is in the LP mode. The
user must provide a software time delay to ensure
proper oscillator start-up."

So by that statement I believe you want to use the internal OSC, I'd use it at 4 or 8 mhz.

Timer one you would use the external crystal and set T1OSCEN =0 so you don't turn on the interal 32.768 crystal....I think? Like I said, I need a data sheet for dummies...

I'd take on one thing at a time, get the pic working on the internal clock first. When you have a good handle on that then take on clocking Timer one from the crystal. Then as it breaks, you'll know what setting did it.

Also, if it has an internal crystal at 32.768 khz, why use an external, is it just an accuracy concern?

I don't think you'll need to dig any deeper than you already are, it's just a matter of getting the correct settings.

Good Luck,
Shane