Автор Тема: PIC18F252 JM204A  (Прочетена 18040 пъти)

Emaloumen

  • Робо-Новак
  • *****
  • Публикации: 11
    • Профил
PIC18F252 JM204A
« -: Януари 09, 2008, 01:10:12 am »
Някой може ли да ми помогне като ми даде примерен код на C
за управление на матричен LCD модул за PIC18F252.Този който ми е под ръка е JM204A.
Искам да съм първи клас

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
PIC18F252 JM204A
« Отговор #1 -: Януари 09, 2008, 02:59:04 pm »
Здравей :) До някъде имаш късмет. Аз ползвам JM202A. Това е кода за него :
#define BL PIN_B3
#define RS PIN_B2
#define RW PIN_B1
#define E  PIN_B0
/*---------------------======PIN DEFINITION======-------------------------------
PIN_B3 - BackLight(BL)
PIN_B2 - Register Select (RS)
PIN_B1 - Read/Write (RW)
PIN_B0 - Enable (E)
PIN_D0 - Data Bit 0 (DB0)
PIN_D1 - Data Bit 1 (DB1)
PIN_D2 - Data Bit 2 (DB2)
PIN_D3 - Data Bit 3 (DB3)
PIN_D4 - Data Bit 4 (DB4)
PIN_D5 - Data Bit 5 (DB5)
PIN_D6 - Data Bit 6 (DB6)
PIN_D7 - Data Bit 7 (DB7)
==============================================================================*/

void Clear_Display(void);
//Clears display and AC (address counter) = 0
void Home(void);
//Sets cursor at home
void Mode_Set(int1 ID, int1 SH);
//I/D  0 - decrease  SH 0 - display shift off at Read/Write
//     1 - increase     1 - display shift on at Read/Write
void Disp_Curs_On_Off(int1 D, int1 C, int1 B);
//D 0 - display off  C 0 - cursor off  B 0 - cursor blinking off
//D 1 - display on     1 - cursor on     1 - cursor blinking on
void Disp_Curs_Shift(int1 S_CD, int1 RL);
//S_CD 0 - cursor shift  RL 0 - left
//     1 - display shift    1 - right
void Function_Set(int1 DL, int1 N, int1 F);
//DL 0 - 4bits interface  N 0 - 1 row  F 0 - 5x8 font
//   1 - 8bits interface  N 1 - 2 rows   1 - 5x10 font
void CGRAM_Adrs(int Adrs);
//Send CGRAM Adrs, Adrs - 6bits
void DDRAM_Adrs(int Adrs);
//Send DDRAM Adrs, Adrs - 7bits
void Write_Data(int data);
//Send data(char), data - 8bits
int Read_Data(int data);
//Read data
int1 Read_BF_AC(int* AC);
//Read Busy Flag (BF) and Address Counter (AC)
void Init_LCD(void);
//initialize LCD
void Set_Zeros(void);
//Set zeros after instruction
void Write_str(char* data, int n);
//write string on the LCD
void Write_number(signed int32 d);
//write number on the LCD

void Clear_Display()
{
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(0x01);
   output_bit(E, 1);
   delay_ms(2);
   Set_Zeros();

}

void Home()
{
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(0x02);
   output_bit(E, 1);
   delay_ms(2);
   Set_Zeros();

}

void Mode_Set(int1 ID, int1 SH)
{
   int port = 0x02;
   port |= ID;
   port <<= 1;
   port |= SH;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Disp_Curs_On_Off(int1 D, int1 C, int1 B)
{
   int port = 0x02;
   port |= D;
   port <<= 1;
   port |= C;
   port <<= 1;
   port |= B;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Disp_Curs_Shift(int1 S_CD, int1 RL)
{
   int port = 0x02;
   port |= S_CD;
   port <<= 1;
   port |= RL;
   port <<= 2;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Function_Set(int1 DL, int1 N, int1 F)
{
   int port = 0x02;
   port |= DL;
   port <<= 1;
   port |= N;
   port <<= 1;
   port |= F;
   port <<= 2;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void CGRAM_Adrs(int Adrs)
{
   int port = 0x40;
   port |= Adrs;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void DDRAM_Adrs(int Adrs)
{
   int port = 0x80;
   port |= Adrs;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Write_Data(int data)
{
   int1 BF;
   int  AC, *pAC;
   pAC = &AC;
   Read_BF_AC(pAC);
   if(*pAC == 0x14)
      DDRAM_Adrs(0x40);
   else
      if(*pAC == 0x54)
         DDRAM_Adrs(0x00);
   output_bit(RS, 1);
   output_bit(RW, 0);
   output_D(data);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

int Read_Data(int data)
{
   output_bit(RS, 1);
   output_bit(RW, 1);
   output_bit(E, 1);
   delay_us(50);
   data = input_D();
   Set_Zeros();
   return data;
}

int1 Read_BF_AC(int* AC)
{
   int1 BF;
   output_bit(RS, 0);
   output_bit(RW, 1);
   output_bit(E, 1);
   delay_us(50);
   BF = input(PIN_D7);
   *AC = input_D();
   *AC &= 0x7F;
   Set_Zeros();
   return BF;
}

void Init_LCD(void)
{
   delay_ms(30);
   Function_Set(1,1,0);
   Disp_Curs_On_Off(1,0,0);
   Clear_Display();
   Mode_Set(1, 0);
   delay_ms(10);
   Set_Zeros();
}

void Set_Zeros(void)
{
   output_bit(E, 0);
   output_bit(RW, 0);
   output_bit(RS, 0);
   output_D(0x00);
}

void write_str(char* data, int n)
{
   int i = 0;
   for(i = 0; i < n; i++)
      write_data((int)data[i]);
}

void write_number(signed int32 d)
{
   signed int i;
   int digit[10] = {0};
   int1 minus;
   if(d < 0) minus = 1;
   for(i = 0; d != 0; i++)
   {
      digit[i] = ((d%10)+48);
      d/=10;
   }
   if(minus)
   {
      digit[i] = 45;
      i++;
   }
   for(i--; i >= 0; i--)
      write_data(digit[i]);
}

Има допълнителни функциики за икзарване на стринг, както и на число. Предполагам, че само адресите са по - различни при JM204A  Иначе няма значение от контролера било то 16 или 18 серия. Копираш фрагмента в сорса ти и връзваш дисплея както е описано :)
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

Emaloumen

  • Робо-Новак
  • *****
  • Публикации: 11
    • Профил
PIC18F252 JM204A
« Отговор #2 -: Януари 09, 2008, 05:37:13 pm »
Аз ти казвам спасяваш ми живота.Много съм ти благодарен.
Искам да съм първи клас

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
PIC18F252 JM204A
« Отговор #3 -: Януари 10, 2008, 07:56:32 pm »
Радвам се мога да помогна :) Кажи дали ти е свършило работа :)
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

Sasho

  • Вече знае какво е робот!
  • *****
  • Публикации: 72
    • Профил
PIC18F252 JM204A
« Отговор #4 -: Февруари 16, 2008, 10:24:54 pm »
Мога ли да го направя с PIC16F84?
Александър Александров 14г.гр.Габрово
Skype:saschko95

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
PIC18F252 JM204A
« Отговор #5 -: Февруари 17, 2008, 01:11:23 am »
Да тъкмо на косъм ще стане :) D0 до D7 ги навръзваш за RB0 до RB7, a другите (RS, RW, E, BL) ги връзваш към PortA, отразяваш промените в програмата в началото и си готов :) Че дори и 1 пин ти хартисва :) Не знам всъщност дали ще се събере в паметта ма би трябвало :)
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания

TheDarkSoul

  • Заклет Роботостроител
  • *****
  • Публикации: 293
    • Профил
PIC18F252 JM204A
« Отговор #6 -: Февруари 17, 2008, 10:47:45 am »
Така ли трябва да стане?




#define BL PIN_A3
#define RS PIN_A2
#define RW PIN_A1
#define E  PIN_A0
/*---------------------======PIN DEFINITION======-------------------------------
PIN_A3 - BackLight(BL)
PIN_A2 - Register Select (RS)
PIN_A1 - Read/Write (RW)
PIN_A0 - Enable (E)
PIN_RB0 - Data Bit 0 (RB0)
PIN_RB1 - Data Bit 1 (RB1)
PIN_RB2 - Data Bit 2 (RB2)
PIN_RB3 - Data Bit 3 (RB3)
PIN_RB4 - Data Bit 4 (RB4)
PIN_RB5 - Data Bit 5 (RB5)
PIN_RB6 - Data Bit 6 (RB6)
PIN_RB7 - Data Bit 7 (RB7)
==============================================================================*/

void Clear_Display(void);
//Clears display and AC (address counter) = 0
void Home(void);
//Sets cursor at home
void Mode_Set(int1 ID, int1 SH);
//I/D  0 - decrease  SH 0 - display shift off at Read/Write
//     1 - increase     1 - display shift on at Read/Write
void Disp_Curs_On_Off(int1 D, int1 C, int1 B);
//D 0 - display off  C 0 - cursor off  B 0 - cursor blinking off
//D 1 - display on     1 - cursor on     1 - cursor blinking on
void Disp_Curs_Shift(int1 S_CD, int1 RL);
//S_CD 0 - cursor shift  RL 0 - left
//     1 - display shift    1 - right
void Function_Set(int1 DL, int1 N, int1 F);
//DL 0 - 4bits interface  N 0 - 1 row  F 0 - 5x8 font
//   1 - 8bits interface  N 1 - 2 rows   1 - 5x10 font
void CGRAM_Adrs(int Adrs);
//Send CGRAM Adrs, Adrs - 6bits
void DDRAM_Adrs(int Adrs);
//Send DDRAM Adrs, Adrs - 7bits
void Write_Data(int data);
//Send data(char), data - 8bits
int Read_Data(int data);
//Read data
int1 Read_BF_AC(int* AC);
//Read Busy Flag (BF) and Address Counter (AC)
void Init_LCD(void);
//initialize LCD
void Set_Zeros(void);
//Set zeros after instruction
void Write_str(char* data, int n);
//write string on the LCD
void Write_number(signed int32 d);
//write number on the LCD

void Clear_Display()
{
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(0x01);
   output_bit(E, 1);
   delay_ms(2);
   Set_Zeros();

}

void Home()
{
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(0x02);
   output_bit(E, 1);
   delay_ms(2);
   Set_Zeros();

}

void Mode_Set(int1 ID, int1 SH)
{
   int port = 0x02;
   port |= ID;
   port <<= 1;
   port |= SH;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Disp_Curs_On_Off(int1 D, int1 C, int1 B)
{
   int port = 0x02;
   port |= D;
   port <<= 1;
   port |= C;
   port <<= 1;
   port |= B;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Disp_Curs_Shift(int1 S_CD, int1 RL)
{
   int port = 0x02;
   port |= S_CD;
   port <<= 1;
   port |= RL;
   port <<= 2;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Function_Set(int1 DL, int1 N, int1 F)
{
   int port = 0x02;
   port |= DL;
   port <<= 1;
   port |= N;
   port <<= 1;
   port |= F;
   port <<= 2;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void CGRAM_Adrs(int Adrs)
{
   int port = 0x40;
   port |= Adrs;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void DDRAM_Adrs(int Adrs)
{
   int port = 0x80;
   port |= Adrs;
   output_bit(RS, 0);
   output_bit(RW, 0);
   output_D(port);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

void Write_Data(int data)
{
   int1 BF;
   int  AC, *pAC;
   pAC = &AC;
   Read_BF_AC(pAC);
   if(*pAC == 0x14)
      DDRAM_Adrs(0x40);
   else
      if(*pAC == 0x54)
         DDRAM_Adrs(0x00);
   output_bit(RS, 1);
   output_bit(RW, 0);
   output_D(data);
   output_bit(E, 1);
   delay_us(50);
   Set_Zeros();
}

int Read_Data(int data)
{
   output_bit(RS, 1);
   output_bit(RW, 1);
   output_bit(E, 1);
   delay_us(50);
   data = input_D();
   Set_Zeros();
   return data;
}

int1 Read_BF_AC(int* AC)
{
   int1 BF;
   output_bit(RS, 0);
   output_bit(RW, 1);
   output_bit(E, 1);
   delay_us(50);
   BF = input(PIN_D7);
   *AC = input_D();
   *AC &= 0x7F;
   Set_Zeros();
   return BF;
}

void Init_LCD(void)
{
   delay_ms(30);
   Function_Set(1,1,0);
   Disp_Curs_On_Off(1,0,0);
   Clear_Display();
   Mode_Set(1, 0);
   delay_ms(10);
   Set_Zeros();
}

void Set_Zeros(void)
{
   output_bit(E, 0);
   output_bit(RW, 0);
   output_bit(RS, 0);
   output_D(0x00);
}

void write_str(char* data, int n)
{
   int i = 0;
   for(i = 0; i < n; i++)
      write_data((int)data[i]);
}

void write_number(signed int32 d)
{
   signed int i;
   int digit[10] = {0};
   int1 minus;
   if(d < 0) minus = 1;
   for(i = 0; d != 0; i++)
   {
      digit[i] = ((d%10)+48);
      d/=10;
   }
   if(minus)
   {
      digit[i] = 45;
      i++;
   }
   for(i--; i >= 0; i--)
      write_data(digit[i]);
}


П.П.    Може ли някой да даде схемата за дисплея,за да знам дали мога да го направа. :roll:
А някакъв друг дисплей със който ще стане?
Иван Зарев-14г.-гр.Дупница Skype:thedarksoul4
Не подценявай този, който прави крачка назад, защото може и да се засилва...:!:

sv_shady

  • Administrator
  • *****
  • Публикации: 636
    • Профил
PIC18F252 JM204A
« Отговор #7 -: Февруари 17, 2008, 12:00:37 pm »
Освен промените които си написал и навсякъде в програмата трябва да смениш output_D с output_B Ами със всеки дисплей от протеуса, който е 2х20 ще стане ;) А схемата просто навръзваш пиновете на контролера за пиновете на дисплея както пише тука /*---------------------======PIN DEFINITION======-------------------------------
PIN_A3 - BackLight(BL)
PIN_A2 - Register Select (RS)
PIN_A1 - Read/Write (RW)
PIN_A0 - Enable (E)
PIN_RB0 - Data Bit 0 (RB0)
PIN_RB1 - Data Bit 1 (RB1)
PIN_RB2 - Data Bit 2 (RB2)
PIN_RB3 - Data Bit 3 (RB3)
PIN_RB4 - Data Bit 4 (RB4)
PIN_RB5 - Data Bit 5 (RB5)
PIN_RB6 - Data Bit 6 (RB6)
PIN_RB7 - Data Bit 7 (RB7)
==============================================================================*/
Imagination is the only limit.......

Светлин Пенков
София / Рединг, Великобритания