CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

interference between rs232 communication and keypad
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
baris_akinci



Joined: 10 Mar 2016
Posts: 17
Location: Ankara

View user's profile Send private message

interference between rs232 communication and keypad
PostPosted: Sat Nov 26, 2016 5:33 am     Reply with quote

Hello dear forum members,

I am trying to make office entry recording system by using keypad and communicating via rs232 with host pc. I have partially completed the main part, and it is working well on proteus. Here are code block and picture.
I have made this on a board too and test in real world.

My question is this: Board and keypad are working well without rs232 connection but when I connect the board to pc by rs 232 connection, the keypad does not wait to push the buttons. It always push the numbers itself and does not accept any push done by me! rs232 is communicating with pc well by the way!!

Thanks in advance.
Code:

#ifndef     rtc_sclk
#define     rtc_sclk   pin_c1
#define     rtc_io     pin_c2       
#define     rtc_rst    pin_c0
#endif

#include <16F877A.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer   
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES RESERVED //Used to set the reserved FUSE bits

#use delay(clock=4000000, crystal) 
#use fast_io(a)
#use fast_io(b)
#use fast_io(d)

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7,parity=N,stop=1,ERRORS) // RS232 protokolünün 9600 bit/sn baud hızında olacağını ve
                                                                  // TX,RX uçlarının hangi pinler olacağını tanımlıyor
                                                                  // parity bitinin olmadığını, stop bitinin 1 bit olacağı belirtiliyor
#define sat1 pin_b0
#define sat2 pin_b1
#define sat3 pin_b2
#define sat4 pin_b3 
#define sut1 pin_b4
#define sut2 pin_b5
#define sut3 pin_b6 

                     // keyboard girişi olduğu bildirimi
#define LCD_DATA_PORT getenv("SFR:PORTD")   // LCD data çıkış portunun D portu üzerinden olacağı tanımlanıyor

#include <lcd.c>
#include <karakterim.c>

#include <DS1302.c>
int saat_kontrol=0;
char keypad_oku();
 volatile int a,b,c,d,e,f,g;
 char aa[3],bb[3],cc[3],dd[3],ee[3],ff[3],gg[2];

unsigned char oku;
char zaman[16];
char tampon[15];
int indis2;
int indis3;
int rx_kontrol=0;

#int_rda
void rda_isr(void)
{
  disable_interrupts(INT_RDA);
  oku = getch();
  saat_kontrol=1;
 
  if(oku=='X')
  {
  for(indis3=0;indis3<=15;indis3++)
     {   
     zaman[indis3]=getch();
     aa[0]=zaman[0];                        //       
     aa[1]=zaman[1];                           // gelen
     aa[2]='\0';
     bb[0]=zaman[2];                            //saat
     bb[1]=zaman[3];                            //verisini
     bb[2]='\0';
     cc[0]=zaman[6];                            //parçalara
     cc[1]=zaman[7];                            //ayırma
     cc[2]='\0';
     dd[0]=zaman[8];                            //işlemi
     dd[1]=zaman[9];                            //yaptırılıp
     dd[2]='\0';
     ee[0]=zaman[10];                           //rtc
     ee[1]=zaman[11];                           //ünitesenin
     ee[2]='\0';
     ff[0]=zaman[12];                           //parametrelerine
     ff[1]=zaman[13];                           //gönderiliyor
     ff[2]='\0';                                 //
     gg[0]=zaman[14];                           // rtc modülündeki gün sabit değişkenini sistemden istiyor ve  buraya saklıyor
     gg[1]='\0';
     }
   
    a=atoi(aa);b=atoi(bb);c=atoi(cc);d=atoi(dd);e=atoi(ee);f=atoi(ff);g=atoi(gg); // seri porttan alınan bilgiler sayı olsa bile string olduğu için atoi ile bunlar integer hale getiriliyor
    rtc_set_datetime(a,b,c,(g+1),d,e);   // gun  ,  ay   ,  yıl  ,  hangigün   ,   saat   ,   dakika
  }
  else if(oku=='$')
  {
     for(indis2=0;indis2<=14;indis2++)    //seri porttan gönderilen isim/soyisimi tampon adında bir dizine alıyoruz
        {
          tampon[indis2]=getch();
        }     
  rx_kontrol=1;
  } 
  enable_interrupts(INT_RDA);
}

void gecikme(int gec);
void tus_bekle(void);
void ses_cal(float sure);
char keypad_oku();
void pic_init();
void ana_sayfa();
void sifre_kontrol(char sifre[], int);
#define boyut 4
char tus;
int indis=0;
int sayac=0;
int sifre_aktif=0;

byte saniye,dakika,saat,gun,ay,yil,haftanin_gunu; // byte türünde değişkenler tanımlanıyor

void main()
{
    pic_init();    // pic kütüphanesi çağırılıyor
    fputs("zaman");
    ozel_karakterler();
  /*  while (saat_kontrol==0) {   // ana giriş sayfasında rs232 hattından saat verisi gelene kadar bekliyor. gelmezse burada takılıp kalıyor.
                        lcd_gotoxy(1,1);printf(lcd_putc,"lütfen ");
                        lcd_gotoxy(1,2);printf(lcd_putc,"bekleyiniz...");
                     } */                 
while(1)
   { 
     if(sifre_aktif==0) {
                            output_low(pin_a0);
                            output_low(pin_a1);
      ana_sayfa();   // eğer *'a basılmasdıysa ana ekranda kal
                         }
      else if (sifre_aktif==1)  {    // *'a basıldı ise şifre alma sayfasına yönlendir
                               
                                 char sifre[4];
                                 char gecici[5];
                                 basla:
                                 
                                 output_high(pin_a0);
                                 output_low(pin_a1);

                                 printf(lcd_putc,"\f");     // ekranı temizle
                                  do { // şifre ilk döngüsüne gir
                                   
                                    keypad_oku();
                                    if(tus=='#') {indis=indis; sayac=sayac;}   // eğer şifre alma programına girilir arkasından sayı yerine # basılırsa bunu algılamaması sağlanır
                                    else {gecici[indis]=tus;}
                                    if(indis==1) {sifre[sayac]=gecici[indis];sayac=1;}
                                    if(indis==2) {sifre[sayac]=gecici[indis];sayac=2;}
                                    if(indis==3) {sifre[sayac]=gecici[indis];sayac=3;}
                                    if(indis==4) {sifre[sayac]=gecici[indis];sayac=4;}
                                    if(indis==5) {sifre[sayac]=gecici[indis];sayac=5;}
                                   
                                    rtc_get_time(saat,dakika,saniye);

                                    lcd_gotoxy(1,1);
                                    if(saat<=13) {  printf(lcd_putc,"   --Günaydın-- ");}        // ekranın üst tarafında hangi dilimde giriş geldiğini gösterir
                                        else     {  printf(lcd_putc,"--İyi Akşamlar--");}
                                   
                                    lcd_gotoxy(1,2);
                                    printf(lcd_putc,"sifre="); 
                                    lcd_gotoxy(sayac+6,2);
                        if(indis==0) {                 // görsel olarak 4 haneli "****" şifre girileceğini gösterme amaçlı
                                      lcd_gotoxy(7,2);
                                      printf(lcd_putc,"****");
                                     }
                        if(indis>0)  {                 // butondan gelen veriyi şifre indisine aktarma fonksiyonu
                                      printf(lcd_putc,"%c",sifre[sayac]);
                                      }         
                        if(sayac>=5) {                 // eğer giriş 4 haneden fazla yapılmış ise fazla giriş uyarısı yapıp tekrar şifre istemeye döndüren parça
                                       lcd_gotoxy(1,2);
                                       printf(lcd_putc,"fazla giriş");
                                       gecikme(400);
                                       indis=0;
                                       sayac=0;
                                       goto basla;
                                                   }
                        if(sayac==4){  if(tus=='#') {            // 4 hane giriliğ "#" tuşunada basılmışsa bunu kontrol fonksiyonuna aktarma parçası
                                                      sifre_kontrol(sifre,boyut);
                                                     }
                         
                                     }                             
                                    } while(sifre_aktif==1);     // şifre girme alanında olup olunmadığı kontrol ediliyor
                                }
   enable_interrupts(INT_RDA);
   }
}

void pic_init()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   lcd_init();
   rtc_init();
   output_b(0xF0);
   set_tris_b(0b01110000);
   set_tris_a(0x00);
   
}

char keypad_oku()
{
      output_b(0x00);
      output_high(sat1); output_low(sat2);output_low(sat3);output_low(sat4);// 1. satır lojik-1 yapılıyor     
      if (input(sut1))      {   while(input(sut1)); tus='1';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='2';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='3';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat1); // 1. satır lojik-0 yapılıyor
      output_high(sat2);output_low(sat1);output_low(sat3);output_low(sat4); // 2. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1)); tus='4';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='5';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='6';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat2); // 2. satır lojik-0 yapılıyor 
      output_high(sat3);output_low(sat1);output_low(sat2);output_low(sat4); // 3. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1)); tus='7';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='8';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='9';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat3); // 3. satır lojik-0 yapılıyor
      output_high(sat4);output_low(sat1);output_low(sat2);output_low(sat3); // 4. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1));  if(sifre_aktif==1) {indis=0; sayac=0; sifre_aktif=0;ses_cal(0.01);} else if(sifre_aktif==0) {indis=0; sayac=0;sifre_aktif=1;ses_cal(0.01);}}  // * ile şifre kontrol işlemine girilip çıkılıyor, indis'i 0'lamak durumundasındasın çünkü giriş çıkışta hafızada durmasın tekrardan başlasın diye
      else if (input(sut2)) {   while(input(sut2)); tus='0';ses_cal(0.01); if(sifre_aktif==1) {indis++;} else indis=0; }  // 2. sütun okunuyor while komutu ile tuşun bırakılmasını bekliyor.
      else if (input(sut3)) {   while(input(sut3)); tus='#';ses_cal(0.01);  }  // 3. sütun okunuyor
     
      output_low(sat4); // 3. satır lojik-0 yapılıyor
      return tus;
}

void ana_sayfa()
{
      rtc_get_time(saat,dakika,saniye);       // DS1302'den saat,dakika,saniye bilgileri alınıyor
      rtc_get_date(gun,ay,yil,haftanin_gunu); // DS1302'den gün,ay,yil ve günün isim bilgisi alınıyor
      printf(lcd_putc,"\fT:%02d/%02d/20%02d ",gun,ay,yil); //LCD'ye gün,ay,yıl bilgileri yazdırılıyor

      switch(haftanin_gunu)  // DS1302'den sayısal olarak alınan haftanın günü bilgisine
      {                      // metin olarak karşılık atanıyor
         case 1: printf(lcd_putc,"PAZ"); break; // Eğer "1" ise LCD'ye PAZ yaz
         case 2: printf(lcd_putc,"PZT"); break; // Eğer "2" ise LCD'ye PZT yaz
         case 3: printf(lcd_putc,"SAL"); break; // Eğer "3" ise LCD'ye SAL yaz
         case 4: printf(lcd_putc,"CRS"); break; // Eğer "4" ise LCD'ye CRS yaz
         case 5: printf(lcd_putc,"PER"); break; // Eğer "5" ise LCD'ye PER yaz
         case 6: printf(lcd_putc,"[spam]"); break; // Eğer "6" ise LCD'ye [spam] yaz
         case 7: printf(lcd_putc,"CTS"); break; // Eğer "7" ise LCD'ye CTS yaz
      }
      printf(lcd_putc,"\nSaat:%02d:%02d:%02d",saat,dakika,saniye); // LCD'ye saat,dakika ve saniye değerlerini yaz
      gecikme(100); // 1 sn gecikme veriliyor
           
      keypad_oku();
   }
   
void gecikme(int gec)   // delay_ms gecikmesi verilirse eğer bu sistemi durdurma komutu olduğundan keypad'den gelen veride kayıba yol açtığı için kendi gecikme döngüsü yazıldı
{  static long int a=0;
   gec=gec*100;
   for(a=0;a<gec;a++) {
                     static long int b=0;
                     for(b=0;b<1000;b++) {}
                     }
}

void tus_bekle(void)
{
    unsigned int i=2500;
    while(i--);
}

void sifre_kontrol(char sifre[], int  )
{
                      output_low(pin_a0);
                      output_high(pin_a1);
                     
         char gecici;
         char gonder[4];
               
                  rtc_get_time(saat,dakika,saniye);
                  if (saat <= 13) {gecici='0';}    // şifre girildiği anda karşı tarafa sabahmı yoksa akşam mı bilgisini veren kısım  0 sabah 1 akşam
                  else            {gecici='1';}
         gonder[0]=gecici;
         gonder[1]=sifre[2];
         gonder[2]=sifre[3];
         gonder[3]='\0';       // eğer bununla kelime sonu bilgisi göndermez isek program ramdom olarak gonder stringinin sonuna karakter ekleyecektir
         
                             
                  fputs(gonder);
                enable_interrupts(GLOBAL);
                  printf(lcd_putc,"\f");
                  devam:
                  if(rx_kontrol==1) {
                  printf(lcd_putc,"%s",tampon);
                  lcd_gotoxy(1,2);
                  printf(lcd_putc," ---%02d:%02d:%02d---",saat,dakika,saniye); 
                  gecikme(10000);}
                  else goto devam;
                  rx_kontrol=0;

  sifre_aktif=0;
  indis=0;
  sayac=0;
}

void ses_cal(float sure)
{
  output_high(pin_a3);
  gecikme(sure);
  output_low(pin_a3);
}


[url=http://hizliresim.com/9gRo63 [/url]
temtronic



Joined: 01 Jul 2010
Posts: 9228
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 6:13 am     Reply with quote

Classic ISR 'problem'.

ALL Interrupt Service Routines(ISR) MUST be short and fast !!

They must NOT contain any 'math' or 'string' functions or calculations !
They must NOT contain any delays ( delay_ms(xx), etc.)
They must NOT contain any 'complex' comarisons or 'IF's.
They must NOT contain any printf() functions.
They do NOT need to disable/reenable INTs( done automatically)

They do need to set a 'flag' to say 'something happened' and exit, fast.
They can set a few variables,but nothing 'complex'.

It's up to 'main()' to see the flag is set, and do whatever needs to be done.....

I'm sure others can add a couple of items I've forgotten.


Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 9:03 am     Reply with quote

Also, another classic.

INT_RDA, means that _one_ (just one) character is waiting to be read. Using more than one getc/getch in this (or a gets), will effectively hang the processor from doing anything else at all. Destroys the whole 'point' of using the interrupt. Look at ex_sisr.c for an example of how to handle RS232 interrupts.
baris_akinci



Joined: 10 Mar 2016
Posts: 17
Location: Ankara

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 12:40 pm     Reply with quote

temtronic wrote:
Classic ISR 'problem'.

ALL Interrupt Service Routines(ISR) MUST be short and fast !!

They must NOT contain any 'math' or 'string' functions or calculations !
They must NOT contain any delays ( delay_ms(xx), etc.)
They must NOT contain any 'complex' comparisons or 'IF's.
They must NOT contain any printf() functions.
They do NOT need to disable/re-enable INTs (done automatically)

They do need to set a 'flag' to say 'something happened' and exit, fast.
They can set a few variables, but nothing 'complex'.

It's up to 'main()' to see the flag is set, and do whatever needs to be done.....

I'm sure others can add a couple of items I've forgotten.


Jay


I think there is another problem because I have tested your thinkings. ı delete almost everything inside "RDA ISR" and remained just RDA function. but the result is same. my problem is actually not only while communicating but also always when board is connected to pc by rs232 cable. I mean that as soon as I plug the rs232 cable to pc, the board is starting to get numbers itself and continue like this.

regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 1:05 pm     Reply with quote

One thing that leaps out on the circuit, is you show the RS232 connector (DB9), going to the PIC directly, instead of to the MAX232 where it needs to go. Duh.
Then with the RS232 interrupt enabled, the ISR _must_ read the character or the port will become hung.
Unfortunately I have a nasty suspicion you are testing in Proteus. If so, it may be misleading you (it probably thinks the watchdog is enabled - it does not know you have it disabled in the code - if so it'd be watchdogging, and generating key sequences because of this...). If so a typical example of why we say _do not trust Proteus_....

Then some general comments.

The fuses and clock settings should be before any libraries are loaded or they may well not behave as they should.
Sequence should always be:

#include chip file
#fuses
clock settings
RS232, I2C etc #use lines

#include libraries

Then your own libraries/code

The code is honestly a mess. Look at the standard keypad driver in the code library, which shows how to scan a keyboard (and handle debounce) in a much more competent way.
baris_akinci



Joined: 10 Mar 2016
Posts: 17
Location: Ankara

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 2:45 pm     Reply with quote

Ttelmah wrote:
One thing that leaps out on the circuit, is you show the RS232 connector (DB9), going to the PIC directly, instead of to the MAX232 where it needs to go. Duh.
Then with the RS232 interrupt enabled, the ISR _must_ read the character or the port will become hung.
Unfortunately I have a nasty suspicion you are testing in Proteus. If so, it may be misleading you (it probably thinks the watchdog is enabled - it does not know you have it disabled in the code - if so it'd be watchdogging, and generating key sequences because of this...). If so a typical example of why we say _do not trust Proteus_....

Then some general comments.

The fuses and clock settings should be before any libraries are loaded or they may well not behave as they should.
Sequence should always be:

#include chip file
#fuses
clock settings
RS232, I2C etc #use lines

#include libraries

Then your own libraries/code

The code is honestly a mess. Look at the standard keypad driver in the code library, which shows how to scan a keyboard (and handle debounce) in a much more competent way.


In order to explain what I face, I have added a video as below:
https://www.youtube.com/watch?v=5VSU6h8nCks
That is so interesting for me and I need your help.

regards,
temtronic



Joined: 01 Jul 2010
Posts: 9228
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Nov 26, 2016 3:11 pm     Reply with quote

You should now post your current program! Several changes needed to be made and we need to see what you now have.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Sun Nov 27, 2016 3:05 am     Reply with quote

Seriously, videoing the problem doesn't change the basic fact.
Your code is too badly written for anyone to waste the time trying to debug it.
Then though the video is almost un-watchable, I can't see any sign of good decoupling close to the processor. Look at this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=55700>
You may well have a lesser version of exactly the same type of problem (I'd suspect that possibly the charge pump on the RS232 driver may be causing oscillations on the power rail when it comes under load - you have to realise that this is a medium frequency oscillator drawing all it's power from the 5v rail - if you look at the circuit diagram on the data sheet, note how the manufacturer has _five_ capacitors round the chip, not the four you show - the fifth one is to provide the momentary spikes in power needed to drive the oscillator without introducing too many spikes on the power rail).....
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Sun Nov 27, 2016 4:11 am     Reply with quote

Baris

You got many advises from professional people.
Instead to follow, you are posting a video that personally I don't understand nothing from it.
Proposing you to start from scratch according to the advises you got.

Best wishes
Joe
drolleman



Joined: 03 Feb 2011
Posts: 116

View user's profile Send private message

PostPosted: Sun Nov 27, 2016 8:22 pm     Reply with quote

Biggest mistake Proteus. If it works in Proteus, it's unlikely will work on real hardware! Read the top of the forum.
baris_akinci



Joined: 10 Mar 2016
Posts: 17
Location: Ankara

View user's profile Send private message

rs232 communication and keypad interference
PostPosted: Mon Nov 28, 2016 11:12 am     Reply with quote

thank you so much for your advices, but still I couldn't solve the problem!

I have tried what you advices me and here is the summarize what ı have done;
- I re-organised the whole code and made explanations --> result is same
- I delete every code inside ISR function and just remained INT_RDA{} but --> result is same
- I deactivated ISR and rs232 part of code but --> result is same
- I take out the capacitors of max232 which provides charge pump to max232 (2 and 6) but --> result is same

ahh, I still coundn't understand what is effect the keypad right after rs232 cable is connected to PC even without opening teraterm somehing.

the code is here;

Code:

//////////////////////////////////*
    this is the software that gets password from keypad when the user comes to office in the morning and leaves in the evening and send it to host pc to record.
    -- user code has 4 digit, and this digits can be anything but not more than 4 and not less than 4.
    -- when the user comes and press '*' on keypad, the system moves into the screen which code is taking. otherwise the screen always shows the current time.
    -- when code is entered, system get last two digit of password entered and send to host pc and wait until the name who match that code part.
    -- after getting the name from host pc, system show that name and the current time on lcd screen then back to main screen
    -- when the system is turned on, it automatically send "zaman" to update board's time (RTC module) by receiving time data from host pc.
*////////////////////////////////////////

#include <16F877A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer   
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES RESERVED //Used to set the reserved FUSE bits

#use delay(clock=4000000, crystal) 

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7,parity=N,stop=1,ERRORS) // RS232 protokolünün 9600 bit/sn baud hızında olacağını ve
                                                                  // TX,RX uçlarının hangi pinler olacağını tanımlıyor
                                                                  // parity bitinin olmadığını, stop bitinin 1 bit olacağı belirtiliyor   
#use fast_io(a)
#use fast_io(b)
#use fast_io(d)
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define sat1 pin_b0
#define sat2 pin_b1
#define sat3 pin_b2
#define sat4 pin_b3 
#define sut1 pin_b4
#define sut2 pin_b5
#define sut3 pin_b6 

#define LCD_DATA_PORT getenv("SFR:PORTD")   // LCD data çıkış portunun D portu üzerinden olacağı tanımlanıyor

#include <lcd.c>
#include <karakterim.c>    // turkish character library
#include "C:\Users\MA\Desktop\projeler\ofise giriş saati kaydı\DS1302.c"    // ds1302 library

char keypad_oku();
volatile int a,b,c,d,e,f,g;
char aa[3],bb[3],cc[3],dd[3],ee[3],ff[3],gg[2];
unsigned char oku;
char zaman[16];
char tampon[15];
int indis2;
int indis3;
int rx_kontrol=0;
void gecikme(int gec);
void tus_bekle(void);
void ses_cal(float sure);
char keypad_oku();
void pic_init();
void ana_sayfa();
void sifre_kontrol(char sifre[], int);
#define boyut 4
char tus;
int indis=0;
int sayac=0;
int sifre_aktif=0;
byte saniye,dakika,saat,gun,ay,yil,haftanin_gunu; // byte türünde değişkenler tanımlanıyor

#int_rda
void rda_isr(void)                                   
{
  oku = getch();
 
  if(oku=='X')
  {
  for(indis3=0;indis3<=15;indis3++)      // here is getting the time information from host pc and breaking them into pieces to be used for RTC parameters by converting integer
     {   
     zaman[indis3]=getch();
     aa[0]=zaman[0];                        //       
     aa[1]=zaman[1];                           // gelen
     aa[2]='\0';
     bb[0]=zaman[2];                            //saat
     bb[1]=zaman[3];                            //verisini
     bb[2]='\0';
     cc[0]=zaman[6];                            //parçalara
     cc[1]=zaman[7];                            //ayırma
     cc[2]='\0';
     dd[0]=zaman[8];                            //işlemi
     dd[1]=zaman[9];                            //yaptırılıp
     dd[2]='\0';
     ee[0]=zaman[10];                           //rtc
     ee[1]=zaman[11];                           //ünitesenin
     ee[2]='\0';
     ff[0]=zaman[12];                           //parametrelerine
     ff[1]=zaman[13];                           //gönderiliyor
     ff[2]='\0';                                 //
     gg[0]=zaman[14];                           // rtc modülündeki gün sabit değişkenini sistemden istiyor ve  buraya saklıyor
     gg[1]='\0';
     }
   
    a=atoi(aa);b=atoi(bb);c=atoi(cc);d=atoi(dd);e=atoi(ee);f=atoi(ff);g=atoi(gg); // seri porttan alınan bilgiler sayı olsa bile string olduğu için atoi ile bunlar integer hale getiriliyor
    rtc_set_datetime(a,b,c,(g+1),d,e);   // gun  ,  ay   ,  yıl  ,  hangigün   ,   saat   ,   dakika
  }
  else if(oku=='$')               // here is reading name information sent by host pc
  {
     for(indis2=0;indis2<=14;indis2++)    //seri porttan gönderilen isim/soyisimi tampon adında bir dizine alıyoruz
        {
          tampon[indis2]=getch();
        }     
  rx_kontrol=1;
  } 
 
}

void main()
{
    pic_init();    // pic kütüphanesi çağırılıyor
    fputs("zaman");     // is asking the current time to host pc
    ozel_karakterler();    // for turkish characters
                 
while(1)
   { 
     if(sifre_aktif==0) {
                            output_low(pin_a0);
                            output_low(pin_a1);
      ana_sayfa();   // eğer *'a basılmasdıysa ana ekranda kal
                         }
      else if (sifre_aktif==1)  {    // *'a basıldı ise şifre alma sayfasına yönlendir   // if '*' entered, then move into this code block and get the numbers not less then 3 and not more than 4
                               
                                 char sifre[4];
                                 char gecici[5];
                                 basla:
                                 
                                 output_high(pin_a0);
                                 output_low(pin_a1);

                                 printf(lcd_putc,"\f");     // ekranı temizle
                                  do { // şifre ilk döngüsüne gir
                                   
                                    keypad_oku();
                                    if(tus=='#') {indis=indis; sayac=sayac;}   // eğer şifre alma programına girilir arkasından sayı yerine # basılırsa bunu algılamaması sağlanır
                                    else {gecici[indis]=tus;}
                                    if(indis==1) {sifre[sayac]=gecici[indis];sayac=1;}
                                    if(indis==2) {sifre[sayac]=gecici[indis];sayac=2;}
                                    if(indis==3) {sifre[sayac]=gecici[indis];sayac=3;}
                                    if(indis==4) {sifre[sayac]=gecici[indis];sayac=4;}
                                    if(indis==5) {sifre[sayac]=gecici[indis];sayac=5;}
                                   
                                    rtc_get_time(saat,dakika,saniye);

                                    lcd_gotoxy(1,1);
                                    if(saat<=13) {  printf(lcd_putc,"   --Günaydın-- ");}        // ekranın üst tarafında hangi dilimde giriş geldiğini gösterir
                                        else     {  printf(lcd_putc,"--İyi Akşamlar--");}
                                   
                                    lcd_gotoxy(1,2);
                                    printf(lcd_putc,"sifre="); 
                                    lcd_gotoxy(sayac+6,2);
                        if(indis==0) {                 // görsel olarak 4 haneli "****" şifre girileceğini gösterme amaçlı
                                      lcd_gotoxy(7,2);
                                      printf(lcd_putc,"****");
                                     }
                        if(indis>0)  {                 // butondan gelen veriyi şifre indisine aktarma fonksiyonu
                                      printf(lcd_putc,"%c",sifre[sayac]);
                                      }         
                        if(sayac>=5) {                 // eğer giriş 4 haneden fazla yapılmış ise fazla giriş uyarısı yapıp tekrar şifre istemeye döndüren parça
                                       lcd_gotoxy(1,2);
                                       printf(lcd_putc,"fazla giriş");
                                       gecikme(400);
                                       indis=0;
                                       sayac=0;
                                       goto basla;
                                                   }
                        if(sayac==4){  if(tus=='#') {            // 4 hane giriliğ "#" tuşunada basılmışsa bunu kontrol fonksiyonuna aktarma parçası
                                                      sifre_kontrol(sifre,boyut);
                                                     }
                         
                                     }                             
                                    } while(sifre_aktif==1);     // şifre girme alanında olup olunmadığı kontrol ediliyor
                                }
   enable_interrupts(INT_RDA);
   }
}

void pic_init()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   lcd_init();
   rtc_init();
   
   output_b(0xF0);
   set_tris_b(0b01110000);
   set_tris_a(0x00);
   
}

char keypad_oku()    // keypad scanning method
{
      output_b(0x00);

      output_high(sat1); output_low(sat2);output_low(sat3);output_low(sat4);// 1. satır lojik-1 yapılıyor     
      if (input(sut1))      {   while(input(sut1)); tus='1';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='2';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='3';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat1); // 1. satır lojik-0 yapılıyor

      output_high(sat2);output_low(sat1);output_low(sat3);output_low(sat4); // 2. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1)); tus='4';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='5';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='6';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat2); // 2. satır lojik-0 yapılıyor 

      output_high(sat3);output_low(sat1);output_low(sat2);output_low(sat4); // 3. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1)); tus='7';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 1. sütun okunuyor
      else if (input(sut2)) {   while(input(sut2)); tus='8';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 2. sütun okunuyor
      else if (input(sut3)) {   while(input(sut3)); tus='9';ses_cal(0.01); if(sifre_aktif==1) {indis++;}else indis=0; }  // 3. sütun okunuyor
     
      output_low(sat3); // 3. satır lojik-0 yapılıyor

      output_high(sat4);output_low(sat1);output_low(sat2);output_low(sat3); // 4. satır lojik-1 yapılıyor
      if (input(sut1))      {   while(input(sut1));  if(sifre_aktif==1) {indis=0; sayac=0; sifre_aktif=0;ses_cal(0.01);} else if(sifre_aktif==0) {indis=0; sayac=0;sifre_aktif=1;ses_cal(0.01);}}  // * ile şifre kontrol işlemine girilip çıkılıyor, indis'i 0'lamak durumundasındasın çünkü giriş çıkışta hafızada durmasın tekrardan başlasın diye
      else if (input(sut2)) {   while(input(sut2)); tus='0';ses_cal(0.01); if(sifre_aktif==1) {indis++;} else indis=0; }  // 2. sütun okunuyor while komutu ile tuşun bırakılmasını bekliyor.
      else if (input(sut3)) {   while(input(sut3)); tus='#';ses_cal(0.01);  }  // 3. sütun okunuyor
     
      output_low(sat4); // 3. satır lojik-0 yapılıyor
     
      return tus;
}

void ana_sayfa()
{
      rtc_get_time(saat,dakika,saniye);       // DS1302'den saat,dakika,saniye bilgileri alınıyor
      rtc_get_date(gun,ay,yil,haftanin_gunu); // DS1302'den gün,ay,yil ve günün isim bilgisi alınıyor
      printf(lcd_putc,"\fT:%02d/%02d/20%02d ",gun,ay,yil); //LCD'ye gün,ay,yıl bilgileri yazdırılıyor

      switch(haftanin_gunu)  // DS1302'den sayısal olarak alınan haftanın günü bilgisine
      {                      // metin olarak karşılık atanıyor
         case 1: printf(lcd_putc,"PAZ"); break; // Eğer "1" ise LCD'ye PAZ yaz
         case 2: printf(lcd_putc,"PZT"); break; // Eğer "2" ise LCD'ye PZT yaz
         case 3: printf(lcd_putc,"SAL"); break; // Eğer "3" ise LCD'ye SAL yaz
         case 4: printf(lcd_putc,"CRS"); break; // Eğer "4" ise LCD'ye CRS yaz
         case 5: printf(lcd_putc,"PER"); break; // Eğer "5" ise LCD'ye PER yaz
         case 6: printf(lcd_putc,"[spam]"); break; // Eğer "6" ise LCD'ye [spam] yaz
         case 7: printf(lcd_putc,"CTS"); break; // Eğer "7" ise LCD'ye CTS yaz
      }
      printf(lcd_putc,"\nSaat:%02d:%02d:%02d",saat,dakika,saniye); // LCD'ye saat,dakika ve saniye değerlerini yaz
      gecikme(100); // 1 sn gecikme veriliyor
           
      keypad_oku();
   }
   
void gecikme(int gec)   // instead of delay_ms gecikmesi verilirse eğer bu sistemi durdurma komutu olduğundan keypad'den gelen veride kayıba yol açtığı için kendi gecikme döngüsü yazıldı
{  static long int a=0;
   gec=gec*100;
   for(a=0;a<gec;a++) {
                     static long int b=0;
                     for(b=0;b<1000;b++) {}
                     }
}

void tus_bekle(void)    // debounce
{
    unsigned int i=2500;
    while(i--);
}

void sifre_kontrol(char sifre[], int  )      // send the last two digits of password entered by adding 0 or 1 to beginning of string to say mrning or afternoon information
{
                      output_low(pin_a0);
                      output_high(pin_a1);
                     
         char gecici;
         char gonder[4];
               
                  rtc_get_time(saat,dakika,saniye);
                  if (saat <= 13) {gecici='0';}    // şifre girildiği anda karşı tarafa sabahmı yoksa akşam mı bilgisini veren kısım  0 sabah 1 akşam
                  else            {gecici='1';}
         gonder[0]=gecici;
         gonder[1]=sifre[2];
         gonder[2]=sifre[3];
         gonder[3]='\0';       // eğer bununla kelime sonu bilgisi göndermez isek program ramdom olarak gonder stringinin sonuna karakter ekleyecektir
         
                             
                  fputs(gonder);
                  printf(lcd_putc,"\f");
                  devam:                                // is waiting the name data which is matched with password entered
                  if(rx_kontrol==1) {
                  printf(lcd_putc,"%s",tampon);
                  lcd_gotoxy(1,2);
                  printf(lcd_putc," ---%02d:%02d:%02d---",saat,dakika,saniye); 
                  gecikme(10000);}
                  else goto devam;
                  rx_kontrol=0;

  sifre_aktif=0;
  indis=0;
  sayac=0;
}

void ses_cal(float sure)     // for buzzer
{
  output_high(pin_a3);
  gecikme(sure);
  output_low(pin_a3);
}

gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Mon Nov 28, 2016 3:27 pm     Reply with quote

Baris

I will propose you a few things:
1. rda_isr; Set a flag and do the if(oku=='X') outside the isr
2. If you want help, invest some time and translate the remarks to English
Not every one knows what are: "saniye,dakika,saat,gun,ay,yil,haftanin_gunu" for example
3. Checkout a few programs written by PCM programmer, Ttelmah and others
and see the structures.
For example, you don't need "void pic_init()", just place the setup's,
enable's, etc'. It will make your software more easy to understand

Best wishes
Joe
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Nov 29, 2016 4:16 am     Reply with quote

I fully endorse all the comments you've received.

Out of curiosity I looked at your video.
It tells me nothing, and is a complete waste of time and effort.

To be positive.

1) Work on the KISS principal.
2) Forget Proteus.
3) Start again from scratch.
4) Use the examples you've been ponted towards.
5) Get each section to work one at a time.

You're complaining that the keypad and RS232 interact.
Throw out everything else and get those to work together first.
Then build on firm foundations.

Mike
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Tue Nov 29, 2016 5:07 am     Reply with quote

I was just proposing as Jay always advising to make a led blink at first.
It will tell you the controller works and in the correct frequency.

Best wishes
Joe
baris_akinci



Joined: 10 Mar 2016
Posts: 17
Location: Ankara

View user's profile Send private message

rs232 communication and keypad interference
PostPosted: Tue Dec 13, 2016 5:13 am     Reply with quote

Dear All,

I have found the problem finally and get the project worked!
The problem was not about the software, it was about hardware! During test the board, I have always used my USB port with RS232/USB converter. Finally I have realised that this connection is making noise back to the board and this affect to the keypad scanning part of the system then keypad has fail. Then I have tested the board on desktop with RS232 port directly and it is worked perfectly!

Thank you for your advice. If you have any idea what can cause this noise and how can I put forward this problem, I would like to listen.

best wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group