dsPIC30F – SPI – NOKIA3310-LCD
|Merhaba, İş yoğunluğumdan dolayı yeterince site ile ilgilenemiyorum bu nedenle yazılarımın çıkışı gecikiyor. Bu uygulamızda dsPIC30F serisinde SPI modülünü kullanarak NOKIA3310 LCD’ye yazacağız. Bu konuya ek olarak C30’da program nasıl yazılır, asm30 hakkında ve microchip 16bit microcontroller’ler hakkında biraz daha detaylı bilgileri 2008 yılında 2. picproje dergisi için hazırladığım makalede bulabilirsiniz.
Web Adresi : http://dergi.picproje.org/author/kutay/
Nokia3310 lcd ile SPI haberleşme çeşidiyle iletişim kurulur. Haberleşme bit sayısı 8bit’tir. Max. clock hızı 4mhz’e kadar kullanılabilir. LCD hakkında daha fazla bilgi için LCD driver’ının datasheet’ine bakabilirsiniz. (PCD8544)
Datasheet’i iyi incelerseniz özellikle komut setini, çok daha iyi uygulamalar yapabilirsiniz. Benim tasarladığım ve geliştirme amaçlı olarak kullandığım dsPIC30F4011 boardunda denedim. Eski alışkanlıklardan dolayı şematik çizmeden pcb çizdiğim için şemasını veremiyorum ama cadsoft eagle pcb’yi dosyası aşağıdadır.
dsPIC30F4011 board pcb dosyası
Program ve resimler aşağıdadır.
/*====================================================== Proje Adı : dsPIC30F4011 ile Nokia 3310 LCD kontrolü web site : uicroarm.com Yazan : Aykut ULUSAN, Elektronik Mühendisi, IZMIR =======================================================*/ #include "p30F3010.h" // 4011 kullanacağız #include "ascii.h" // karakter hexlerini include edelim _FOSC(CSW_FSCM_OFF & XT_PLL8); //10Mhz *8 = 80 MHz /4 = 20 MIPS _FWDT(WDT_OFF); // WDT off _FBORPOR(PBOR_OFF & PWRT_64 & MCLR_EN); // MCLR on, PWRT=64ms, PBOR off _FGS(CODE_PROT_OFF); // kod koruması off // clock ve data SPI portundan sağlanır, 40 pin DSpic30F4011 // SDI1 RF2 26 - Okuma yapılmadığı için kullanılmıyor // SDO1 RF3 25 - Kullanılıyor // SCK1 RF6 24 - Kullanılıyor /* Nokia GLCD dsPIC30F4011(40pin) SCK RF6 SDA RF3 DC PORTD2 CS PORTD0 RST PORTD3 */ #define GLCD_DC LATDbits.LATD2 // Data/Command select #define GLCD_CS LATDbits.LATD0 // Chip Select #define GLCD_RST LATDbits.LATD3 // Reset #define D 1 // data gönderilecek #define C 0 // komut gönderilecek #define off 1 // Chip select on #define on 0 // Chip select off yapıyoruz void GLCD_INIT(void); // Glcd’yi hazırla void PORT_SETUP(void); // portları hazırla void GLCD_YAZ(unsigned int DA_TA,unsigned int D_C); // GLCD’ye yaz void GLCD_CLEAR(void); // ekranı temizle void GLCD_POZISYON(unsigned int sayfa, unsigned int sutun); // koordinata git void GLCD_KARAKTER_YAZ(char c); // ekrana karakter yaz void GLCD_YAZI_YAZ(const char *s); // ekrana string yaz void DLY_MS(unsigned int ms); // 1ms - 65536ms delay sağlar void DLY_US(unsigned int us); // 1-65535 us delay sağlar void BIR_USN(void); // 1us lik delay int main (void){ PORT_SETUP(); GLCD_INIT(); GLCD_CLEAR(); // Ekranı temizle GLCD_POZISYON(0,0); // 0. sayfa 0. sütuna git GLCD_YAZI_YAZ("NOKIA 3310 LCD"); // NOKIA 3310 LCD yaz GLCD_POZISYON(1,0); // 1. sayfa 0. sutuna git GLCD_YAZI_YAZ("UICROARM.COM"); // UICROARM.COM yazar GLCD_POZISYON(2,0); GLCD_YAZI_YAZ("EEMKUTAY"); // while(1); } void PORT_SETUP(void){ ADPCFG=0xFFFF; // tüm portlar digital PORTB=0; PORTC=0; PORTD=0; PORTE=0; // SCK1 çıkış RE8 TRISB=0; // çıkış TRISC=0; TRISD=0; TRISE=0; TRISF=0xFFF4; // 0100 RF2=SDI(input) , RF3=SDO(çıkış) // Aşağıdaki şekilde 4MIPS clock hızında ,Master,Data aktiften idle’a geçerken değişir, idle clock low // state,aktif clock high state,8bit modunda, // SS1 pini kullanılmıyor olacak şekilde ayarladık SPI1CON=0x012F; SPI1STAT=0x8000; // SPI port enable } void GLCD_INIT(void){ DLY_MS(150); // beslemenin tam oturması için 150ms GLCD_CS=off; // chip select off (reset, chip select'e bakmaz) GLCD_DC=D; // Ram'i temizleyeceğimiz için data modu seçilir DLY_MS(10); // Kararlılık için 10ms bekle GLCD_RST=0; // resetle DLY_MS(50); // 50ms bekle GLCD_RST=1; // reset sonu, DLY_MS(10); GLCD_YAZ(0x21,C); // PD=0(Chip enable),V=0(Horizontel modu),H=1(extended instruction set) GLCD_YAZ(0xC8,C); // Vop (6/8 Vlcd) GLCD_YAZ(0x13,C); // 1/48 bias GLCD_YAZ(0x20,C); // PD=0 (Chip enable), V=0 (Horizontel modu), H=0 (basic instruction set) GLCD_YAZ(0x0C,C); // Normal Mode // GLCD_YAZ(0x0D,C); // Görüntüyü invert et } void GLCD_YAZ(unsigned int DA_TA,unsigned int D_C){ unsigned int temp; // overflow varsa temizleyeceğiz if (D_C==D) GLCD_DC = 1; // Data Mode else GLCD_DC = 0; // Komut Mode GLCD_CS=on; // chip on SPI1STATbits.SPIROV=0; // overflow varsa da yoksa da clear temp=SPI1BUF; // Buffer'ı temizle, SPI1BUF=DA_TA; // gönderilecek veriyi buffer'a at while(SPI1STATbits.SPITBF); while ( !SPI1STATbits.SPIRBF); GLCD_CS=off; } void GLCD_CLEAR(void){ unsigned int x; // Counter olarak kullanacağız GLCD_POZISYON(0,0); // 0.Sayfa ve 0.sutuna git for(x=0;x<504;x++) GLCD_YAZ(0x00,D); // Data yazılacak ama 0x00 } // sayfa yerine 0-5, sutun yerine 0-83 arası sayı girilebilir void GLCD_POZISYON(unsigned int sayfa, unsigned int sutun){ GLCD_YAZ((0x40|(sayfa&0x07)),C); // sayfa'in ilk 3 bitini maskele ve 0x40 ile OR'la, C=Komut GLCD_YAZ((0x80|(sutun&0x7F)),C); // Sutun için ilk 7 biti maskele 0x80 ile OR'la } void GLCD_KARAKTER_YAZ(char c) { // c urada karakterdir ve 'c' şeklinde yazılır (a harfi için = 'A'yazılır) unsigned int n; // Sadece bir counter(1 karekteri ekranda göstermek için 5 byte gerekli) unsigned int ch; // Karakterin 5 byte'nın bulunduğu yeri belirler ve tutar if ((c<32)||(c>126)) // Karekter değeri 48'den küçük veya 90'dan büyük ise c=63; // c=63 yap. (bu şart sağlanıyorsa karekter sınırlarını aşmışız demektir) ? =63 ch = (c-32)*5; // C'den 32(20h yani ilk karakterin hex değeri) çıkart ve 5 ile çarp for(n=5; n>0; n--) // ch'ı bir arttır ve gösterdiği hex'i Glcd'ye gönder GLCD_YAZ((font[ch++]),D); // 5 kez bu işlem devam eder GLCD_YAZ(0,D); // Her karakter arasında bir sütun boşluk bırakılır. } void GLCD_YAZI_YAZ(const char *s){ while(*s) GLCD_KARAKTER_YAZ(*s++); } void BIR_USN(void){ // 1 usn delay asm("REPEAT #15"); // (15+1)x50ns=800 usn asm("nop"); } // 1 usn - 65 535 usn arasında (65,536ms) void DLY_US(unsigned int us){ unsigned int c; for(c=0;c<=us;c++) BIR_USN(); } void DLY_MS(unsigned int ms){ unsigned int c; for(c=0;c<=ms;c++) DLY_US(1000); } /*======================================================== ASC2 karakterler ascii.h =========================================================*/ const char font[ ] ={ 0x0,0x0,0x0,0x0,0x0, // 32 -esp- 20 0x0,0x0,0x4F,0x0,0x0, // 33 - ! - 21 0x0,0x7,0x0,0x7,0x0, // 34 - " - 22 0x14,0x7F,0x14,0x7F,0x14, // 35 - # - 23 0x24,0x2A,0x7F,0x2A,0x12, // 36 - $ - 24 0x23,0x13,0x8,0x64,0x62, // 37 - % - 25 0x36,0x49,0x55,0x22,0x50, // 38 - & - 26 0x0,0x5,0x3,0x0,0x0, // 39 - ' - 27 0x1C,0x22,0x41,0x0,0x0, // 40 - ( - 28 0x0,0x0,0x41,0x22,0x1C, // 41 - ) - 29 0x14,0x8,0x3E,0x8,0x14, // 42 - * - 2A 0x8,0x8,0x3E,0x8,0x8, // 43 - + - 2B 0x0,0x50,0x30,0x0,0x0, // 44 - , - 2C 0x8,0x8,0x8,0x8,0x8, // 45 - - - 2D 0x0,0x60,0x60,0x0,0x0, // 46 - . - 2E 0x20,0x10,0x8,0x4,0x2, // 47 - / - 2F 0x3E,0x51,0x49,0x45,0x3E, // 48 - 0 - 30 0x0,0x42,0x7F,0x40,0x0, // 49 - 1 - 31 0x42,0x61,0x51,0x49,0x46, // 50 - 2 - 32 0x21,0x41,0x45,0x4B,0x31, // 51 - 3 - 33 0x18,0x14,0x12,0x7F,0x10, // 52 - 4 - 34 0x27,0x45,0x45,0x45,0x39, // 53 - 5 - 35 0x3C,0x4A,0x49,0x49,0x30, // 54 - 6 - 36 0x1,0x71,0x9,0x5,0x3, // 55 - 7 - 37 0x36,0x49,0x49,0x49,0x36, // 56 - 8 - 38 0x06,0x49,0x49,0x29,0x1E, // 57 - 9 - 39 0x0,0x36,0x36,0x0,0x0, // 58 - : - 3A 0x0,0x56,0x36,0x0,0x0, // 59 - ; - 3B 0x8,0x14,0x22,0x41,0x0, // 60 - < - 3C 0x14,0x14,0x14,0x14,0x14, // 61 - = - 3D 0x0,0x41,0x22,0x14,0x8, // 62 - > - 3E 0x2,0x1,0x51,0x9,0x6, // 63 - ? - 3F 0x32,0x49,0x79,0x41,0x3E, // 64 - @ - 40 0x7E,0x11,0x11,0x11,0x7E, // 65 - A - 41 0x7F,0x49,0x49,0x49,0x36, // 66 - B - 42 0x3E,0x41,0x41,0x41,0x22, // 67 - C - 43 0x7F,0x41,0x41,0x22,0x1C, // 68 - D - 44 0x7F,0x49,0x49,0x49,0x41, // 69 - E - 45 0x7F,0x9,0x9,0x9,0x1, // 70 - F - 46 0x3E,0x41,0x49,0x49,0x7A, // 71 - G - 47 0x7F,0x8,0x8,0x8,0x7F, // 72 - H - 48 0x0,0x41,0x7F,0x41,0x0, // 73 - I - 49 0x20,0x40,0x41,0x3F,0x1, // 74 - J - 4A 0x7F,0x8,0x14,0x22,0x41, // 75 - K - 4B 0x7F,0x40,0x40,0x40,0x40, // 76 - L - 4C 0x7F,0x2,0xC,0x2,0x7F, // 77 - M - 4D 0x7F,0x4,0x8,0x10,0x7F, // 78 - N - 4E 0x3E,0x41,0x41,0x41,0x3E, // 79 - O - 4F 0x7F,0x9,0x9,0x9,0x6, // 80 - P - 50 0x3E,0x41,0x51,0x21,0x5E, // 81 - Q - 51 0x7F,0x9,0x19,0x29,0x46, // 82 - R - 52 0x46,0x49,0x49,0x49,0x31, // 83 - S - 53 0x1,0x1,0x7F,0x1,0x1, // 84 - T - 54 0x3F,0x40,0x40,0x40,0x3F, // 85 - U - 55 0x1F,0x20,0x40,0x20,0x1F, // 86 - V - 56 0x3F,0x40,0x38,0x40,0x3F, // 87 - W - 57 0x63,0x14,0x8,0x14,0x63, // 88 - X - 58 0x7,0x8,0x70,0x8,0x7, // 89 - Y - 59 0x61,0x51,0x49,0x45,0x43, // 90 - Z - 5A 0x7F,0x41,0x41,0x0,0x0, // 91 - [ - 5B 0x2,0x4,0x8,0x10,0x20, // 92 - \ - 5C 0x0,0x0,0x41,0x41,0x7F, // 93 - ] - 5D 0x4,0x2,0x1,0x2,0x4, // 94 - ^ - 5E 0x40,0x40,0x40,0x40,0x40, // 95 - _ - 5F 0x0,0x1,0x2,0x4,0x0, // 96 - ` - 60 0x20,0x54,0x54,0x54,0x78, // 97 - a - 61 0x7F,0x48,0x44,0x44,0x38, // 98 - b - 62 0x38,0x44,0x44,0x44,0x20, // 99 - c - 63 0x38,0x44,0x44,0x48,0x7F, // 100 d - 64 0x38,0x54,0x54,0x54,0x18, // 101 e - 65 0x8,0x7E,0x9,0x1,0x2, // 102 f - 66 0xC,0x52,0x52,0x52,0x3E, // 103 g - 67 0x7F,0x8,0x4,0x4,0x78, // 104 h - 68 0x0,0x44,0x7D,0x40,0x0, // 105 i - 69 0x0,0x20,0x40,0x44,0x3D, // 106 j - 6A 0x7F,0x10,0x28,0x44,0x0, // 107 k - 6B 0x0,0x41,0x7F,0x40,0x0, // 108 l - 6C 0x7C,0x4,0x18,0x4,0x78, // 109 m - 6D 0x7C,0x8,0x4,0x4,0x78, // 110 n - 6E 0x38,0x44,0x44,0x44,0x38, // 111 o - 6F 0x7C,0x14,0x14,0x14,0x8, // 112 p - 70 0x8,0x14,0x14,0x18,0x7C, // 113 q - 71 0x7C,0x8,0x4,0x4,0x8, // 114 r - 72 0x48,0x54,0x54,0x54,0x20, // 115 s - 73 0x4,0x3F,0x44,0x40,0x20, // 116 t - 74 0x3C,0x40,0x40,0x20,0x7C, // 117 u - 75 0x1C,0x20,0x40,0x20,0x1C, // 118 v - 76 0x3C,0x40,0x30,0x40,0x3C, // 119 w - 77 0x44,0x28,0x10,0x28,0x44, // 120 x - 78 0xC,0x50,0x50,0x50,0x3C, // 121 y - 79 0x44,0x64,0x54,0x4C,0x44, // 122 z - 7A 0x8,0x36,0x41,0x0,0x0, // 123 { - 7B 0x0,0x0,0x7F,0x0,0x0, // 124 | - 7C 0x0,0x0,0x41,0x36,0x8, // 125 } - 7D 0x0,0x8,0x4,0x8,0x4 // 126 ~ - 7E };
Microchip’in C30’u yerine Hi-Tech’te ne var acaba?
Ya da Hi-Tide’a C30 entegre edilebiliyor mu?
Merhaba,
Hi-tech için dspic ve pic24 compiler var. Sitesinden öğrenebilirsin. Hi-tide çok önceden kullandım, PIC için tüm derleyicileri mplab içinde kullanıyorum. Ama programları harici editörde yazıyorum , mplab içinde derliyorum. Hi-tide içine başka bir derleyici gömülebileceğini sanmıyorum ama belki geliştirilmiştir. Seni yanlış yönlendirmiş olmayayım, araştır.
Kolay gelsin
Arkadaşlar LCDiçin bir kaç tane program yazdım ama çalıştıramadım ilki aşagıdaki.Bu program ilk çalıştırdığımda karakterleri karışık bir şekilde gösteriyor ancak gerillimi kesip tekrar verdiğimde program çalışmıyor….. /************************************************************/
//deneme11
//05.09.2009
#include “p24fj128ga010.h”
void LCDinit(void){
PMCON=0x83BF;
PMMODE=0x3FF;
T1CON=0X8030;
TMR1=0; while(TMR1<2000);
#define LCDDATA 1
#define LCDCMD 0
#define PMDATA PMDIN1
TRISEbits.TRISE1 = 0; //MAKE OUTPUT (LCD WR)
LATEbits.LATE1 = 1; //SET HIGH
TRISEbits.TRISE3 = 0; //MAKE OUTPUT (LCD CD)
LATEbits.LATE3 = 1; //SET HIGH
TRISEbits.TRISE4 = 0; //MAKE OUTPUT (LCD CE)
LATEbits.LATE4 = 1; //SET HIGH
PMADDR=LCDCMD;
PMDATA=0b00111000;
TMR1=0; while(TMR1<3);
PMDATA=0b00001100;
TMR1=0; while(TMR1<3);
PMDATA=0b00000001;
TMR1=0; while(TMR1<100);
PMDATA=0b00000110;
TMR1=0; while(TMR1<100);
}
char LCDread(int addr){
int dummy;
while(PMMODEbits.BUSY);
PMADDR=addr;
dummy=PMDATA;
while(PMMODEbits.BUSY);
return(PMDATA);
}
#define LCDbusy() LCDread(LCDCMD)&0x80
#define LCDaddr() LCDread(LCDCMD)&0x7F
#define getLCD() LCDread(LCDDATA)
void LCDwrite(int addr,char c){
while(LCDbusy());
while(PMMODEbits.BUSY);
PMADDR=addr;
PMDATA=c;
}
#define putLCD(d) LCDwrite(LCDDATA,(d))
#define LCDcmd(c) LCDwrite(LCDCMD,(c))
#define LCDhome() LCDwrite(LCDCMD,2)
#define LCDclr() LCDwrite(LCDCMD,1)
void putsLCD(char *s)
{
while(*s)
putLCD(*s++);
}
main(void)
{
TRISB=0x7FFF;
TRISD=0xFF00;
TRISE=0xFF00;
PORTD=0x0010;
PORTB=0x8000;
PORTE=PMDATA;
LCDinit();
putsLCD("Yıldız Bilisim");
while(1)
{
}
}
Yukardaki program düzgün çalışmayınca bende aşağıdaki programı yazdım. Yazdım ama bunu hiç çalıştıramadım……Nerde hata yaptığımı bulmam için bana yardım ederseniz çok sevinirim….İyi çalışmalar.
/*********************************************************/
//deneme16
//09.09.2009
#include “p24fj128ga010.h”
#define LCD_D0 LATEbits.LATE0
#define LCD_D1 LATEbits.LATE1
#define LCD_D2 LATEbits.LATE2
#define LCD_D3 LATEbits.LATE3
#define LCD_D4 LATEbits.LATE4
#define LCD_D5 LATEbits.LATE5
#define LCD_D6 LATEbits.LATE6
#define LCD_D7 LATEbits.LATE7
#define LCD_E LATDbits.LATD4
#define LCD_RW LATDbits.LATD5
#define LCD_RS LATBbits.LATB15
#define LCD_Data LATE
void LCD_Wr_Command ( unsigned char byte );
void LCD_Wr_Data ( unsigned char byte );
void Set_LCD1_Rd ( void );
void Set_LCD1_Wr (void );
void Clear_LCD (void);
unsigned char Bit_Reverse_Nibble ( unsigned char byte );
void Set_DD_Address_LCD_Display ( unsigned char Address );
void Write_String_Positioned_LCD_Display ( unsigned char *string );
void Write_String_LCD_Display ( char *string );
void Write_Integer_Formatted_LCD_Display ( float *number );
void init_LCD_pins(){
TRISDbits.TRISD4=0;
TRISDbits.TRISD5=0;
TRISBbits.TRISB15=0;
LATDbits.LATD4=1;
LATDbits.LATD5=1;
LATBbits.LATB15=1;
}
void LCD_Wr_Nibble(unsigned char nibble){
LCD_Data &=0xFFF0;
LCD_Data |=(Bit_Reverse_Nibble (nibble)&0x0F);
LCD_E=1;
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
LCD_E=0;
T1CON=0x8030;
TMR1=0; while(TMR1>4);
LCD_Wr_Nibble (byte );
}
void LCD_Wr_Command (unsigned char byte){
LCD_RS=0;
LCD_Wr_Byte_In_Nibbles(byte);
}
void LCD_Wr_Data(unsigned char byte){
LCD_RS=1;
LCD_Wr_Byte_In_Nibbles(byte);
}
unsigned char Bit_Reverse_Nibble (unsigned char byte ) {
unsigned char temp;
temp = byte;
temp = (byte & 0x08)>>3 |(byte & 0x04)>>1;
temp |= (byte & 0x02)<<1 | (byte & 0x01)<<3;
return (temp);
}
void LCDInit(void){
T1CON=0x8030;
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0x03);
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0x03);
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0x02);
LCD_Wr_Command(0x28);
LCD_Wr_Command(0x08);
LCD_Wr_Command(0x01);
TMR1=0; while(TMR1<2);
LCD_Wr_Command(0x06);
LCD_Wr_Command(0xE);
}
void Clear_LCD(){
LCD_Wr_Command(0x01);
TMR1=0; while(TMR10){
buffer[index–]=number%10+0x30;
number/=10;
}
Wr_String_Positioned_LCD_Display( buffer);
}
main(void){
TRISB=0x7FFF;
TRISD=0xFF00;
init_LCD_pins();
LCDInit();
Set_LCD_Wr();
Wr_String_Positioned_LCD_Display (“Pogramlama”);
while(1)
{
}
}
/****************************************************************************************/
Merhaba ,
işlemci ve bağlantı gibi küçük prosedürleri hallet çalıştır.
KUTAY
/*
Aykut ULUSAN(KUTAY)
Elektronik Mühendisi
IZMIR
http://www.uicroarm.com
işlemci : PIC24Fj32
osc: dahili fast osc, 8mhz, TCY=1us/8=125ns
LCD busy flag kullanılmayacak, 4bit interface
*/
#include //
_CONFIG1(0x3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0x78EF) // Dahili fast rc osc enable, xtal uçları boş olacak
//_CONFIG2( IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & I2C1SEL_PRI & POSCMOD_HS );
//_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & WINDIS_OFF );
#define LCD_RS LATBbits.LATB8 // lcd için register select pin
#define LCD_E LATBbits.LATB5 // lcd enable pin
#define LCD_PORT LATB
#define LCD_TRIS TRISB
#define d 1 // lcd’ye data/karakter yazılacak
#define c 0 // lcd’ye komut yazılacak
#define D d // lcd’ye data/karakter yazılacak
#define C c // lcd’ye komut yazılacak
#define NOP() {__asm__ volatile (“nop”);}
#define CLRWDT() {__asm__ volatile (“clrwdt”);}
#define SLEEP() {__asm__ volatile (“pwrsav #0”);}
#define IDLE() {__asm__ volatile (“pwrsav #1”);}
#define LINE_1 0x80
#define LINE_2 0xC0
#define LINE_3 0x94
#define LINE_4 0xD4
/*
LCD PIC24
D4 PORTBbits.RB0
D5 PORTBbits.RB1
D6 PORTBbits.RB2
D7 PORTBbits.RB3
*/
// X*10US
void
DLY_10US(unsigned int us){
while(us–) {
__asm__ volatile (“repeat #33”);
__asm__ volatile (“nop”);
}
}
// 65536ms’ye kadar
void
DLY_MS(unsigned int ms){
while(ms–){
DLY_10US(100);
}
}
void
LCD_ENABLE(void){
LCD_E=1;asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);LCD_E=0;
}
void
LCD_WRITE(unsigned char da_ta, unsigned char D_C){
if(D_C) LCD_RS=1; // data modu
else LCD_RS=0; // komut modu
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta&0x0F; // lcd’ye gönder
LCD_ENABLE(); // enable
DLY_10US(50); // 50us delay
LCD_RS=0;
}
void
LCD_SETUP(void){
DLY_MS(100); // lcd’nin kendini hazırlaması için 100ms
LCD_PORT=0x3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0x2;
LCD_ENABLE();
DLY_MS(10);
LCD_WRITE(0x28,c); // disp on, cursor off
LCD_WRITE(0x0c,c); //
LCD_WRITE(0x06,c); //
LCD_WRITE(0x01,c); // clear display
LCD_WRITE(0x02,c); //
DLY_MS(2);
}
void
LCD_STRING(const char *str){
while(*str)
LCD_WRITE(*str++,d);
}
void
LCD_GOTO(unsigned char satir,unsigned char adres){
LCD_WRITE(satir+adres,c);
}
int
main(void){
OSCCON=0;
CLKDIV=0;
AD1PCFG=0xFFFF; // portlar dijital
PMCON=0;
PORTB=0; // latch’leri temizle
TRISB=0; asm(“NOP”); // B portu çıkış
LCD_SETUP();
LCD_GOTO(LINE_1,0);
LCD_STRING(“www.uicroarm.com”);
LCD_GOTO(LINE_2,0);
LCD_STRING(“PIC24 by Kutay”);
while(1);
return(0);
Aşağıdaki gibi değişiklikleri yapıp hataları düzelttim ama yinede çalışmadı program (LCD portE’ ye bağlı)….
#include “p24fj128ga010.h”
_FOSC(CSW_FSCM_OFF );
_FOSC(XT_PLL8);
_FWDT(WDT_OFF);
_CONFIG1(0x3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0x78EF) // Dahili fast rc osc enable, xtal uçları boş olacak
//_CONFIG2( IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & I2C1SEL_PRI & POSCMOD_HS );
//_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & WINDIS_OFF );
#define LCD_RS LATBbits.LATB15 // lcd için register select pin
#define LCD_E LATDbits.LATD4 // lcd enable pin
#define LCD_PORT LATE
#define LCD_TRIS TRISE
#define d 1 // lcd’ye data/karakter yazılacak
#define c 0 // lcd’ye komut yazılacak
#define D d // lcd’ye data/karakter yazılacak
#define C c // lcd’ye komut yazılacak
#define CLRWDT() {__asm__ volatile (“clrwdt”);}
#define SLEEP() {__asm__ volatile (“pwrsav #0”);}
#define IDLE() {__asm__ volatile (“pwrsav #1”);}
#define LINE_1 0x80
#define LINE_2 0xC0
#define LINE_3 0x94
#define LINE_4 0xD4
void
DLY_10US(unsigned int us){
asm(“REPEAT #33”);
asm(“nop”);}
// 65536ms’ye kadar
void
DLY_MS(unsigned int ms){
DLY_10US(100);
}
void
LCD_ENABLE(void){
LCD_E=1;asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);LCD_E=0;
}
void
LCD_WRITE(unsigned char da_ta, unsigned char D_C){
if(D_C) LCD_RS=1; // data modu
else LCD_RS=0; // komut modu
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta&0x0F; // lcd’ye gönder
LCD_ENABLE(); // enable
DLY_10US(50); // 50us delay
LCD_RS=0;
}
void
LCD_SETUP(void){
DLY_MS(100); // lcd’nin kendini hazırlaması için 100ms
LCD_PORT=0x3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0x2;
LCD_ENABLE();
DLY_MS(10);
LCD_WRITE(0x28,c); // disp on, cursor off
LCD_WRITE(0x0c,c); //
LCD_WRITE(0x06,c); //
LCD_WRITE(0x01,c); // clear display
LCD_WRITE(0x02,c); //
DLY_MS(2);
}
void
LCD_STRING(const char *str){
while(*str)
LCD_WRITE(*str++,d);
}
void
LCD_GOTO(unsigned char satir,unsigned char adres){
LCD_WRITE(satir+adres,c);
}
int
main(void){
OSCCON=0;
CLKDIV=0;
AD1PCFG=0xFFFF; // portlar dijital
PMCON=0;
PORTE=0; // latch’leri temizle
TRISE=0; asm(“nop”); // E portu çıkış
LCD_SETUP();
LCD_GOTO(LINE_1,0);
LCD_STRING(”www.uicroarm.com”);
LCD_GOTO(LINE_2,0);
LCD_STRING(”PIC24 by Kutay”);
while(1);
return(0);
}
1) LCD_E : D portunu kullanmışsın ama hazırlamamışsın , TRISD=0;
2) Delay’i yanlış yapmışsın, ms hiç kullanılmamış , benim gönderdiğim örneğe bak
void DLY_MS(unsigned int ms){ // hep 1ms delay yapar
DLY_10US(100);
}
3) benim ayarladığım configler yeterli aşağıdakilere gerek yok (sanırım senin c30 eski versiyon veya c24 olanlardan )
_FOSC(CSW_FSCM_OFF );
_FOSC(XT_PLL8);
_FWDT(WDT_OFF);
Fazla incelemedim ama birkere bunlar gözüme battı.
Benim gönderdiğim kodu çalıştır sonra port değiştirsin
Yardımlarınız için çok teşekkür ederim. Belirttiğiniz noktalara dikkat ettim ve düzelttim….Displayde 1. satırda japon karakterlerine benzeyen ilginç şeyler çıktı. Line adreslerini değiştirip bir şeyler yapayım dedim olmadı…Sorunun kaynağını bulamadım, sizide meşkul ediyorum kusuruma bakmayın….İyi çalışmalar….
/************************************************************************************************************************************************************/
//deneme 17
//14.09.2009
#include “p24fj128ga010.h”
_CONFIG1(0x3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0x78EF) // Dahili fast rc osc enable, xtal uçları boş olacak
//_CONFIG2( IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & I2C1SEL_PRI & POSCMOD_HS );
//_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & WINDIS_OFF );
#define LCD_RS LATBbits.LATB15 // lcd için register select pin
#define LCD_E LATDbits.LATD4 // lcd enable pin
#define LCD_RW LATDbits.LATD5 // lcd R/W pin
#define LCD_PORT LATE
#define LCD_TRIS TRISE
#define d 1 // lcd’ye data/karakter yazılacak
#define c 0 // lcd’ye komut yazılacak
#define D d // lcd’ye data/karakter yazılacak
#define C c // lcd’ye komut yazılacak
#define CLRWDT() {__asm__ volatile (“clrwdt”);}
#define SLEEP() {__asm__ volatile (“pwrsav #0”);}
#define IDLE() {__asm__ volatile (“pwrsav #1”);}
#define LINE_1 0x80
#define LINE_2 0xC0
#define LINE_3 0x94
#define LINE_4 0xD4
// X*10US
void
DLY_10US(unsigned int us){
asm(“REPEAT #33”);
asm(“nop”);
}
// 65536ms’ye kadar
void
DLY_MS(unsigned int ms){
DLY_10US(100);
}
void
LCD_ENABLE(void){
LCD_E=1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
LCD_E=0;
}
void
LCD_WRITE(unsigned char da_ta, unsigned char D_C){
if(D_C) LCD_RS=1; // data modu
else LCD_RS=0; // komut modu
LCD_RW=0;
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0x3F0;
LCD_PORT|=da_ta&0x0F; // lcd’ye gönder
LCD_ENABLE(); // enable
DLY_10US(50); // 50us delay
LCD_RS=0;
}
void
LCD_SETUP(void){
DLY_MS(100); // lcd’nin kendini hazırlaması için 100ms
LCD_PORT=0x3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0x2;
LCD_ENABLE();
DLY_MS(10);
LCD_WRITE(0x28,c); // disp on, cursor off
LCD_WRITE(0x0c,c); //
LCD_WRITE(0x06,c); //
LCD_WRITE(0x01,c); // clear display
LCD_WRITE(0x02,c); //
DLY_MS(2);
}
void
LCD_STRING(const char *str){
while(*str)
LCD_WRITE(*str++,d);
}
void
LCD_GOTO(unsigned char satir,unsigned char adres){
LCD_WRITE(satir+adres,c);
}
int
main(void){
OSCCON=0;
CLKDIV=0;
AD1PCFG=0xFFFF; // portlar dijital
PMCON=0;
PORTE=0; // latch’leri temizle
TRISE=0;
asm(“nop”); // E portu çıkış
TRISB=0x7FFF;
asm(“nop”);
TRISD=0;
LCD_SETUP();
LCD_GOTO(LINE_1,0);
LCD_STRING(“Yıldız”);
LCD_GOTO(LINE_2,0);
LCD_STRING(“14.09.2009”);
while(1);
return(0);
}
Bu şekilde sana cevap veremem, devre şematiğini göreliyim,
Belgeyi mailinize attım. İlginiz için teşekkür ederim, iyi çalışmalar….
Tamam müsait olduğumda cevaplayacağım
Merhaba,
Hatalarını düzelttim, dene, sorun çıkarsa yine osc ve config’e ayarlarına bak. Benim bit bit tanımladığım gibi sende config’i tanımlayabilirsin.
#include “p24fj128ga010.h”
_CONFIG1(0×3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0×78EF) // Dahili fast rc osc enable, xtal uçları boş olacak
#define LCD_RS LATBbits.LATB15 // lcd için register select pin
#define LCD_E LATDbits.LATD4 // lcd enable pin
#define LCD_RW LATDbits.LATD5 // lcd R/W pin
#define LCD_PORT LATE
#define LCD_TRIS TRISE
#define d 1 // lcd’ye data/karakter yazılacak
#define c 0 // lcd’ye komut yazılacak
#define D d // lcd’ye data/karakter yazılacak
#define C c // lcd’ye komut yazılacak
#define LINE_1 0×80
#define LINE_2 0xC0
#define LINE_3 0×94
#define LINE_4 0xD4
// X*10US
void
DLY_10US(unsigned int us){
asm(”REPEAT #33″);
asm(”nop”);
}
// 65536ms’ye kadar
void
DLY_MS(unsigned int ms){
while(ms–){DLY_10US(100);};
}
void
LCD_ENABLE(void){
LCD_E=1;
asm(”nop”);
asm(”nop”);
asm(”nop”);
asm(”nop”);
LCD_E=0;
}
//RE4-RE7 data pinleri
void
LCD_WRITE(unsigned char da_ta, unsigned char D_C){
if(D_C) LCD_RS=1; // data modu
else LCD_RS=0; // komut modu
LCD_PORT&=0×FFF0;
LCD_PORT|=(unsigned int)da_ta<<4; // lcd’ye gönder, RS ve E bozulmamalı LCD_ENABLE(); // enable LCD_PORT&=0×FFF0; LCD_PORT|=(unsigned int)da_ta&0×F0; // lcd’ye gönder LCD_ENABLE(); // enable DLY_10US(50); // 50us delay LCD_RS=0; } void LCD_SETUP(void){ DLY_MS(100); // lcd’nin kendini hazırlaması için 100ms LCD_PORT|=0×30; LCD_ENABLE(); DLY_MS(10); LCD_ENABLE(); DLY_MS(10); LCD_ENABLE(); DLY_MS(10); LCD_PORT|=0×20; LCD_ENABLE(); DLY_MS(10); LCD_WRITE(0×28,c); // disp on, cursor off LCD_WRITE(0×0c,c); // LCD_WRITE(0×06,c); // LCD_WRITE(0×01,c); // clear display LCD_WRITE(0×02,c); // DLY_MS(2); } void LCD_STRING(const char *str){ while(*str) LCD_WRITE(*str++,d); } void LCD_GOTO(unsigned char satir,unsigned char adres){ LCD_WRITE(satir+adres,c); } int main(void){ OSCCON=0; CLKDIV=0; AD1PCFG=0xFFFF; // portlar dijital PMCON=0; PORTE=0; PORTE=0; PORTD=0; TRISE=0; TRISB=0×7FFF; TRISD=0; // LCD_RW=0; // gerek yok, default olarak 0 LCD_SETUP(); LCD_GOTO(LINE_1,0); // LCD_STRING(”Yıldız”); // yanlış kullanım, türkçe karakter olmaz LCD_STRING(”Yildiz”); // doğrusu LCD_GOTO(LINE_2,0); LCD_STRING(”14.09.2009″); while(1); return(0); }
Merhaba Aykut Bey,
Ben sitedeki projelerden yola çıkarak buna benzer program yazmıştım. Bu verdiğiniz programıda yazdım, ikisindede aynı sorun oluyor. LCD nin ilk satırı komple siyah oluyor. Tek harf yazdığımdada aynı şey oluyor..Donanım olarak bir sorun olduğunu düşünmüyorum çünkü microchipin demo programını kullandığımda lcd sorunsuz bir şekilde çalışıyor….Demo programı inceliyorum fakat bir fark göremedim….
Merhaba,
Geliştirme boardu kullandığın için donanımda sorun olduğunu düşünmedim. Fakat sana pic24FJ64 ile çalışan lcd kodu verdim bundan sonrası sana düşüyor çünkü farklı işlemci, farklı portlar ve farklı donanım var. Yapman gereken ufak bir kaç değişiklik. Biraz osilaskop kullanarak veya işlemci bilgisiyle, port testleriyle ve birazda LCD nasıl çalışır bilgisiyle bu işi çözebilirsin.
Mesela işlemci osc çalışıyor mu, kaç Mhz’de çalışıyor? Osilaskopla data ve kontrol sinyalleri lcd’ye doğru iletiliyor mu? Kontrol ettin mi?
Merhaba,
Aşağıda butona basınca yanan led programı yazdım, fakat çalışmıyor. Ben hatayı göremedim…Butondan veriyi okuyamıyorum galiba…
#include “p24fj128ga010.h”
#define led10 LATAbits.LATA7
#define led9 LATAbits.LATA6
#define led6 LATAbits.LATA3
#define BUTTON1 PORTDbits.RD6
#define BUTTON2 PORTDbits.RD13
int main(void){
TRISA=0;
TRISD=1;
OSCCON = 0x33C0;
CLKDIV = 0x0000;
AD1PCFG = 0xFFFF;
while(1){
if(BUTTON1)
led10=1;
if(!BUTTON2)
led9=1;
if((!BUTTON1)&&(!BUTTON2))
led6=1;
}
}
Sorun çözüldü.
TRISD=1; yazarken hata yapmışım.
TRISD = 0b00010000001000000; yazarak sorun çözüldü.
Portları binary şekilde tanımlamak yerine aşağıdaki gibide tanımlayabilirsin.
TRISDbits.TRISD6=1;
TRISDbits.TRISD13=1;
veya
_TRISD6=1;
_TRISD13=1;