Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

xc8 lcd sorunu

Başlatan canbulut, 27 Kasım 2013, 14:36:23

canbulut

Arkadaslar xc8 ile yeni çalışmaya başladım.denemelerimde proteus'da picin osilatörünü 1 ve 4 mhzde ayarlayınca lcd'de yazdıklarım görünüyor fakat 20mhz yaptığımda görünmüyor.
xc8'in xlcd.h ve delays.h kullanıldı.

MrDarK

Genelde bu tarz projelerde kodlarınızıda paylaşmanız gerekir yardım alabilmek için.

Aklıma gelen ilk şey sigorta ayarı yaptınız mı ? XT , HS şeklinde
Picproje Eğitim Gönüllüleri ~ MrDarK

Kabil ATICI

Eğer zamanlamaları değiştirmeden kullanmaya kalkarsan sıkıntı olabilir. Burada belirtmemişsin özellikle  LCD'nin busy ucunu kullanmıyorsan sorun olur. Çünkü LCD iş yapması için gereken zamanı ona göre vermen gerekir.
Yani diyelim ki 4 MHz'de  LCD bir işlem 5ms sürüyor bunu yapılan işlemcide yapılan işlemler ile kapatabilirken saat frekansını 20MHz çıkardığın zaman  senin işlemcin 5ms sürmesi gereken işlemi 5 kez daha hızlı yapar. Bu durumda senin işleni 1ms sürer ama LCD aynı işlemi yine 5 ms'de yapar. Ve hata kaçınılmaz olur.

LCD içingereken  zamanlamaları incele,
İsis'in verdiği uyarıları bir kontrol et. Muhtemelen sana bir şey anlatmaya çalışıyor olabilir.
ambar7

canbulut

dosyalar olsa daha iyi olur sanırım.Çok Çeşitli denemeler yaptım ama sonuç hep hüsran hep hüsran :)


lcd.c
/* 
 * File:   lcd_app.c
 * Author: 
 *
 * 
 */

#include <plib/xlcd.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib/delays.h>
#include <p18f2520.h>
#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1H
#pragma config OSC = XT        // Oscillator Selection bits (HS oscillator)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)

// CONFIG2H
#pragma config WDT = ON         // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks

#define _XTAL_FREQ   20000000

void init_XLCD(void); //Initialize LCD display
void DelayFor18TCY( void ); //18 cycles delay
void DelayPORXLCD (void); // Delay of 15ms
void DelayXLCD (void); // Delay of 5ms

void main(void)
{
 init_XLCD(); //Call the Initialize LCD display function
 putrsXLCD("Hello World"); //Display "Hello World"
 SetDDRamAddr(0x40); //shift cursor to beginning of second line
 putrsXLCD("LCD Display"); //Display "LCD display"
 while(1)
 {
 }
 }
void init_XLCD(void) //Initialize LCD display
{  OpenXLCD(FOUR_BIT&LINES_5X7); //configure LCD in 4-bit Data Interface mode
 //and 5x7 characters, multiple line display
 while(BusyXLCD()); //Check if the LCD controller is not busy
 //before writing some commands?
 WriteCmdXLCD(0x06); // move cursor right, don't shift display
 WriteCmdXLCD(0x0C); //turn display on without cursor

 }
void DelayFor18TCY( void ) //18 cycles delay
{
 Nop( ); Nop( ); Nop( ); Nop( ); // 18 cycle delay
 Nop( ); Nop( ); Nop( ); Nop( );
 Nop( ); Nop( ); Nop( ); Nop( );
 Nop( ); Nop( );
 return;
}

void DelayPORXLCD (void) // Delay of 15ms
{
 Delay1KTCYx(30);
}

void DelayXLCD (void) // Delay of 5ms
{
 Delay1KTCYx(10);
}


xlcd.h
#ifndef __XLCD_H
#define __XLCD_H
#include "p18cxxx.h"
/* PIC18 XLCD peripheral routines.
 *
 *   Notes:
 *      - These libraries routines are written to support the
 *        Hitachi HD44780 LCD controller.
 *      - The user must define the following items:
 *          - The LCD interface type (4- or 8-bits)
 *          - If 4-bit mode
 *              - whether using the upper or lower nibble
 *          - The data port
 *              - The tris register for data port
 *              - The control signal ports and pins
 *              - The control signal port tris and pins
 *          - The user must provide three delay routines:
 *              - DelayFor18TCY() provides a 18 Tcy delay
 *              - DelayPORXLCD() provides at least 15ms delay
 *              - DelayXLCD() provides at least 5ms delay
 */

/* Interface type 8-bit or 4-bit
 * For 8-bit operation uncomment the #define BIT8
 */
/* #define BIT8 */

/* When in 4-bit interface define if the data is in the upper
 * or lower nibble.  For lower nibble, comment the #define UPPER
 */
/* #define UPPER */

/* DATA_PORT defines the port to which the LCD data lines are connected */
 #define DATA_PORT      		PORTB
 #define TRIS_DATA_PORT 		TRISB
 #define BIT4
 #define LOWER
/* CTRL_PORT defines the port where the control lines are connected.
 * These are just samples, change to match your application.
 */
 #define RW_PIN   LATBbits.LATB6   		/* PORT for RW */
 #define TRIS_RW  TRISBbits.TRISB6    	/* TRIS for RW */

 #define RS_PIN   LATBbits.LATB5   		/* PORT for RS */
 #define TRIS_RS  TRISBbits.TRISB5    	/* TRIS for RS */

 #define E_PIN    LATBbits.LATB4  		/* PORT for D  */
 #define TRIS_E   TRISBbits.TRISB4    	/* TRIS for E  */

/* Display ON/OFF Control defines */
#define DON         0b00001111  /* Display on      */
#define DOFF        0b00001011  /* Display off     */
#define CURSOR_ON   0b00001111  /* Cursor on       */
#define CURSOR_OFF  0b00001101  /* Cursor off      */
#define BLINK_ON    0b00001111  /* Cursor Blink    */
#define BLINK_OFF   0b00001110  /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT    0b00000100  /* Cursor shifts to the left   */
#define SHIFT_CUR_RIGHT   0b00000101  /* Cursor shifts to the right  */
#define SHIFT_DISP_LEFT   0b00000110  /* Display shifts to the left  */
#define SHIFT_DISP_RIGHT  0b00000111  /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT   0b00101100  /* 4-bit Interface               */
#define EIGHT_BIT  0b00111100  /* 8-bit Interface               */
#define LINE_5X7   0b00110000  /* 5x7 characters, single line   */
#define LINE_5X10  0b00110100  /* 5x10 characters               */
#define LINES_5X7  0b00111000  /* 5x7 characters, multiple line */

#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif

#ifndef MEM_MODEL
#ifdef _OMNI_CODE_
#define MEM_MODEL
#else
#define MEM_MODEL far  /* Change this to near for small memory model */
#endif
#endif

/* OpenXLCD
 * Configures I/O pins for external LCD
 */
void OpenXLCD(PARAM_SCLASS unsigned char);

/* SetCGRamAddr
 * Sets the character generator address
 */
void SetCGRamAddr(PARAM_SCLASS unsigned char);

/* SetDDRamAddr
 * Sets the display data address
 */
void SetDDRamAddr(PARAM_SCLASS unsigned char);

/* BusyXLCD
 * Returns the busy status of the LCD
 */
unsigned char BusyXLCD(void);

/* ReadAddrXLCD
 * Reads the current address
 */
unsigned char ReadAddrXLCD(void);

/* ReadDataXLCD
 * Reads a byte of data
 */
char ReadDataXLCD(void);

/* WriteCmdXLCD
 * Writes a command to the LCD
 */
void WriteCmdXLCD(PARAM_SCLASS unsigned char);

/* WriteDataXLCD
 * Writes a data byte to the LCD
 */
void WriteDataXLCD(PARAM_SCLASS char);

/* putcXLCD
 * A putc is a write
 */
#define putcXLCD WriteDataXLCD

/* putsXLCD
 * Writes a string of characters to the LCD
 */
void putsXLCD(PARAM_SCLASS char *);

/* putrsXLCD
 * Writes a string of characters in ROM to the LCD
 */
void putrsXLCD(const char *);

/* User defines these routines according to the oscillator frequency */
extern void DelayFor18TCY(void);
extern void DelayPORXLCD(void);
extern void DelayXLCD(void);

#endif


delays.h
#ifndef __DELAYS_H
#define __DELAYS_H

/* C18 cycle-count delay routines. */

/* Delay of exactly 1 Tcy */
#define Delay1TCY() _delay(1)

/* Delay of exactly 10 Tcy */
#define Delay10TCY() _delay(10)

/* Delay1TCYx */
void Delay1TCYx(unsigned char);

/* Delay10TCYx
 * Delay multiples of 10 Tcy
 * Passing 0 (zero) results in a delay of 2560 cycles.
 */
void Delay10TCYx(unsigned char);

/* Delay100TCYx
 * Delay multiples of 100 Tcy
 * Passing 0 (zero) results in a delay of 25,600 cycles.
 */
void Delay100TCYx(unsigned char);

/* Delay1KTCYx
 * Delay multiples of 1000 Tcy
 * Passing 0 (zero) results in a delay of 256,000 cycles.
 */
void Delay1KTCYx(unsigned char);

/* Delay10KTCYx
 * Delay multiples of 10,000 Tcy
 * Passing 0 (zero) results in a delay of 2,560,000 cycles.
 */
void Delay10KTCYx(unsigned char);

#endif




Kabil ATICI

void DelayFor18TCY( void ) //18 cycles delay
{
Nop( ); Nop( ); Nop( ); Nop( ); // 18 cycle delay
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( );
return;
}

bunun gibi. Burada nop komutu (burada fonksiyon) 14 (sanırım fonksiyona çağırma ve geri dönüş de dahil edilerek 18 cycles bekleme) tane çevrimde işlemciyi bekletir.
4 MHZ için hadi idare edebilir ama 20 MHz için ne olur? Zaman olarak düşünürse çok kısalır.
ambar7

canbulut

Alıntı yapılan: ambar7 - 27 Kasım 2013, 15:42:44
void DelayFor18TCY( void ) //18 cycles delay
{
Nop( ); Nop( ); Nop( ); Nop( ); // 18 cycle delay
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( );
return;
}

bunun gibi. Burada nop komutu (burada fonksiyon) 14 (sanırım fonksiyona çağırma ve geri dönüş de dahil edilerek 18 cycles bekleme) tane çevrimde işlemciyi bekletir.
4 MHZ için hadi idare edebilir ama 20 MHz için ne olur? Zaman olarak düşünürse çok kısalır.

peki hocam ne yapmamız gerekir?

Kabil ATICI

buradaki bekleme olayını 5 katına çıkarmak için basitçe buradaki nop fonksiyonlarına 4x18=72 nop eklemek gerek. O zaman toplamda 86 tane nop olacak.

Aynı olayı döngüler ile de yapılabilir. O zaman döngü gecikmelerini göz önüne alınarak hesaplamak gerekir.

ayın olay zamanlama (delay gerektiren tüm satırlar için göz önüne alınmalıdır.)
örneğin;
/* Delay of exactly 1 Tcy */
#define Delay1TCY() _delay(1)

/* Delay of exactly 10 Tcy */
#define Delay10TCY() _delay(10)

void DelayPORXLCD (void); // Delay of 15ms
void DelayXLCD (void); // Delay of 5ms

örneğin yukarıdaki iki fonksiyonun kullanıldığı yerlerde belirtiler ms değerini vermen gerekir. Yoksa LCD başlama işlemleri yerine getirilmemiş olur. Buradaki ms değerleri nasıl hesaplanıyor bunu incelemen lazım.
ambar7

canbulut

Alıntı yapılan: ambar7 - 27 Kasım 2013, 15:26:09
Eğer zamanlamaları değiştirmeden kullanmaya kalkarsan sıkıntı olabilir. Burada belirtmemişsin özellikle  LCD'nin busy ucunu kullanmıyorsan sorun olur. Çünkü LCD iş yapması için gereken zamanı ona göre vermen gerekir.
Yani diyelim ki 4 MHz'de  LCD bir işlem 5ms sürüyor bunu yapılan işlemcide yapılan işlemler ile kapatabilirken saat frekansını 20MHz çıkardığın zaman  senin işlemcin 5ms sürmesi gereken işlemi 5 kez daha hızlı yapar. Bu durumda senin işleni 1ms sürer ama LCD aynı işlemi yine 5 ms'de yapar. Ve hata kaçınılmaz olur.

LCD içingereken  zamanlamaları incele,
İsis'in verdiği uyarıları bir kontrol et. Muhtemelen sana bir şey anlatmaya çalışıyor olabilir.

hocam burdaki busy'i kullanma olayını nasıl gerçekleştirebiliriz?

Kabil ATICI

Burada sözü edilen RW bacağının kullanmama durumu idi ama gördüğüm kadarı ile RW bacağı kullanılıyor.
Busy durumu kullanılıyor görünüyor.
Not: Busy durumu LCD'ye bir komut veya iş verildiği zaman LCD'nin gönderilen komutlara ve verilere yanıt vermeme durumudur. Bu LCD bağlantısının 7. bacağı üzerinden okunabilir.
ambar7

canbulut

Ben faal kullanılıp kullanılmadığını bilmiyorum.pin olarak bağlı yazılımsal işlev yapmıyor olabilir.belkide ayrıca düşük yapılması gerekebilir.

Kabil ATICI

 //and 5x7 characters, multiple line display
while(BusyXLCD()); //Check if the LCD controller is not busy<<<<< burada busy kontrolu
//before writing some commands?
ambar7

metaltrrocker

20mhz kristal kullanıyorsanız,configuration ayarlarında XT değil de HS yapmak gerekiyor diye biliyorum.Yanlış biliyor da olabilirim.

canbulut

Alıntı yapılan: metaltrrocker - 27 Kasım 2013, 19:18:29
20mhz kristal kullanıyorsanız,configuration ayarlarında XT değil de HS yapmak gerekiyor diye biliyorum.Yanlış biliyor da olabilirim.
doğrudur hocamda öyle göründüğüne bakmayın.ambar7 hocam tam isabetlemiş çözüldü.Sağolsun.

canbulut

#13
Tekrar merhaba arkadaslar,
sorun aynı konunun devamı niteliğinde olduğundan yeni konu açmadım.devrem proteusta çalışıyor fakat gerçekte çalışmıyor.aynı config ayarları ile led ile tarama yaptım hexini yükledim(karaşimşek) yüklendi çalışıyor.aynı zamanda başka derleyicilerle yaptığım kodlama çalışıyor.yani devrede düzgün çalışır durumda.bu derleyicide xc8 bir türlü 2x16 lcd'yi çalıştıramadım.dosyanın içeriği burda.ilgilenirseniz sevinirim.
http://www.dosya.tc/server20/rXgr1V/lcd_demos1.X.zip.html

MrDarK

Proje ekinde bağlantı pinlerini varsa kurduğun board üzerindeki devrenin resmi gerek yoksa simulasyonda çalışıyor. Kullandığın Lcd'nin ayak bağlantıları için uygun datasheet araştırdın mı ?

Yani xc8 le ilgili bir sıkıntı gözükmüyor
Picproje Eğitim Gönüllüleri ~ MrDarK