PIC16F1826 met HD44780 en PicBasic

Bavelt

Golden Member

Ik ben inmiddels begonnen met de uC PIC 16F1826 omdat deze een I2C ondersteuning biedt.

Echter loop ik tegen een startprobleem aan.

In onderstaand heel simpel programmaatje werkt het met de PIC16F628A, maar met de 1826 lukt het niet; ik krijg niets op het scherm .

De Display (1602A) kent een 4-tal data-lijnen, een Enable (EN) en een Register Select (RS).
In de PICBasic cursus wordt verklaard dat PIC Basic 'het allemaal regelt'.

De 1826 is pin compatible met de 628A. Maar kan het wellicht zijn dat de pinnen EN en RS op een andere pin moeten? (EN zit nu op 8 en RS op 9).
Uit de datasheet van de 1826 kan ik dat niet zo gauw halen.

Daar komt bij dat de fuses zoals die voor de 628A worden ingebracht compilatie errors geven. Ik heb ze nu met de 'Fuse generator' aangemaakt.
Maar misschien zit daar ook iets niet goed.

De code:

pic basic code:

 DEVICE = 16F628A 
CONFIG INTRC_OSC_NOCLKOUT, WDT_ON, PWRTE_ON, MCLRE_OFF, BODEN_ON, LVP_OFF, CP_OFF 
DECLARE XTAL 4

CLS
PRINT "Hallo"
END
 

;*** Met een PCIF1826 werkt het niet ***
;DEVICE = 16F1826
;CONFIG1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_ON, CLKOUTEN_OFF, IESO_ON, FCMEN_ON
;CONFIG2 WRT_OFF, PLLEN_ON, STVREN_ON, LVP_ON
;DECLARE XTAL 4
;CLS
;PRINT "Hallo"
;END  
Fouten zijn het bewijs dat je het probeert..

Je hebt bij de 1826 code LVP aan staan. Afhankelijk van de pin kan het zijn dat de microcontroller niet start.

Verder kan je best ook aan de compiler met declares laten weten welke pinnen wat doen.

Ik heb even gezocht en kwam deze code tegen in een oud project van mij dat dit type PIC gebruikt.

pic basic code:

Device = 16F1826                 
Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_ON, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_ON, FCMEN_ON
Config2 WRT_OFF, PLLEN_OFF, STVREN_ON, BORV_19, LVP_OFF

Xtal                  = 32       
All_Digital           = true   

OSCCON                = %11110000	'Oscillator goed zetten voor 32Mhz     
'****************************************************************

Declare LCD_DTPin PORTB.4
Declare LCD_ENPin PORTB.0
Declare LCD_RSPin PORTB.3
Declare LCD_Interface 4 
Declare LCD_Lines 2 
Cls
Print At 1, 1, "Sens: ", 2, ":   ", 3, ":"   

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--
Bavelt

Golden Member

Er zit al een beetje leven in de display!
Ik heb de EN op PortB.2 gezet (= pin 8).

Ik neem aan dat de Datalijnen van de LCD op Poorten B.4, B.5, B.6 en B.7 zijn (vanwege Declare LCD_DTPin PORTB.4)

Het programma toont na starten echter 4 vraagtekens op het scherm, zelfs zonder de Print instructie. De cursor knippert op de 5e positie.

Daar gaat dus nog iets niet goed...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Omdat ik het LCD display maar niet aan de praat kreeg met de PIC16F1826, ben ik maar een stap terug gegaan, om te kijken of ik de PIC überhaupt kan laten werken.

Ik stuit dan meteen tegen een probleem aan: een simpele Toggle werkt alleen op de Poorten A.6, A.7 en voor B.0.
De rest van de poorten reageert niet op de Toggle.
Er moet iets zijn dat deze poorten anders laat reageren, of een van mijn fuse settings moet niet goed zijn.
Hier kom ik even niet uit, in de datasheet kan ik het probleem niet herleiden (ws gebrek aan kennis).
De PIC heb ik al vervangen en is niet defect.

Het programma (even alleen voor de B-poorten):

pic basic code:

 DEVICE = 16F1826                 
CONFIG1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_ON, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_ON, FCMEN_ON
CONFIG2 WRT_OFF, PLLEN_OFF, STVREN_ON, BORV_19, LVP_OFF


DECLARE XTAL  32       
ALL_DIGITAL TRUE   

OSCCON                = %11110000	'Oscillator goed zetten voor 32Mhz     
'****************************************************************

CLEAR
DELAYMS 1000

PORTB = %11111111             ;Alle Poorten B hoog
TRISB = %00000000             ;Alle Poorten B output
DELAYMS 1000

Main:


TOGGLE PORTB.0
TOGGLE PORTB.1
TOGGLE PORTB.2
TOGGLE PORTB.3
TOGGLE PORTB.4
TOGGLE PORTB.5
TOGGLE PORTB.6
TOGGLE PORTB.7
DELAYMS 2000

GOTO Main

;Alleen Poort B.0 reageert

END
  
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

ANSELA en ANSELB staan default op analoog. Een toggle geeft dan altijd '0'
(schijnbaar werkt ALL DIGITAL TRUE niet...)

[Bericht gewijzigd door Arco op maandag 30 september 2019 12:08:27 (98%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

CONFIG1 FOSC_INTOSC,

DECLARE XTAL 32 ,

FOSC_INTOSC staat per default op 16 MHz.

Haal DECLARE XTAL 32 eens weg

Guus@Sint-Michielsgestel
Arco

Special Member

@waters: OSCCON op 11110000 geeft 32MHz... (voor een toggle maakt de exacte frequentie trouwens niets uit)

[Bericht gewijzigd door Arco op maandag 30 september 2019 12:14:59 (43%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Kan ook het Read-Modify-Write probleem zijn.

De 16F1826 heeft voor de uitgangen ook een LAT register.
Probeer i.p.v. PORTB.1 LATB.1 etc....

Bij PIC's die het LAT register hebben altijd het LAT register gebruiken voor output

Zie ook: http://www.knutselaar.eu/WP/datasheets-io-poorten/

Arco

Special Member

Da's een hele goeie, had ik over het hoofd gezien!... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 30 september 2019 12:22:51 schreef Piet_Knutselaar:
Kan ook het Read-Modify-Write probleem zijn.

De 16F1826 heeft voor de uitgangen ook een LAT register.
Probeer i.p.v. PORTB.1 LATB.1 etc....

Bij PIC's die het LAT register hebben altijd het LAT register gebruiken voor output

Zie ook: http://www.knutselaar.eu/WP/datasheets-io-poorten/

En nu doet de Toggle het inderdaad!. Daar was ik in mijn eentje niet uitgekomen. Wel had ik in de Datasheet al gelezen:

The ANSELA bits default to the Analog
mode after Reset. To use any pins as
digital general purpose or peripheral
inputs, the corresponding ANSEL bits
must be initialized to ‘0’ by user software

En nu maar eens kijken of dit het probleem met de aansturing van het 44780-LCD oplost.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 30 september 2019 12:09:37 schreef Arco:
@waters: OSCCON op 11110000 geeft 32MHz... (voor een toggle maakt de exacte frequentie trouwens niets uit)

Inderdaad werkt dit nu ook!
De Port vervangen door Lat:

pic basic code:

 DECLARE LCD_DTPIN LATB.4
DECLARE LCD_ENPIN LATB.2
DECLARE LCD_RSPIN LATB.3 

En het werkt!

@Stynus: grappig dat het bij jou wel werkte met 'PORT'.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Als je geen (te) zware belastingen aan de pinnen hangt, werkt het meestal met PORT ook wel...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Nu de LCD werkt, heb ik de DS3231 aangekoppeld.
Maar het tijd zetten of ophalen gaat niet goed.
(Ik weet niet waar het precies mis gaat, wellicht zet hij de tijd wel. Maar bij ophalen wordt de waarde niet getoond op de LCD (vierkant blokje).

Uit de datasheet van de PIC16F1826 haal ik dat voor SDA poort B.1 kan worden gebruikt en voor de SCL poort B.4.
Maar op B.4 zit ook een datalijn van de LCD.
Mag dat door elkaar worden gebruikt? Zit hier wellicht iets niet goed?

Een andere mogelijkheid lijkt B.5 (SCL) en B.2 (SDA).
Maar B,5 is ook in gebruik door de LCD.
Kan dat wel?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het is: of i2c, of gewone i/o. Anders kan niet.
Je kunt voor dat display toch andere pinnen gebruiken?

De 1826 heeft maar 1 MSSP/i2c: op RB1 en RB4... (2e MSSP zit alleen op 1827)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Dat wilde ik ook. Maar kon dat niet zo vinden;
in de PICbasic cursus wordt deze LCD behandeld, maar "Picbasic regelt het allemaal".

Of het zou moeten kunnen met 'DECLARE LCD_DTPIN LATB.4' (en daar een andere poort voor kiezen), maar dat weet ik niet zeker.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Met DECLARE LCD_DTPIN LATA.0 werkt het ook.
Dan zijn de datalijnen poorten A0, A1, A2 en A3.

Kies ik echter PORTA.4 (in de verwachting dat de datalijnen dan A4, A5, A6 en A7 zijn), dan werkt het niet.

[Bericht gewijzigd door Henry S. op maandag 30 september 2019 21:27:11 (37%)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

RA5 = MCLR (MCLR is altijd alleen een input, geen output)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ah, vandaar.
Ik vermoedde al dat het met de MCLR te maken had. Weer wat geleerd.
Nu op naar de volgende stap: de RTC DS3231 aan de praat zien te krijgen in combinatie met de LCD.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

In mijn enthousiasme en onschuld dacht ik dat onderstaand programmaatje (schrijft en leest de datum / tijd) van een DS3231 en toont het op een 44780 Display) zou moeten werken.

Na de communicatie met de RTC krijg ik echter niets terug (waarde 00) of er wordt niets weggeschreven, dat kan natuurlijk ook. Of beide.
De Datasheet van de DS3231 ziet er complex uit; ik vraag me ook af of er niet eerst iets moet worden 'geïnitialiseerd'.

Wie geeft me een zetje in de goede richting?

pic basic code:

DEVICE = 16F1826                 
CONFIG1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_ON, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_ON, FCMEN_ON
CONFIG2 WRT_OFF, PLLEN_OFF, STVREN_ON, BORV_19, LVP_OFF

DECLARE XTAL  32       
ALL_DIGITAL true   

OSCCON                = %11110000	'Oscillator goed zetten voor 32Mhz     

CLEAR
DECLARE LCD_DTPIN LATA.0
DECLARE LCD_ENPIN LATB.2
DECLARE LCD_RSPIN LATB.3
SYMBOL RTC_SDA    LATB.1
SYMBOL RTC_SCL    LATB.4
DECLARE LCD_INTERFACE 4
DECLARE LCD_LINES 2 

'------------ Variabelen-------------------------
DIM RTCYear      AS BYTE
DIM RTCMonth     AS BYTE
DIM RTCDate      AS BYTE
DIM RTCDay       AS BYTE
DIM RTCHour      AS BYTE
DIM RTCMin       AS BYTE
DIM RTCSec       AS BYTE
DIM I2C_Adr      AS BYTE
    
;Hoofdprogramma
CLS 

RTCYear = $19                     ;Datum op  29-09-19 zetten
RTCDay = $29
RTCMonth = $09
RTCDate = $01
RTCHour = $08
RTCMin = 2
RTCSec = 1

CLS
PRINT AT 1,1, "Jaar:  ", HEX RTCYear
DELAYMS 1000                            

GOSUB SetTime
DELAYMS 500
GOSUB GetTime
DELAYMS 500

PRINT AT 2,1, "Klok: ", HEX RTCYear 
GOTO Einde

' Datum / Tijd naar RTC schrijven
SetTime:

    I2C_Adr = $00
    I2COUT RTC_SDA, RTC_SCL, $D0, I2C_Adr, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]
    RETURN

' Lezen van Datum/ Tijd van de RTC
GetTime: 

    I2C_Adr = $00
    I2CIN RTC_SDA, RTC_SCL, $D0, I2C_Adr, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]
    RETURN

Einde:

END
  
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik dacht dat ic2cin/out software i2c was? (of niet?)
Dat heb je niet nodig omdat er een hardware poort is.

Is ook vreemd dat je nergens de bussnelheid moet opgeven bij iets als een i2c_init... (hoe stelt de compiler de baudrategenerator van de pic dan in?)
(ik blijf dat een heel wazige boel vinden bij Picbasic)

Je geeft ook nergens het adres van de RTC op (0x68) zo te zien. Dan geeft de chip ook nooit antwoord...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Oef, nu wordt het echt ingewikkeld.
Ik dacht dat het commando I2Cin juist was bedoeld voor PIC's met deze ondersteuning.
Wellicht verkeerd gedacht.

Maar er is ook BUSIN Commando. Die werkt zo te zien met de interne MSSP, praat met I2C devices en dat is inderdaad hardwarematig.
Wellicht is daar ook een voorbeeld van te vinden.

Fouten zijn het bewijs dat je het probeert..

Op 1 oktober 2019 00:22:19 schreef Bavelt:
Maar er is ook BUSIN Commando. Die werkt zo te zien met de interne MSSP, praat met I2C devices en dat is inderdaad hardwarematig.

Ook niet, Hbusin(Hardware_busin) wel.

Busin kun je op alle pic's gebruiken ook deze zonder MSSP module.
Hbusin is enkel te gebruiken MET MSSP module.

Dus alle instructies met een H ervoor gebruiken specifieke mogelijkheden van ingebouwde (hardware)registers/timers, alle andere worden afgehandeld met software routines.

De uitkomst blijft dezelfde, al is de H_instructie te verkiezen omdat het veel minder geheugen vraagt.

LDmicro user.
Arco

Special Member

Je moet dus zoals gezegd ook wel het i2c adres van de DS3231 opgeven, anders gaat 't nooit werken...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het blijft een taaie materie moet ik zeggen. Ik heb heel wat afgespeurd (nachtwerk). Voorbeelden voor een Arduino (en C) te over.

Maar met een PIC en PICbasis blijft het dun gezaaid.
Ik heb het nu zover dat onderstaand programma het dichtst in de buurt zou moeten komen. Het adres voor de RTC wordt binair opgegeven.
Het voorbeeld is voor een DS1307 RTC, maar die zou functioneel (inclusief adres) gelijk zijn aan de DS3231 die ik hier gebruik.
Ik gebruik de MSSP module van de PIC16F1826, zodat de RTC en DTA pinnen niet hoeven te worden gedefiniëerd.
Toch werkt onderstaand programma niet; de communicatie met de RTC slaagt niet.
Het is een beetje om moedeloos van te worden.

pic basic code:

 DEVICE = 16F1826                 
CONFIG1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_ON, CPD_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_ON, FCMEN_ON
CONFIG2 WRT_OFF, PLLEN_OFF, STVREN_ON, BORV_19, LVP_OFF
DECLARE XTAL 32
ALL_DIGITAL true
OSCCON                = %11110000	'Oscillator goed zetten voor 32Mhz 

'-------------------------------
DECLARE LCD_TYPE 0
DECLARE LCD_DTPIN LATA.0
DECLARE LCD_ENPIN LATB.2
DECLARE LCD_RSPIN LATB.3
DECLARE LCD_LINES 2
DECLARE LCD_INTERFACE 4
DECLARE LCD_DATAUS = 50
DECLARE LCD_COMMANDUS = 2000

;Er wordt gebruik gemaakt van de hardware (MSSP) module in de PIC
;Dat zijn B.1 (pin 7) voor de SDA en B.4 (pin 10) voor de SCL
   
DIM Temp1 AS BYTE
DIM Temp2 AS BYTE
DIM TempVal AS BYTE
 
DIM Seconden AS BYTE              
DIM Minuten AS BYTE               
DIM Uren AS BYTE                  
DIM Dag AS BYTE                   
DIM Datumdag AS BYTE                
DIM Maand AS BYTE                 
DIM Jaar AS BYTE                 
DIM Ctrl AS BYTE 
DIM Secs_last AS BYTE
   
DELAYMS 50
CLS                             ; Wis LCD scherm
 
Seconden = 00
Minuten = 01                    
Uren  = 02                      
Dag  = 7                        
Datumdag = 01                   
Maand= 04                       
Jaar = 09                       
 
Ctrl = 0                        ; Control byte)
 
DELAYMS 50
GOSUB Datum_Tijd_Instellen      ; initiële datum en tijd naar de RTC
   
WHILE 1 = 1
  GOSUB Datum_Tijd_Ophalen
  CLS
  PRINT AT 1,1, "Tijd: ", DEC2, Uren,  ":", DEC2 Minuten, ":", DEC2 Seconden
  PRINT AT 2,1, "Dat: ", DEC2, Datumdag ,  "/", DEC2 Maand,     "/", DEC2 Jaar
  IF Dag=1 THEN PRINT AT 2,15,"Ma"
  IF Dag=2 THEN PRINT AT 2,15,"Di" 
  IF Dag=3 THEN PRINT AT 2,15,"Wo" 
  IF Dag=4 THEN PRINT AT 2,15,"Do" 
  IF Dag=5 THEN PRINT AT 2,15,"Vr"
  IF Dag=6 THEN PRINT AT 2,15,"Za"
  IF Dag=7 THEN PRINT AT 2,15,"Zo" 
  DELAYMS 500 
  Secs_last = Seconden
WEND
 

'Instellen Datum en Tijd op de RTC
Datum_Tijd_Instellen: 

TempVal=Seconden 
GOSUB BIN_TO_BCD
Seconden=TempVal
 
TempVal=Minuten
GOSUB BIN_TO_BCD
Minuten=TempVal
 
TempVal=Uren
GOSUB BIN_TO_BCD
Uren=TempVal
 
TempVal=Dag
GOSUB BIN_TO_BCD
Dag=TempVal
 
TempVal=Datumdag
GOSUB BIN_TO_BCD
Datumdag=TempVal
 
TempVal=Maand
GOSUB BIN_TO_BCD
Maand=TempVal
 
TempVal=Jaar
GOSUB BIN_TO_BCD
Jaar=TempVal

;Volgens de datasheet zijn is het eerste BYTE 1101000x, waarbij x is lezen(1) of schrijven(0).
'De tweede byte vertelt de RTC waar te beginnen met lezen, 0 is vanaf het begin.
HBSTART
HBUSOUT 11010000, 0, [Seconden, Minuten, Uren , Dag, Datumdag , Maand, Jaar, Ctrl] 'Write initial values for time / Date
HBSTOP
RETURN

Datum_Tijd_Ophalen:

HBSTART
'Volgens de datasheet zijn is het eerste byte 1101000x, waarbij x is lezen(1) of schrijven(0).
'De tweede byte vertelt de RTC waar te beginnen met lezen, 0 is vanaf het begin.
HBUSIN 11010001 , 0 , [Seconden, Minuten, Uren , Dag, Datumdag , Maand, Jaar, Ctrl]
HBSTOP
  
'De RTC werkt met BCD waarden, daarom moeten ze worden veranderd in Binair tbv display doeleinden
TempVal=Seconden 
GOSUB BCD_TO_BIN
Seconden=TempVal
 
TempVal=Minuten
GOSUB BCD_TO_BIN
Minuten=TempVal
 
TempVal=Uren
GOSUB BCD_TO_BIN
Uren=TempVal
 
TempVal=Dag
GOSUB BCD_TO_BIN
Dag=TempVal
 
TempVal=Maand
GOSUB BCD_TO_BIN
Maand=TempVal
 
TempVal=Jaar
GOSUB BCD_TO_BIN
Jaar=TempVal
DELAYMS 100
RETURN

'------------Converteer BIN naar BCD -------------------
BIN_TO_BCD:

   Temp1 = DIG TempVal, 0                     
   Temp2 = DIG TempVal, 1                     
   Temp2 = Temp2 << 4                         
   TempVal = Temp1 ^ Temp2                    
RETURN

'------------Converteer BCD naar BIN--------------------
BCD_TO_BIN:                                   ; Converteer BCD naar BIN
   Temp1 = $0F & TempVal                      ; Clear top vier bits
   Temp1 = DIG Temp1, 0
   Temp2 = TempVal >> 4                       ; 4 posities opschuiven om een 2 BCD waarde te lezen
   Temp2 = DIG Temp2, 0
   TempVal = Temp2 * 10 + Temp1
RETURN
Fouten zijn het bewijs dat je het probeert..

Of

pic basic code:

HBUSOUT %11010000, 0, [Seconden, Minuten, Uren , Dag, Datumdag , Maand, Jaar, Ctrl]

Zonder HBSTART en HBSTOP dus.

Of

pic asm code:

HBSTART
HBUSOUT %11010000
HBUSOUT 0 
HBUSOUT Seconden 
HBUSOUT Minuten 
HBUSOUT Uren  
HBUSOUT Dag 
HBUSOUT Datumdag  
HBUSOUT Maand 
HBUSOUT Jaar 
HBUSOUT Ctrl 
HBSTOP

Begrijp uit het manual (blz 197) dat gebruik met HBSTART en HBSTOP "low-level" Hbus commands genoemd worden en de voorbeelden laten zien dat je dan alle items apart moet behandelen.