PDA

View Full Version : Migrating to 18F4420



Amoque
- 20th February 2015, 13:54
I have a project that threatens to outgrow a 16F877A and so have upgraded to the 16F4420. This is quite a step for me as, I have not done much work with a 40 pin chip prior - and never anything with the 18F. So... I've stripped the board down to the MCU, a 4x20 LCD, an I2C clock (3231 module), and required supporting circuitry.

Using meCONFIG, I have managed to configure the chip and, the heartbeat LED is blinking merrily; the LCD starts up and displays exactly like the old '877, but the I2C clock is stubborn. I'm wondering if there is anything in the CONFIG causing the problem, or if perhaps there is some difference in the syntax that I have not seen?

Any help will be appreciated!

Configuration:


__config _CONFIG1H, _OSC_HSPLL_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
__config _CONFIG2L, _PWRT_OFF_2L & _BOREN_SBORDIS_2L & _BORV_3_2L
__config _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
__config _CONFIG3H, _CCP2MX_PORTC_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_ON_3H
__config _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
__config _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
__config _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__config _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
__config _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
__config _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
__config _CONFIG7H, _EBTRB_OFF_7H


CODE:


'-----DEFINES------------------------------------------------------------------
'-----OSC
DEFINE OSC 4

'----ADC
DEFINE ADC_BITS 10 ' Set number of bits in result
'DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 100

'-----LCD
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 3
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 2
DEFINE LCD_LINES 4

'-----REGISTERS SET------------------------------------------------------------
CMCON = %00000111 'DISABLE COMPARITOR
TRISA = %00011111 ' Set PORTA.OUTPUT; ADC
TRISB = %00000000 ' Set PORTB OUTPUT
TRISC = %00000000 ' Set PORTC
TRISD = %00000000 ' Set PORTD OUTPUT
TRISE = %00000000
ADCON0 = %10100001
ADCON1 = %10000010 ' RIGHT justify; Set AN0 - AN5 ADC

'-----LED
LINE1 CON $80
LINE2 CON $C0
LINE3 CON $94
LINE4 CON $D4

'-----I2C
SCL VAR PORTE.1
SDA VAR PORTE.2
'DEFINE I2C_SLOW 1
'DEFINE I2C_HOLD 1
'DEFINE I2C_SCLOUT 1

'-----INDICATOR LIGHTS
LIT_ADD CON %01110010

'-----GAUGES
REG_CHP1 CON %01011000
REG_CHP2 CON %01011010
GAGE VAR BYTE

'-----CLOCK/ CALENDAR
REG_VAL VAR Byte[12]
RTC_ADD CON %11010000
REG_TIM CON $00
REG_CTL CON $07
REG_STS CON $0F
CURR_MIN VAR WORD
OLD_MIN VAR byte
OLD_DAY VAR BYTE

'-----INITIALIZE---------------------------------------------------------------
'----SET TIME 'Seconds, minutes, hours, day of week, date, month, year
REG_VAL[0] = 00 'SECONDS
REG_VAL[1] = 12 'MINUTES
REG_VAL[2] = 19 'HOURS
REG_VAL[3] = 03 'DOW
REG_VAL[4] = 18 'DAY
REG_VAL[5] = 02 'MONTH
REG_VAL[6] = 15 'YEAR
REG_VAL[7] = %01100000 'SPECIAL
REG_VAL[8] = %00001000 'SPECIAL
REG_VAL[9] = %00001000 'SPECIAL
I2CWrite SDA, SCL, REG_CTL, $0E, [REG_VAL[7]]
GOSUB CLK_WRITE

'-----MISC '.6
D1 VAR BYTE
LP VAR BYTE
ADC_VAL VAR WORD[3]
IND_LIT VAR BYTE

PAUSE 250
LCDOUT $FE, $01 ' Bit 7 =
LCDOUT $FE, LINE1,"--STEGETROLLER--"
PAUSE 250
LCDOUT $FE, LINE2,"---START-UP"
PAUSE 1250
LCDOUT $FE, $01

MAIN:
FOR LP = 1 TO 3
ADCIN LP, ADC_VAL[LP]
PAUSE 10
NEXT LP

'I2CWrite SDA, SCL, LIT_ADD, $00, [IND_LIT]
'IND_LIT = IND_LIT + 1

'I2CWrite SDA, SCL, REG_CHP1, $00, [GAGE, GAGE] 'GUAGE 1 - TEMP
'pause 100
'GAGE = GAGE + 10

PORTA.5 = 1
PAUSE 100
PORTA.5 = 0
PAUSE 100
GOSUB CLK_READ
GOSUB UPDATE_DISPLAY
GOTO MAIN

UPDATE_DISPLAY:
'LINE1
LCDOUT $FE, LINE1, DEC1 REG_VAL[3], "<", DEC2 REG_VAL[5], "/", DEC2 REG_VAL[4]
LCDOUT $FE, LINE1 + 14, "[", DEC4 CURR_MIN, "]"
LCDOUT $FE, LINE2, DEC4 ADC_VAL[1], ":", DEC4 ADC_VAL[2], ":", DEC4 ADC_VAL[3]
LCDOUT $FE, LINE3, DEC2 REG_VAL[2], ":", DEC2 REG_VAL[1], ":", DEC2 REG_VAL[0]
LCDOUT $FE, LINE4, BIN16 ADC_VAL[1]
'-----READ CLOCK AND CONVERT TO DECIMAL
CLK_READ:
I2CRead SDA, SCL, RTC_ADD, $00, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6], REG_VAL[7], REG_VAL[8], REG_VAL[9], REG_VAL[10], REG_VAL[11], REG_VAL[12]]
FOR LP = 0 TO 6
D1 = REG_VAL[LP]
D1 = D1 & $70
D1 = D1 >> 4
D1 = D1 * 10
REG_VAL[LP] = D1 + (REG_VAL[LP] & $0F)
NEXT LP
CURR_MIN = REG_VAL[2] * 60 + REG_VAL[1]
Return

'-----CONVERT TO BCD VALUES, WRITE TO CLOCK REGISTERS
CLK_WRITE:
FOR LP = 0 TO 6
D1 = REG_VAL[LP] DIG 1
D1 = d1 << 4
D1 = D1 + (REG_VAL[LP] DIG 0)
REG_VAL[LP] = D1
NEXT LP
I2CWrite SDA, SCL, RTC_ADD, $00, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6], REG_VAL[7]]
GOSUB CLK_READ
Return


The code is quite messy as I've been up way too late trying to solve the issue myself and now, as I prepare for work, am admitting defeat. Still, it does work on the 877, just wondering what the problem on the 4420 might be?

HenrikOlsson
- 20th February 2015, 14:58
Hi,
Your ADCON1 looks wrong:
ADCON1 = %10000010

Bit7 which doesn't do anything, yet you have it set for some reason and the four bottom bits (0010) will leave all the analog pins in analog mode. So PortE.1 and PortE.2 (your I2C pins) are analog.

/Henrik.