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
};




3/08/2009 05:27
Microchip’in C30′u yerine Hi-Tech’te ne var acaba?
Ya da Hi-Tide’a C30 entegre edilebiliyor mu?
3/08/2009 19:27
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
10/09/2009 15:17
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=0×83BF;
PMMODE=0×3FF;
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)&0×80
#define LCDaddr() LCDread(LCDCMD)&0×7F
#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=0×7FFF;
TRISD=0xFF00;
TRISE=0xFF00;
PORTD=0×0010;
PORTB=0×8000;
PORTE=PMDATA;
LCDinit();
putsLCD("Yıldız Bilisim");
while(1)
{
}
}
10/09/2009 15:21
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)&0×0F);
LCD_E=1;
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
Nop()
LCD_E=0;
T1CON=0×8030;
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 & 0×08)>>3 |(byte & 0×04)>>1;
temp |= (byte & 0×02)<<1 | (byte & 0×01)<<3;
return (temp);
}
void LCDInit(void){
T1CON=0×8030;
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0×03);
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0×03);
TMR1=0; while(TMR1<2);
LCD_Wr_Nibble(0×02);
LCD_Wr_Command(0×28);
LCD_Wr_Command(0×08);
LCD_Wr_Command(0×01);
TMR1=0; while(TMR1<2);
LCD_Wr_Command(0×06);
LCD_Wr_Command(0xE);
}
void Clear_LCD(){
LCD_Wr_Command(0×01);
TMR1=0; while(TMR10){
buffer[index--]=number%10+0×30;
number/=10;
}
Wr_String_Positioned_LCD_Display( buffer);
}
main(void){
TRISB=0×7FFF;
TRISD=0xFF00;
init_LCD_pins();
LCDInit();
Set_LCD_Wr();
Wr_String_Positioned_LCD_Display (“Pogramlama”);
while(1)
{
}
}
/****************************************************************************************/
10/09/2009 20:47
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(0×3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0×78EF) // 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 0×80
#define LINE_2 0xC0
#define LINE_3 0×94
#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&=0×3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0×3F0;
LCD_PORT|=da_ta&0×0F; // 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×3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0×2;
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;
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);
14/09/2009 16:18
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(0×3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0×78EF) // 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 0×80
#define LINE_2 0xC0
#define LINE_3 0×94
#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&=0×3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0×3F0;
LCD_PORT|=da_ta&0×0F; // 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×3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0×2;
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; // 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);
}
14/09/2009 21:54
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
15/09/2009 16:10
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(0×3F20) // JTAG, WDF, flash memory’ye yazma kullanılmayacak
_CONFIG2(0×78EF) // 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 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){
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&=0×3F0;
LCD_PORT|=da_ta>>4; // lcd’ye gönder, RS ve E bozulmamalı
LCD_ENABLE(); // enable
// while(1);
LCD_PORT&=0×3F0;
LCD_PORT|=da_ta&0×0F; // 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×3;
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_ENABLE();
DLY_MS(10);
LCD_PORT=0×2;
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; // latch’leri temizle
TRISE=0;
asm(“nop”); // E portu çıkış
TRISB=0×7FFF;
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);
}
16/09/2009 19:09
Bu şekilde sana cevap veremem, devre şematiğini göreliyim,
18/09/2009 15:51
Belgeyi mailinize attım. İlginiz için teşekkür ederim, iyi çalışmalar….
19/09/2009 13:03
Tamam müsait olduğumda cevaplayacağım
28/09/2009 21:56
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);
}
29/09/2009 15:06
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….
1/10/2009 21:53
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?
12/10/2009 15:31
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 = 0×33C0;
CLKDIV = 0×0000;
AD1PCFG = 0xFFFF;
while(1){
if(BUTTON1)
led10=1;
if(!BUTTON2)
led9=1;
if((!BUTTON1)&&(!BUTTON2))
led6=1;
}
}
13/10/2009 09:45
Sorun çözüldü.
TRISD=1; yazarken hata yapmışım.
TRISD = 0b00010000001000000; yazarak sorun çözüldü.
14/10/2009 19:15
Portları binary şekilde tanımlamak yerine aşağıdaki gibide tanımlayabilirsin.
TRISDbits.TRISD6=1;
TRISDbits.TRISD13=1;
veya
_TRISD6=1;
_TRISD13=1;