MPLABX IDE XC8 lcd.h kütüphanesi

Başlatan hamza777, 17 Haziran 2013, 12:38:13

hamza777

Arkadaşlar MPLABX IDE XC8 de   PIC 16 serisi için LCD.h kütüphane dosyasını nasıl  bulacağız veya ayarlayacağız.


Yardımlarınız için teşekkürler.

Mr.Java

Kendin yazacaksın.Ya da hazır istersen google'den araştıracaksınız.Hi-tech c compiler'deki lcd kütüphanesinide xc8'e uyarlayıp çalıştırabilirsin.

Tagli

Ben zamanında PIC18 için yarım yamalak bir kütüphane yazmıştım XC8'de. Az bir değişiklik ile PIC16'ya da uygulanabilir.

İlk akla gelen değişiklik LAT yerine PORT register'larının kullanılması. Bunu header dosyasında değiştirmen yeterli olur sanırım. Kütüphaneyi 4 bitlik iletişimde portun büyük bitlerini kullanacak şekilde yazmıştım. Küçük bitlerle de çalışabilir ama yazdıktan sonra test etmedim o kısmı. Ayrıca, kütüphane R/W bacağını da kullanıyor LCD'nin yeni komut için hazır olup olmadığını anlamak için. O bacak bağlanmazsa program kilitlenip kalır. "INTERNAL_WAIT" bayrağı normalde bunu kaldırmak içindi ama ona güvenme, yerine başka bekleme yapmıyor çünkü, o kısmı yazmamışım.

Kodda kullanılan bekleme kısmını "delayMS()" kendim biryerlerde yazmıştım, paylaştığım kısımda yok. Onu kendin yazabilir veya hazır bir fonksiyon kullanabilirsin ama yanlış hatırlamıyorsam XC8'in hazır fonksiyonu yüksek bekleme değerleri için sorun çıkarıyordu bir ara. Hala öyle mi bilmiyorum.

lcd.h
#ifndef LCD_H
#define LCD_H

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "globals.h"

#define LCD_DELAY 5

#define ON 1
#define OFF 0

//Control Pins
#define LCD_RS LATCbits.LATC0
#define LCD_RW LATCbits.LATC1
#define LCD_E LATCbits.LATC2

//Data Port
#define UPPER //Lower nibble support is NOT tested!
#define INTERNAL_WAIT //Wait for BF included in functions.
#define LCD_LAT LATD
#define LCD_PORT PORTD
#define LCD_TRIS TRISD

//LCD Shift Commands for lcdCommand()
#define CURSOR_LEFT B'00010000'
#define CURSOR_RIGHT B'00010100'
#define SCREEN_LEFT B'00011000'
#define SCREEN_RIGHT B'00011100'

//Function Prototypes
void lcdInit();
void lcdPutChar(char c);
char lcdBusy(void);
void lcdPutStr(char *str);
void lcdSetAddr(char addr);
void lcdCommand(char cmd);
void lcdDisplay(char onOff);
void lcdCursor(char onOff);
void lcdBlink(char onOff);
void lcdNewChar(char pos, const char *ptr);

//LCD Macros
#define lcdClear() lcdCommand(0x01)
#define lcdHome() lcdCommand(0x02)

#endif


lcd.c
#include "lcd.h"

//Local Function Prototypes
void clockE(void);
void write(char c);
char read(void);

//Local variables
char displayMode;


void lcdInit(){
	displayMode = 0x08;

#ifdef UPPER
	LCD_LAT &= 0x0F;
	LCD_TRIS &= 0x0F;
#else
	LCD_LAT &= 0xF0;
	LCD_TRIS &= 0xF0;
#endif
	LCD_E = 0;
	LCD_RS = 0;
	LCD_RW = 0;

	//----Software Reset Sequence----
	delayMS(30); // > 15 ms
#ifdef UPPER
	LCD_LAT &= 0x0F;
	LCD_LAT |= 0b00110000; //LCD_PORT = 0b00110000
#else
	LCD_LAT &= 0xF0;
	LCD_LAT |= 0b00000011;
#endif
	clockE();
	delayMS(10); // > 4.1 ms
	clockE();
	delayMS(1); // > 100 us
	clockE();

#ifdef UPPER
	LCD_LAT &= 0x0F;
	LCD_LAT |= 0b00100000; //LCD_LAT = 0b00100000
#else
	LCD_LAT &= 0xF0;
	LCD_LAT |= 0b00000010;
#endif
	clockE();

	lcdCommand(0b00101000);
	lcdCommand(0b00001000); //Shutdown everything
	lcdCommand(0b00000001); //Clear Display
	lcdCommand(0b00001100); //Display On
}

//Common write routine
void write(char c){
	LCD_RW = 0;
	char low = 0, high = 0;
	char temp = 0;

	low = c & 0x0F;
	high = (c & 0xF0) >> 4;
#ifdef UPPER
	LCD_TRIS &= 0x0F;
	LCD_LAT &= 0x0F;
#else
	LCD_TRIS &= 0xF0;
	LCD_LAT &= 0xF0;
#endif

	//Sending high nibble
#ifdef UPPER
	temp = (high << 4) & 0xF0;
#else
	temp = high & 0x0F;
#endif
	LCD_LAT |= temp;
	clockE();

	//Sending low nibble
#ifdef UPPER
	LCD_LAT &= 0x0F;
	temp = (low << 4) & 0xF0;
#else
	LCD_LAT &= 0xF0;
	temp = low & 0x0F;
#endif
	LCD_LAT |= temp;
	clockE();

#ifdef UPPER
	LCD_LAT &= 0x0F;
#else
	LCD_LAT &= 0xF0;
#endif
}

//Common read routine
char read(void){
	char temp = 0;
	LCD_RW = 1;
#ifdef UPPER
	LCD_LAT &= 0x0F;
	LCD_TRIS |= 0xF0;
#else
	LCD_LAT &= 0xF0;
	LCD_TRIS |= 0x0F;
#endif
	__delay_us(LCD_DELAY);

	LCD_E = 1;
	__delay_us(LCD_DELAY);
#ifdef UPPER
	temp |= LCD_PORT & 0xF0;
#else
	temp |= (LCD_PORT & 0x0F) << 4;
#endif
	LCD_E = 0;
	__delay_us(LCD_DELAY);

	LCD_E = 1;
	__delay_us(LCD_DELAY);
#ifdef UPPER
	temp |= (LCD_PORT & 0xF0) >> 4;
#else
	temp |= LCD_PORT & 0x0F;
#endif
	LCD_E = 0;
	__delay_us(LCD_DELAY);

	return temp;
}

void lcdCommand(char cmd){
#ifdef INTERNAL_WAIT
	while(lcdBusy() == 1);
#endif

	//Checking for display option change
	if ((cmd & 0b11111000) == 0b00001000){
		displayMode = cmd;
	}

	LCD_RS = 0;
	write(cmd);
}

void lcdPutChar(char c){
#ifdef INTERNAL_WAIT
	while(lcdBusy() == 1);
#endif
	LCD_RS = 1;
	write(c);
}

char lcdBusy(){
	LCD_RS = 0;

	if ((read() & 0b10000000) == 0b10000000)
		return 1; //LCD is busy
	else
		return 0; //LCD is free
}

void lcdPutStr(char *str){
	while (*str != '\0'){
		lcdPutChar(*str);
		++str;
	}
}

void lcdSetAddr(char addr){
	addr |= 0x80;
	lcdCommand(addr);
}

void lcdNewChar(char pos, const char *ptr){
	char i;
	char addr = (pos << 3);
	lcdCommand(addr | 0b01000000);
	for (i = 0; i < 8; ++i){
		lcdPutChar(*ptr++);
	}
}

void lcdDisplay(char onOff){
	if (onOff == OFF)	displayMode &= 0b11111011;
	else displayMode |= 0b00000100;
	lcdCommand(displayMode);
}

void lcdCursor(char onOff){
	if (onOff == OFF) displayMode &= 0b11111101;
	else displayMode |= 0b00000010;
	lcdCommand(displayMode);
}

void lcdBlink(char onOff){
	if (onOff == OFF) displayMode &= 0b11111110;
	else displayMode |= 0b00000001;
	lcdCommand(displayMode);
}

void clockE(void){
	__delay_us(LCD_DELAY);
	LCD_E = 1;
	__delay_us(LCD_DELAY);
	LCD_E = 0;
	__delay_us(LCD_DELAY);
}


Kodu yazalı baya olduğu için ayrıntılarını hatırlamıyorum. Pek genel ve kullanışlı olmamakla birlikte kod çalışıyordu ve işimi görmüştü. PIC18F4520'de denemiştim sanırım.
Gökçe Tağlıoğlu

hamza777