PDA

View Full Version : 12F675 vs 12F1840



Ioannis
- 15th April 2021, 19:33
I had a test program developed on 12F675 until my samples of 12F1840 arrive.

Now I transferred the exact same code to the 1840 chip and the size of compiled code went from 547 words to 785 words.

I thought maybe the x8 system clock of 1840 could affect code size but when compiled as 4MHz (just as the 12F675) the code went up to 794!!!

It is not critical obviously for my project, just curious why that happens.

Ioannis

Ioannis
- 15th April 2021, 20:13
Forgot to change GPIO to LATA and PORT registers.

Now it counts down to 679 words. But still away from 547 words.

Ioannis

HenrikOlsson
- 16th April 2021, 11:29
Intersting, still ~25% larger compared to 12F675.
The 12F1840 has a larger instructionset than the old 675 so one would think there would be "better" ways to do things on the 1840 (though PBP most likely uses the same library for both devices) - which then raises the question: Why so much larger?

Care to post the actual code so we can take a look and perhaps learn something?

/Henrik.

Ioannis
- 16th April 2021, 21:03
I shouldn't but for the sake of the very strange case I will. On both the chips the code is the same except for the port access. Everything else is identical.

12F675:


#config
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON & _CP_ON
#endconfig

DEFINE OSC 4
DEFINE OSCCAL_1K 1 'Read OscCal value from the last location
'DEFINE PULSIN_MAX 2000
'DEFINE ADC_CLOCK 3 'INTERNAL A/D RC CLOCK
'DEFINE ADC_SAMPLEUS 50 'SET SAMPLE TIME IN MICROSECONDS
'DEFINE ADC_BITS 8
INTCON = $00

TRISIO = %00011101
CMCON=7

OPTION_REG.0=0 'PSA0 PRESCALER SELECT 1:1 TO 1:256
OPTION_REG.1=0 'PSA1
OPTION_REG.2=0 'PSA2
OPTION_REG.3=0 'PRESCALER TO: 1->WDT, 0->TMR0
OPTION_REG.4=0 'T0SE SOURCE EDGE 1->H TO L, 0->L TO H
OPTION_REG.5=0 'T0CS 1->FROM RA4, 0->FROM INT. CLOCK
OPTION_REG.6=1 'INT EDGE SELECT 0->H TO L, 1->L TO H
OPTION_REG.7=0 'PULL UP 1->DISABLE, 0->ENABLE

WPU=%00000101

ADCON0 = %00001101 ' Configure and turn on A/D Module:
' Right justify result, AN3 in on GP4

'adcon 7 ADFM: A/D Result Formed Select BIT
' 1 = Right justified
' 0 = Left justified
'adcon 6 VCFG: Voltage Reference BIT
' 1 = VREF pin
' 0 = VDD
'adcon 5-4 Unimplemented
'adocn 3-2 CHS1:CHS0: Analog Channel Select bits
' 00 = Channel 00 (AN0)
' 01 = Channel 01 (AN1)
' 10 = Channel 02 (AN2)
' 11 = Channel 03 (AN3)
'adcon 1 GO/DONE: A/D Conversion Status BIT
' 1 = A/D conversion cycle in progress.
' 0 = A/D conversion completed/NOT in progress
'adcon 0 ADON: A/D Conversion STATUS BIT
' 1 = A/D converter module Is operating
' 0 = A/D converter Is shut-off AND consumes no operating current

ANSEL = %00111000 ' Set ADC clock to Frc and GP1 to analog mode


servo VAR GPIO.5 'PIN# 2, Prog. Button
ldr VAR GPIO.4 'PIN# 3, Direction control and LED
prog VAR GPIO.3 'PIN# 4, MCLR/RS232 Receive
down VAR GPIO.2 'PIN# 5, RS232 Transmit/Receive
led VAR GPIO.1 'PIN# 7, Analog input
up var gpio.0

pos var word
timer var byte
adval var byte
flag1 vAR BIT
i var byte
up_lim var word
down_lim var word
max_up var word
max_down var word
ldr_l var byte

data @0,word 2100,word 550,word 2100,word 550,230

high led
read 0,word up_lim,word down_lim,word max_up,word max_down,ldr_l

while 1
if !prog then gosub setup
gosub ldr_sub
gosub servo_sub
timer=timer+1
if timer>50 then
timer=0
low led:pause 10:high led
endif
wend

setup:
pause 1000
if prog then return

while !prog:pause 100:toggle led:wend
high led

setup1:
pos=up_lim:gosub servo_sub1
if !up then
up_lim=up_lim+10
if up_lim>max_up then up_lim=max_up
low led:pos=up_lim:gosub servo_sub1:high led
endif

if !down then
up_lim=up_lim-10
if up_lim<(max_down+10) then up_lim=(max_down+10)
low led:pos=up_lim:gosub servo_sub1:high led
endif

if prog then setup1

while !prog:pause 100:toggle led:wend
high LED

setup2:
pos=down_lim:gosub servo_sub1
if !up then
down_lim=down_lim+10
if down_lim>(max_up-100) then down_lim=(max_up-100)
low led:pos=down_lim:gosub servo_sub1:high led
endif

if !down then
down_lim=down_lim-10
if down_lim<max_down then down_lim=max_down
low led:pos=down_lim:gosub servo_sub1:high led
endif

if prog then setup2
while !prog:pause 100:toggle led:wend
GOTO EXIT_SETUP

setup3:
if !up then
LDR_L=LDR_L+5
if LDR_L>250 then LDR_L=250
low led:PAUSE 20:high led:pause 50
endif

if !down then
LDR_L=LDR_L-5
if LDR_L<100 then LDR_L=100
low led:PAUSE 20:high led:pause 50
endif

if prog then setup3
while !prog:pause 100:toggle led:wend

exit_setup:
high led
while !prog:pause 100:wend
write 0,word up_lim,word down_lim',LDR_l
for i=0 to 3
low led:pause 250:high led:pause 250
next i
return

servo_sub:
if flag1 then
pos=up_lim
else
pos=down_lim
endif
servo_sub1:
high servo:pauseus pos:low servo
pause 19
return

ldr_sub:
adcon0.1=1
while adcon0.1:wend
select case adresh

case is < ldr_l
flag1=0
case is > (ldr_l+10)
flag1=1
end select
return

End


12F1840


#CONFIG
;----- CONFIG1 Options --------------------------------------------------
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_OFF

;----- CONFIG2 Options --------------------------------------------------
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG

' ************************************************** ******************
' SYSTEM INITIALIZATION
' ************************************************** ******************

PORTA = %00000000
TRISA = %00001111 ' Make A0,A2,A3 inputs,A1,A4,A5 outputs
OSCCON = %11110000 'PLL ENABLED,8Mhz,FSOSC<2:0>
OSCTUNE = %00000000 ' Internal osc Adjustment
WHILE !OSCSTAT.3 ' Wait for stable OSC ...
WEND
INTCON = %00000000 'CLEAR GIE,PEIE,TMR0IE,INTE,RBIE,TMR0IF,INTF,RBIF
PIE1 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
PIR1 = %00000000 'CLEAR ALL INTERRUPT FLAGS
PIE2 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
PIR2 = %00000000 'CLEAR ALL INTERRUPT FLAGS
APFCON = %00000000 'ALL DEFAULTS
ANSELA = %00000010 'Select digital/analog pins
CPSCON0 = %00000000 'ENABLE CAP SENSE,DAC/FVR,HIGH RANGE
WPUA = %00001101 'weak pull ups
ADCON0 = %00000101 'CHS2:0,GO/DONE,ADOFF
ADCON1 = %00110000 'LEFT JUSTIFIED,FRC,VSS,VDD
SRCON0 = %00000000
SRCON1 = %00000000
CM1CON0 = %00000000 'CLEAR/DISABLE COMPARATOR
CM1CON1 = %00000000 'CLEAR/DISABLE COMPARATOR
DACCON0 = %00000000 'ENABLE DAC,ENABLE POS REFERENCE,SOURCE IS FVR
DACCON1 = %00000000 'SET FOR 1/4 SCALE (8) ~ 1.024
FVRCON = %00000000 'ENABLE VOLTAGE REFERENCE,4,096
OPTION_REG = %00000000 'INTEDG,T0CS,T0SE,PSA,PS
T1CON = %00000000 'CAPOSC INPUT,PRESCALER 1/1,START TIMER 1
T1GCON = %00000000 'NO GATE CONTROL
T2CON = %00000000 'POSTSCALER 1/1,STOP,PRESCALER 1
TMR2 = 0 'CLEAR TMR2 MODULE REGISTER
PR2 = 255 'SET PERIOD ((((1 / 32,000,000)*4) * 1 PRESCALE) * (1+255 PR2)) = 31.25 KHZ.
CCP1CON = %00000000 'PLACE CCP1 INTO DISABLE MODE
CCPR1L = $00 'CLEAR CCP1 LOWER 8 BITS
CCPR1H = $00 'CLEAR CCP1 UPPER 2 BITS
PSTR1CON = %00000001'DEFAULT

DEFINE OSC 32

servo VAR lata.5
led VAR lata.4
prog VAR porta.3
down VAR porta.2
ldr VAR porta.1
up var porta.0

pos var word
timer var byte
adval var byte
flag1 vAR BIT
i var byte
up_lim var word
down_lim var word
max_up var word
max_down var word
ldr_l var byte

data @0,word 2200,word 550,word 2200,word 550,230
'data @0,word 550,word 2200,word 550,word 2200,230

high led
read 0,word up_lim,word down_lim,word max_up,word max_down,ldr_l

while 1
if !prog then gosub setup
gosub ldr_sub
gosub servo_sub
timer=timer+1
if timer>50 then
timer=0
low led:pause 10:high led
endif
wend

setup:
pause 1000
if prog then return

while !prog:pause 100:toggle led:wend
high led

setup1:
pos=up_lim:gosub servo_sub1
if !up then
up_lim=up_lim+10
if up_lim>max_up then up_lim=max_up
low led:pos=up_lim:gosub servo_sub1:high led
endif

if !down then
up_lim=up_lim-10
if up_lim<(max_down+10) then up_lim=(max_down+10)
low led:pos=up_lim:gosub servo_sub1:high led
endif

if prog then setup1

while !prog:pause 100:toggle led:wend
high LED

setup2:
pos=down_lim:gosub servo_sub1
if !up then
down_lim=down_lim+10
if down_lim>(max_up-100) then down_lim=(max_up-100)
low led:pos=down_lim:gosub servo_sub1:high led
endif

if !down then
down_lim=down_lim-10
if down_lim<max_down then down_lim=max_down
low led:pos=down_lim:gosub servo_sub1:high led
endif

if prog then setup2
while !prog:pause 100:toggle led:wend
GOTO EXIT_SETUP

setup3:
if !up then
LDR_L=LDR_L+5
if LDR_L>250 then LDR_L=250
low led:PAUSE 20:high led:pause 50
endif

if !down then
LDR_L=LDR_L-5
if LDR_L<100 then LDR_L=100
low led:PAUSE 20:high led:pause 50
endif

if prog then setup3
while !prog:pause 100:toggle led:wend

exit_setup:
high led
while !prog:pause 100:wend
write 0,word up_lim,word down_lim',LDR_l
for i=0 to 3
low led:pause 250:high led:pause 250
next i
return

servo_sub:
if flag1 then
pos=up_lim
else
pos=down_lim
endif
servo_sub1:
high servo:pauseus pos:low servo
pause 19
return

ldr_sub:
adcon0.1=1
while adcon0.1:wend
select case adresh

case is < ldr_l
flag1=0
case is > (ldr_l+10)
flag1=1
end select
return

End


Ioannis

Ioannis
- 16th April 2021, 21:07
Most strange is the 32 vs 4 MHz clock. Lower clock needs more code space!!! I expected the oposite.

Ioannis

Acetronics2
- 19th April 2021, 10:39
Hi, Ioannis,

I'd have a look to internal registers PBP default settings ( the PBP default Config file ) ... as you overwrite most of them ...

just an idea ...

Alain