PIC16F1826 LCD problemi

Başlatan baran123, 24 Mayıs 2015, 22:13:54

baran123

.Amaç yaklaşık 1 saniyede DS18B20 den sıcaklık okumak ve okunan değeri ekrana basmak.Fakat lcd deki bütün karelerde 3 yazıyor ve simülasyonda bir sürü aynı uyarı çıkıyor.Yaklaşık 6000 tane :)

Hata : [HD44780]Controller received data whilst busy.

/*****************************************************************************

* File Name        : main.c

* Description      : Sıcaklık okuma

* Author           : Baran EKREM

*****************************************************************************/
#include "main.h"

static int1 ds_flag=0;
static unsigned int8 temp;
static unsigned int8 counter=0;

static void Init_MCU(void);

#Int_Timer0
void Interrupt_Timer0(void)
{
   set_timer0(60);
   if(counter == 20)
   {
      counter=0;
      ds_flag=1;
   }
   else
   {
      counter++;
      ds_flag=0;
   }
}

static void main(void)          
{        
   Init_MCU();
   Init_LCD();
    
   while(TRUE)
   {
      if(ds_flag)
      {
         ds_flag=0;
         temp = ds1820_read();
         set_pwm1_duty((unsigned int8)temp); 
         printf(lcd_putc, "\fTemp : %d%cC", temp, 223);
      }
      enable_interrupts(INT_timer0);
   }
}        
      
static void Init_MCU(void)
{
   set_tris_a(0x01);
   set_tris_b(0x00);   
      
   output_b(0x00); 
    
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   setup_timer_1(T1_DISABLED);   
   Setup_timer_2(T2_DISABLED, 0, 1); 
   setup_comparator(NC_NC_NC_NC);
   setup_ccp1(CCP_PWM);   
   setup_adc(ADC_OFF);
   setup_vref(FALSE);    
   
   set_timer0(60);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
}


main.h
/*****************************************************************************

* File Name        : main.h

* Description      : Header file for main.c

* Author           : Baran EKREM

*****************************************************************************/
#include <16F1826.h>
#device ADC=10
#fuses XT,NOMCLR,NOWDT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOPROTECT
#use DELAY(CLOCK = 4MHz, CRYSTAL=4MHz)

#include "lcd.c"
#include "ds18b20.c"

#define LED PIN_A1


lcd.c
/*****************************************************************************

* File Name        : main.h

* Description      : 2x16 LCD Driver

*****************************************************************************/
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7

#define LCD_E   PIN_B3
#define LCD_RS  PIN_B2
#define LCD_RW  PIN_B1

#define lcd_type 2   
#define lcd_line_two 0x40  

static int8 const LCD_INIT_STRING[4] = { 0x20 | (lcd_type << 2), 0xc, 1, 6 };

void lcd_send_nibble(int8 nibble)
{
   output_bit(LCD_DB4, !!(nibble & 1));
   output_bit(LCD_DB5, !!(nibble & 2));
   output_bit(LCD_DB6, !!(nibble & 4));
   output_bit(LCD_DB7, !!(nibble & 8));
   
   delay_cycles(1);
   output_high(LCD_E);
   delay_us(2);
   output_low(LCD_E);
}

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
   static int8 retval;
   #bit retval_0 = retval.0
   #bit retval_1 = retval.1
   #bit retval_2 = retval.2
   #bit retval_3 = retval.3
   
   retval = 0;
   
   output_high(LCD_E);
   delay_cycles(1);
   
   retval_0 = input(LCD_DB4);
   retval_1 = input(LCD_DB5);
   retval_2 = input(LCD_DB6);
   retval_3 = input(LCD_DB7);
   
   output_low(LCD_E);
   
   return(retval);
}
#endif

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
   static int8 low;
   static int8 high;
   
   output_high(LCD_RW);
   delay_cycles(1);
   
   high = lcd_read_nibble();
   
   low = lcd_read_nibble();
   
   return((high<<4) | low);
}
#endif

void lcd_send_byte(int8 address, int8 n)
{
   output_low(LCD_RS);
   
   #ifdef USE_LCD_RW
      while(bit_test(lcd_read_byte(),7)) ;
      #else
      delay_us(60);
   #endif
   
   if(address)
      output_high(LCD_RS);
   else
      output_low(LCD_RS);
   
   delay_cycles(1);
   
   #ifdef USE_LCD_RW
      output_low(LCD_RW);
      delay_cycles(1);
   #endif
   
   output_low(LCD_E);
   
   lcd_send_nibble(n >> 4);
   lcd_send_nibble(n & 0xf);
}

void Init_LCD(void)
{
   static int8 i;
   
   output_low(LCD_RS);
   
   #ifdef USE_LCD_RW
      output_low(LCD_RW);
   #endif
   
   output_low(LCD_E);
   
   delay_ms(15);
   
   for(i=0 ; i<3; i++)
   {
      lcd_send_nibble(0x03);
      delay_ms(5);
   }

   lcd_send_nibble(0x02);

   for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
      lcd_send_byte(0, LCD_INIT_STRING[i]);
      
      #ifndef USE_LCD_RW
         delay_ms(5);
      #endif
   }
}

void lcd_gotoxy(int8 x, int8 y)
{
   static int8 address;
   
   if(y != 1)
      address = lcd_line_two;
   else
      address=0;
   
   address += x-1;
   lcd_send_byte(0, 0x80 | address);
}

void lcd_putc(char c)
{
   switch(c)
   {
      case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;
      
      case '\n': lcd_gotoxy(1,2);      break;
      case '\b': lcd_send_byte(0,0x10);break;
      default: lcd_send_byte(1,c);     break;
   }
}

#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
   static char value;
   
   lcd_gotoxy(x,y);
   
   while(bit_test(lcd_read_byte(),7));
   
   output_high(LCD_RS);
   value = lcd_read_byte();
   output_low(lcd_RS);
   
   return(value);
}
#endif

RaMu

Proje zip daha kolay olur.
Set tris satırlarını kaldırıp denesene.
   set_tris_a(0x01);
   set_tris_b(0x00);   
     

zaten use fast io dememişsin ama.

DS18b20 nin bağlı olduğu pini tanımlamamış olabilirsin.
DQ pinine pull up bağlamamış olabilirsin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Denedim fakat yine aynı

Dosyalar : http://s5.dosya.tc/server2/mjbway/Fan_kontrol.rar.html

mesaj birleştirme:: 24 Mayıs 2015, 23:25:49

Pull up ve tanımlama yaptım hocam.

mehmet

İnterrupt kurmadan sıcaklık okuyabiliyor musun?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

RaMu

#4
LCD yi PORTA ya taşırsan düzelir.
Lcd nin bağlı olduğu pinler ccp ile alakalı,
ya datasheete bakıp olayı çözeceksin
yada basitçe porta ya lcdyi taşıyabilirsin.

mesaj birleştirme:: 25 Mayıs 2015, 00:18:16

Birde LCD.c de RW pinini tanımlamışsın
kullanıyorum anlamına gelir,
ve şemada bu pini bağlamamışsın.

Birde bu flex_lcd.c dosyası
kullandığın yaygın kütüphanelerin adını ve
içeriğini açıklamalarını değiştirmesen daha iyi olur.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

@mehmet "İnterrupt kurmadan sıcaklık okuyabiliyor musun?" - Okuyamıyorum hocam
@RaMu hocam direk taşıyabilirim ama datasheet'den baksam daha iyi olacak teşekkürler.

mehmet

Alıntı yapılan: Baran Ekrem - 25 Mayıs 2015, 00:40:55
@mehmet "İnterrupt kurmadan sıcaklık okuyabiliyor musun?" - Okuyamıyorum hocam
10sn. aralıkla öncelikle okumaya çalış, zira 18B20 normal çözünürlüğünde
~750ms. aralıkla cevap verir...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

baran123

#7
Hocam hafızası 2 katı olduğundan 1827 ye geçtim fakat A portutan taşımama rağmen yine aynı hata mevcut.LCD ye hiç bir şey basamıyorum.PLL yi kapattım proteusda 8 mhz kristal ile deniyorum.Programda da aynı şekilde ama neden aynı.

En son şöyle denedim.
#include <16F1827.h>
#fuses HS,NOWDT,NOPUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOCLKOUT,NOIESO,NOFCMEN,NOWRT,PLL_SW,NOSTVREN,NODEBUG,NOLVP
#use DELAY(CRYSTAL = 8MHz, CLOCK=8MHz)
#use FAST_IO(A)
#use FAST_IO(B)

#include "ds18b20.c"
#include "flex_lcd.c"


#include "main.h"

static int1 ds_flag=0;
static unsigned int8 temp;
static unsigned int8 counter=0;

static void Init_MCU(void);

#Int_Timer0
void Interrupt_Timer0(void)
{
   set_timer0(60);
   if(counter == 20)
   {
      counter=0;
      ds_flag=1;
   }
   else
   {
      counter++;
      ds_flag=0;
   }
}

void main(void)
{
   set_tris_a(0x00);
   set_tris_b(0x01);
   
   Init_MCU();
   
   while(TRUE)
   {
      if(ds_flag)
      {
         ds_flag=0;
         temp = ds1820_read();
         set_pwm1_duty((unsigned int8)temp); 
         printf(lcd_putc, "\fTemp : %d%cC", temp, 223);
      }
      enable_interrupts(INT_timer0);
   }
}

static void Init_MCU(void)
{
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   setup_timer_1(T1_DISABLED);   
   Setup_timer_2(T2_DISABLED, 0, 1); 
   setup_comparator(NC_NC_NC_NC);
   setup_ccp1(CCP_PWM);   
   setup_adc(ADC_OFF);
   setup_vref(FALSE);    
   
   set_timer0(60);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
}


#define LCD_DB4 PIN_A2
#define LCD_DB5 PIN_A3
#define LCD_DB6 PIN_A4
#define LCD_DB7 PIN_A5

#define LCD_E   PIN_A0
#define LCD_RS  PIN_A1
#define LCD_RW  PIN_B2// pin GND de

RaMu

#define LCD_RW  PIN_B2// pin GND de

ise
//#define LCD_RW  PIN_B2// pin GND de

defien satırını yorum haline getirmen lazım.

DS18B20 nin bulunduğu portu
fastio ile kullanmak problem çıkarabilir (tam hatırlamıyorum)
fastio ları şimdilik kaldırıp deneyebilirsin.

Ben deneyip isisde çalıştırmıştım birazdan bakar yine yazarım.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Getirdim hocam fakat ynı problem devam ediyor.
FAST IO b yi iptal ettim.

RaMu

#10
Hangi problem devam ediyor?
Ben şuan lcd nin çalışır hale getirdim ama
ds18b20 den sıcaklık okumada problem var, doğru değer gelmiyor.


mesaj birleştirme:: 27 Mayıs 2015, 20:09:54

http://s4.dosya.tc/server3/uloesg/1.rar.html
Bu lcd çalışan hali.  sıcaklık okumada sıkıntı var.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Hocam sürekli uyarı çıkarıyor proteus ve uyarılar artmaya devam ediyor.Ekranda boş

Uyarı: [HD44780]Controller received data whilst busy.


RaMu

Benim gönderdiğim örneği denedin mi?
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Denedim hocam çalışıyor.1827 ye göre düzenledim sanırım siz lcd pinlerini değiştirdiniz.

RaMu

#14
LcdE pinini ccp den kurtardım sadece.
Başka çözümü vardır belki ama datasheeti kurcalamak lazım.

mesaj birleştirme:: 27 Mayıs 2015, 21:49:55

10 nolu mesajda gönderdiğim program iyi çalışıyor.
Sadece sıcaklığı göstermede problem kalmıştı,
onun çözümü;
DS18B20 nin DQ pinine bağlı olan 4.7k lık pull up direncinin
üzerine çift tıklayıp MODEL TYPE kısmından DIGITAL seçilecek.
Böylece doğru sıcaklık değerinide lcd de gösteriyor.

Birde sıcaklık değişkenini  özellikle unsigned int8 tanımlamışsın sanırım,
virgülden sonrası lazım değilse,
programın daha az yer kaplaması için
ds1820 kütüphanesinde ufak bir düzenleme yapılabilir diye düşünüyorum.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html