Pıc16f628a ı2c lcd ve uart habeeleşmesi

Katılım
19 Ağu 2021
Mesajlar
21
Puanları
1
Yaş
30
İyi günl herkese,

2 tane pic'i haberleştirmek istiyorum. Master olana Lcd bağlı olacak ve menü içeriği olacak. Diğeri iste masterdan gelen veri ile stepper motoru kontrol edecek. Yeni öğreniyorum programlamayı. Lcd için i2c protokolünden iletişim sağlıyorum. İnternette bulduğum bir kütüphane ile. Picleri ise uart ile haberleştiricem. Ancak i2c lcd kütüphanesinin lcdyi başlatan "lcd.begin(0x4E);" kodu huart haberleşmesini engelliyor. Bu kodu sildiğimde haberleşme oluyor.

Master pic haberleşme protokol başlangıçları;
CSS:
#include <16F628a.h>
#USE delay(clock=4000000)
#fuses INTRC,NOMCLR,NOWDT,NOBROWNOUT,NOPROTECT,NOCPD
#use i2c(master,sda=pin_b1,scl=pin_b2,FAST=100000,STREAM=I2C_LCD) //i2c ayarı. STREAM kısmı önemli
#use rs232(baud=9600,xmit=pin_b4,stop=1,bits=8)  //pic to pic haberleşme
#use fast_io(a)
#use fast_io(b)
#include <I2C_LCD.c>

Master pic'in main kısmı ve bahsettiğim lcd.begin;(yazı büyümesin diye koların önemsiz yerleirni eksik atıyorum)
CSS:
void main() { // ANA FONKSİYON
 lcd_begin(0x4E);
 set_tris_a(0xC0);
 set_tris_b(0x01);
 
 output_a(0x00);
 
 enable_interrupts(INT_EXT);
 enable_interrupts(GLOBAL);
 setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
 setup_timer_0(T0_INTERNAL | T0_DIV_256);
 ext_int_edge(H_TO_L);
 
 
 while(TRUE){

Bu da i2c lcd kütüphanesi;
CSS:
// CCS C driver code for I2C LCDs (HD44780 compliant controllers)
// https://simple-circuit.com/
 
 
 
#define LCD_BACKLIGHT          0x08
#define LCD_NOBACKLIGHT        0x00
#define LCD_FIRST_ROW          0x80
#define LCD_SECOND_ROW         0xC0
#define LCD_THIRD_ROW          0x94
#define LCD_FOURTH_ROW         0xD4
#define LCD_CLEAR              0x01
#define LCD_RETURN_HOME        0x02
#define LCD_ENTRY_MODE_SET     0x04
#define LCD_CURSOR_OFF         0x0C
#define LCD_UNDERLINE_ON       0x0E
#define LCD_BLINK_CURSOR_ON    0x0F
#define LCD_MOVE_CURSOR_LEFT   0x10
#define LCD_MOVE_CURSOR_RIGHT  0x14
#define LCD_TURN_ON            0x0C
#define LCD_TURN_OFF           0x08
#define LCD_SHIFT_LEFT         0x18
#define LCD_SHIFT_RIGHT        0x1E
 
#ifndef LCD_TYPE
   #define LCD_TYPE 2           // 0=5x7, 1=5x10, 2=2 lines
#endif
 
 
int1 RS;
unsigned int8 i2c_addr, backlight_val = LCD_BACKLIGHT;
 
void LCD_Write_Nibble(unsigned int8 n);
void LCD_Cmd(unsigned int8 Command);
void LCD_Goto(unsigned int8 col, unsigned int8 row);
void LCD_Out(unsigned int8 LCD_Char);
void LCD_Begin(unsigned int8 _i2c_addr);
void Backlight();
void noBacklight();
void Expander_Write(unsigned int8 value);
 
void LCD_Write_Nibble(unsigned int8 n) {
  n |= RS;
  Expander_Write(n);
  Expander_Write(n | 0x04);
  delay_us(1);
  Expander_Write(n & 0xFB);
  delay_us(50);
}
 
void LCD_Cmd(unsigned int8 Command) {
  RS = 0;
  LCD_Write_Nibble(Command & 0xF0);
  LCD_Write_Nibble((Command << 4) & 0xF0);
}
 
void LCD_Goto(unsigned int8 col, unsigned int8 row) {
  switch(row) {
    case 2:
      LCD_Cmd(0xC0 + col-1);
      break;
    case 3:
      LCD_Cmd(0x94 + col-1);
      break;
    case 4:
      LCD_Cmd(0xD4 + col-1);
    break;
    default:      // case 1:
      LCD_Cmd(0x80 + col-1);
  }
}
 
void LCD_Out(unsigned int8 LCD_Char){
  RS = 1;
  LCD_Write_Nibble(LCD_Char & 0xF0);
  LCD_Write_Nibble((LCD_Char << 4) & 0xF0);
}
 
void LCD_Begin(unsigned int8 _i2c_addr) {
  i2c_addr = _i2c_addr;
  Expander_Write(0);
  delay_ms(40);
  LCD_Cmd(3);
  delay_ms(5);
  LCD_Cmd(3);
  delay_ms(5);
  LCD_Cmd(3);
  delay_ms(5);
  LCD_Cmd(LCD_RETURN_HOME);
  delay_ms(5);
  LCD_Cmd(0x20 | (LCD_TYPE << 2));
  delay_ms(50);
  LCD_Cmd(LCD_TURN_ON);
  delay_ms(50);
  LCD_Cmd(LCD_CLEAR);
  delay_ms(50);
  LCD_Cmd(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
  delay_ms(50);
}
 
void Backlight() {
  backlight_val = LCD_BACKLIGHT;
  Expander_Write(0);
}
 
void noBacklight() {
  backlight_val = LCD_NOBACKLIGHT;
  Expander_Write(0);
}
 
void Expander_Write(unsigned int8 value) {
  I2C_Start(I2C_LCD);
  I2C_Write(I2C_LCD, i2c_addr);
  I2C_Write(I2C_LCD, value | backlight_val);
  I2C_Stop(I2C_LCD);
}

Yardımlarınızı ve görüşlerinizi bekliyorum. Şimdiden teşekkürler.
 
C:
lcd_begin(0x4E);
 set_tris_a(0xC0);
 set_tris_b(0x01);

Sanki lcd_begin değilde set_tris fonksiyonları uart haberleşmesine engel gibi duruyor. Portların yönünü hem i2c hem uart giriş çıkışı için ayarladın mı? Bildiğim kadarıyla da i2c ve uart pinlerini set_tris fonksiyonuyla ayarlamasan da pic onları otomatik giriş çıkış olarak ayarlar. Yani bu iki satırı silip dene önce sonrasına bakarız.
 
Sildim sonuç aynı. Hatta tris b yi silince dış kesme çalışmıyor.

Hatt aşağıdaki şekilde deneme amaölı bir kod ile sistemi denedim. Lcd_begin ile bu basit kod bile çalışmıyor. Silincw herşey güllük gülistanlık oluyor.
CSS:
#include <16F628a.h>
#USE delay(clock=4000000)
#fuses INTRC,NOMCLR,NOWDT,NOBROWNOUT,NOPROTECT,NOCPD
#use i2c(master,sda=pin_b1,scl=pin_b2,FAST=100000,STREAM=I2C_LCD) //i2c ayarı. STREAM kısmı önemli
#use rs232 (baud=9600,xmit=pin_b4,rcv=pin_b5,parity=N,stop=1,bits=8)
#use fast_io(a)
#include <I2C_LCD.c>
int hiz=1; // Stepper motor hızı
#int_EXT
void EXT_isr(void) { //Dış kesme ile buton dinleme
 if(hiz==1) hiz=3;
 hiz--;
 write_eeprom(1,hiz);
 printf("%u",hiz);
 putc(hiz);
 
 }
 
void main() { // ANA FONKSİYON
 lcd_begin(0x4E);
 set_tris_a(0xC0);
 
 output_a(0x00);
 
 enable_interrupts(INT_EXT);
 enable_interrupts(GLOBAL);
 ext_int_edge(H_TO_L);
 
 while(TRUE){
 if(input(pin_a6)) {
 if(hiz==2) hiz=0;
 hiz++;
 write_eeprom(1,hiz);
 printf("%u",hiz);
 putc(hiz);
 delay_ms(250);
 }
 
 if(input(pin_a7)) {
 if(hiz==1) hiz=3;
 hiz--;
 write_eeprom(1,hiz);
 printf("%u",hiz);
 putc(hiz);
 delay_ms(250);
 
 }
 }
 }
 
Kod:
 #use rs232(baud=9600,xmit=pin_b4,stop=1,bits=8)
Gördüğüm kadarıyla 16f628 denetleyicisinde I2C ve UART haberleşmesi aynı pinler üzerinden sağlanıyor. Eğer rcv pini tanımlamazsanız rcv pini otomatik olarak b1 pini olarak algılıyor olabilir. Bu nedenle rcv pin tanımlamalısınız. Örneğin rcv pin b5 pini yaparsak aşağıdaki kodu kullanıp tekrar deneyin.

Yukarıdaki seri haberleşme kodunu şununla değiştirip deneyin:
Kod:
 #use rs232(baud=9600,xmit=pin_b4,rcv=pin_b5, stop=1,bits=8, stream=PORT1)

veri gönderirken

Kod:
printf(PORT1, "%u", hiz);
 
Son düzenleme:
İkinci mesajımda gönderdiğim deneme kodunda pinler tanımlı ancak malesef yine çalışmıyor.

Ayrıca pic16f628a kullanıyorum. Hardware olarak sadece uart destekli. I2c desteği software olarak sağlıyorum
 
Son düzenleme:
Sorunu çözdüm. Pic'in a4 bacağı open collector olduğu için veri alımı yapamıyormuşum. Değiştirdim sorun çözüldü.

Ancak başka bir sorum olacak herkese, iki farklı veri göndermek istiyorum nasıl yaparım? Şöyle ki, aynı anda masterdan slave a=1 ve c=3 gib iki veriyi yollamam lazım ki diğer picte seri kodlar çalışsın. Slave if(a=1){ if(c=3){ gibi bir kod serisini başlatıcak ya da durdurucak.
 
Son düzenleme:
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için onları kabul etmelisiniz. Daha fazla bilgi edin…