18f25k80 donanımsal 2 UART nasıl kullanılır

Başlatan mikro29, 13 Mart 2018, 16:28:42

mikro29

18f25k80 HSERIN gsm module,HSERIN2 donanımsal kesme ile dokunmatik ekrana bağlı. Kesmeye girince daha çıkmıyor.2 Usart kesmesi olmasa bile sadece HSERIN normal(kesmesiz), HSERIN2 donanımsal kesme nasıl yapılabilir yardımlarınızı bekliyorum.Koddan parça aşağıda


Device = 18F25K80
Declare Xtal = 10
On_Hardware_Interrupt GoTo KESME
PORTA = %00000000
PORTB = %00000000
PORTC = %00000000
Declare  SHOW_SYSTEM_VARIABLES = OFF 
Declare  FSR_CONTEXT_SAVE = OFF
Declare  Reminders = OFF
Declare  Warnings = OFF
Declare  Optimiser_Level 0

Config_Start
  RETEN = OFF ;Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
  INTOSCSEL = High ;LF-INTOSC in High-power mode during Sleep
  SOSCSEL = High ;High Power SOSC circuit selected
  XINST = On ;Enabled
  FOSC = HS1 ;HS oscillator (Medium power, 4 MHz - 16 MHz)
  PLLCFG = OFF ;Disabled
  FCMEN = OFF ;Disabled
  IESO = On ;Enabled
  PWRTEN = On ;Disabled
  BOREN = OFF ;Disabled in hardware, SBOREN disabled
  BORV = 3 ;1.8V
  BORPWR = ZPBORMV ;ZPBORMV instead of BORMV is selected
  WDTEN = OFF ;WDT disabled in hardware; SWDTEN bit disabled
  WDTPS = 1048576 ;1:1048576
  CANMX = PORTC
  MSSPMSK = MSK7 ;7 Bit address masking mode
  MCLRE = OFF ;MCLR Disabled, RE3 Enabled
  STVREN = OFF ;Disabled
  BBSIZ = BB2K ;2K word Boot Block size
  Cp0 = OFF ;Disabled
  CP1 = OFF ;Disabled
  CP2 = OFF ;Disabled
  CP3 = OFF ;Disabled
  CPB = OFF ;Disabled
  CPD = OFF ;Disabled
  WRT0 = OFF ;Disabled
  WRT1 = OFF ;Disabled
  WRT2 = OFF ;Disabled
  WRT3 = OFF ;Disabled
  WRTC = OFF ;Disabled
  WRTB = OFF ;Disabled
  WRTD = OFF ;Disabled
  EBTR0 = OFF ;Disabled
  EBTR1 = OFF ;Disabled
  EBTR2 = OFF ;Disabled
  EBTR3 = OFF ;Disabled
  EBTRB = OFF ;Disabled
Config_End
         '76543210
TRISA  = %00000001
TRISB  = %10011011
TRISC  = %10101000
PORTA  = %00000000
PORTB  = %00000000
PORTC  = %00000000
ADCON0 = %00000000
ADCON1 = %00000000
CCP1CON = %00000000
LATA   = %00000000
LATB   = %00000000
LATC   = %00000000
OSCCON = %00000000
'INTCON = %00000000
'OSCCON = %00000000
'INTCON2.7 = 1  ' PULL UP AKTİF
INTCON= %10100000
INTCON2=%10000000
'PMD2  = %00001111
'PMD1  = %11111111
'PMD0  = %11111111' 1.BİT=USART1 , 2.BİT=USART2(0 AKTİF)
PIR1 =  %00000000
PIE1 =  %00000000
IPR1 =  %00000000

' T0CON = %11000000
'-----------------------------------------------------------
Declare All_Digital = TRUE         
'-----------------------------------------------------------
Declare Hserial_Baud = 9600   
Declare Hserial_RCSTA = %10010000                                       
Declare Hserial_TXSTA = %00100100
Declare Hserial_Clear = On              ' bilgi alındığında Tampon belleği temizle

Declare Hserial2_Baud 9600             
Declare Hserial2_RCSTA = %10010000 
Declare Hserial2_TXSTA = %00100100
Declare Hserial2_Clear = On
'-----------------------------------------------------------
Declare PortB_Pullups = OFF
PIE1.5=0 'USART1 RX KESME KAPALI
PIR1.5=0
PIR1.7=0'OKUMA YAZMA KAPALI

Symbol GIE    =INTCON.7 'genel interruptlar  aciyor 
Symbol PEIE   =INTCON.6 'Cevresel kesmeleri  aciyor 
Symbol RCIE   =PIE3.5   'usart2 rx kesme devrede   
Symbol RCIF   =PIR3.5   'USART Receive interrupt flag bit
'PIE3.4=0
RCIE=1
PEIE=1
GIE=1 

GoTo BASLA
KESME: 'DONANIMSAL KESME
Context Save                    ' register içeriklerini sakla
     GIE=0                      ' kesme olmaması için kesmeler kapalı
     HSerIn2 1,CIK,[ALINAN]     '
     If ALINAN=$0A Then
    GOSUB SMS_GONDER
'     GOSUB BIP   
'     HSerOut ["KESME...",13,10]
CIK:
     RC=RCREG
     RCIF=0                     'USART Receive interrupt Flag Temizleniyor
     GIE=1                      'kesmeler aktif
Context Restore
Retfie Fast

MESGUL = 0:GoSub MESGULMU
BASLA: '******************** PROGRAM BAŞLANGICI ***************
    ALINAN=0   
    GLN_MSJ=0
    HSerIn 1,BASLA,[Wait ("+CMTI:"),Wait ("SM")]
    GoTo SMS_VARMI   
    GoTo BASLA     
End '********************** PROGRAM SONU **************************************

SMS_GONDER: 
        HSerOut ["AT+CMGF=1",13]                         ' SMS FORMATI 0 = PDU ,1 =TEXT
        HSerIn 1000,SMS_GONDER,[Wait("OK")]   
    SMS_ADIM2:                                                             
        HSerOut ["AT+CMGS=",34,"05",Dec SMS_TEL_NO,34,13,10]      ' SMS NUMARASI 
        HSerIn 1000,SMS_ADIM2,[Wait(">")]   '             
    SMS_ADIM3:   
        HSerOut [Str SMS_MESAJ,$1A,13]                             ' SMS MESAJI
'    MESGUL = 0:GoSub MESGULMU       
Return


ete

Olaya tamamen mantık açısından bakmak gerek. 1 adet USART portu olanlar için ne yapıyorsan aynısını bu port içinde yapacaksın.
Yalnızca Register isimlerinin sonuna 2 geliyor. Veri yollarken HSEROUT2 , veri alırken HSERIN2 kullanacaksın.
Tabiiki 1 olu usart için kullanacağın register adlarına 1 eklenecektir. Buna ait Alma verme komutlarında 1 yer almıyor. HSEROUT ve HSERIN şeklinde kullanılacak.
Kesme için aktivasyon PIE1.5 USART1 kesmesini aktive ederken buna ait alım registeri RCREG1 ve Kesme bayrağı PIR1.5 nolu biti olacaktır. USART2 için ise PIE3.5 biti kesme aktivasyon biti, register RCREG2 ve kesme bayrağıda PIR3.5 biti şeklinde kullanılacaktır.
Kısaca değişen bir şey yok. Her iki portuda kullanacak iseniz Kesme içinde kesme bayrağına bakarak hangisine ait kesmenin oluştuğunu anlayıp programı kesme içinde oraya yönlendirmek gerekir.
Bunun için iki tane if satırı kullanmaya gerek yok.
IF PIR1.5=1 then deyip altına 1 nolu usart için alma komutları ve en sonda bayarağı sıfırlayacak TEMP=RCREG1 yazıp ATLA etiketine yönlendirmek yeterli olacak. Bu bölümün sonunda yer alacak ENDIF ten sonra
direk USART2 ye ait komutları yazıp TEMP=RCREG2 deyip altında yer alan ATLA etiketi ile işi bitirmek gerekir.
Umarım anlaşılmıştır.
Ete

mikro29

#2
ETE hocam sadece HSERIN1 kesme olmasına gerek yok HSERIN2 kesme olsun yeterli dediklerinizi yapmaya çalışacağım şu anda ikiside kesmeye giriyor. Böyle yaptım yine olmadı. EKRAN_OKU etiketindede HSERIN1 ler var burda takılıyor.


GoTo BASLA
KESME: 'DONANIMSAL KESME
Context Save                    ' register içeriklerini sakla
     GIE=0                      ' kesme olmaması için kesmeler kapalı
'          '
     If PIR3.5=1 Then
         HSerIn2 [ALINAN]
         If ALINAN=$0A Then GoTo EKRAN_OKU  'GoSub BIP'
     EndIf
CIK:
     RC=RCREG
     RC2IF=0                    'USART Receive interrupt Flag Temizleniyor
     GIE=1                      'kesmeler aktif
Context Restore
Retfie Fast

MESGUL = 0:GoSub MESGULMU
BASLA: '******************** PROGRAM BAŞLANGICI ***************
    ALINAN=0   
    GLN_MSJ=0
'    GoSub BIP
'    DelayMS 1000
   HSerIn 1,BASLA,[Wait ("+CMTI:"),Wait ("SM")]
    GoTo SMS_VARMI
    GoTo BASLA     
End '********************** PROGRAM SONU **************************************

ete

Kesme içinde şu dallanmayı yapamazsın
         If ALINAN=$0A Then GoTo EKRAN_OKU  'GoSub BIP'
Ekran Oku etiketini göremedim nerede yer alıyor ama muhtemelen kesme dışında. Kesme özel bir bölümdür. Oraya girerken bir sürü protokol ile giriliyor. Çıkarkende o protokolü geriye uygulamak gerekiyor.
  RC=RCREG
     RC2IF=0                    'USART Receive interrupt Flag Temizleniyor
     GIE=1                      'kesmeler aktif
Context Restore
Retfie Fast
komut satırları bunu yapıyor. Ama sen GOTO EKRAN_OKU demekle bunları atlamış oluyorsun ve program stack şaşırmasına girip kilitleniyordur.
Önce kesmeden normal şekilde çıkacaksın. Çıktığın yerde bunu yapabilirsin ancak. Madem yalnızca USART2 için kesme kullanıyorsun; ...... IF PIR3.5=1 THEN  şeklinde bir test satırınada gerek yok. Başka amaçla kesme oluşmayacak ise bu satırıda yazmaya gerek yok. Zaten PIR3.5=1 olduğu için program oraya gelmiş olacak.

Ekran Oku diye bir etiket bile göremedim ben.

Ete

mikro29

#4

GoTo BASLA
KESME: 'DONANIMSAL KESME
Context Save                      ' register içeriklerini sakla
     GIE=0                           ' kesme olmaması için kesmeler kapalı
     If PIR3.5=1 Then            'HSEROUT2 kesme oluşmuşsa
         HSerIn2 [ALINAN]
         If ALINAN = $0A Then   
           ALINAN=0     
            HSerOut2 ["t2.txt=",34,Dec2 SAATT,":",Dec2 DAKIKA,"-MOTOR OTOMATiK CALISTIRILDI",34,$ff,$ff,$ff]
            GoSub BIP
            SMS_TEL_NO=12346567 
            StrN SMS_MESAJ = "YARLOAC"
            GoSub SMS_GONDER  [glow=red,2,300] HSEROUT2 kesmesi olunca burada sürekli kalıyor[/glow]
            StrN INT_MESAJ ="MOTOR_OTOMATiK_CALISTIRILDI"
            GoSub DEPO_GONDER
        EndIf
     EndIf
CIK:
     RC=RCREG
     RC2IF=0                    'USART Receive interrupt Flag Temizleniyor
     GIE=1                      'kesmeler aktif
Context Restore
Retfie Fast

MESGUL = 0:GoSub MESGULMU
BASLA: '******************** PROGRAM BAŞLANGICI ***************
    ALINAN=0   
    GLN_MSJ=0
    GoSub BIP
    DelayMS 500
    HSerIn 1,BASLA,[Wait ("+CMTI:"),Wait ("SM")] [glow=red,2,300]Denemek için her 500ms de bir bip sesi çıkar dediğim halde bir kere buraya girip bekliyor bekliyor. Ama mesaj geldiği zaman burdan çıkıyor[/glow]
    GoTo SMS_VARMI
    GoTo BASLA     
End '********************** PROGRAM SONU **************************************

SMS_GONDER: 
        HSerOut ["AT+CMGF=1",13]                         ' SMS FORMATI 0 = PDU ,1 =TEXT
        HSerIn 1000,SMS_GONDER,[Wait("OK")]   
    SMS_ADIM2:                                                             
        HSerOut ["AT+CMGS=",34,"05",Dec SMS_TEL_NO,34,13,10]      ' SMS NUMARASI 
        HSerIn 1000,SMS_ADIM2,[Wait(">")]   '             
    SMS_ADIM3:   
        HSerOut [Str SMS_MESAJ,$1A,13]                             ' SMS MESAJI
'    MESGUL = 0:GoSub MESGULMU       
Return



HSEROUT2 kesmesine girince sonuç


AT+CMGF=1

OK
AT+CMGS="053000000000"

> 0"
AT+CMGS="050"
AT+CMGS="050"
AT+CMGS="050"
AT+CMGS="050"
AT+CMGS="050"
AT+CMGS="050"


böyle devam ediyor
 HSerIn 1,BASLA,[Wait ("+CMTI:"),Wait ("SM")]
  bu komut işlemiyor veya UART1 kesmesini kapatamadım gibi

ete

Söylediklerimi anlamadın galiba,
KESME içinden kesme dışına GOSUB , GOTO vs gibi komutlarla gidemezsin. Çok gerekiyorsa bit değişkeni kullanarak işaretçi olarak kullanıp programın ana ksımında bu işaretçilere bakıp aynı işlemleri orada yaptırman gerekir.
Son kez söylüyorum. KESME içinden normal şekilde , kesme bayrağını sıfırlayıp Context Restore yaptırarak çıkman gerekir.
Programını bu talimata göre değiştir.

Söyledim KESME özel bölge, program buraya bütün registerleri bir yerlere kayıt ederek girer ve çıkarkende bunları geri yükler. Sen aradan çıkınca bütün düzen altüst olur ve sonunda program şaşırıp kilitlenir. Yada hata yapmaya başlar.
Ete

mikro29


GoTo BASLA
KESME: 'DONANIMSAL KESME
Context Save                    ' register içeriklerini sakla
     GIE=0                      ' kesme olmaması için kesmeler kapalı
         HSerIn2 1,CIK,[ALINAN]
CIK:     
     RC=RCREG
     RC2IF=0                    'USART Receive interrupt Flag Temizleniyor
     GIE=1                      'kesmeler aktif   
Context Restore
Retfie Fast

MESGUL = 0:GoSub MESGULMU
BASLA: '******************** PROGRAM BAŞLANGICI ***************
'    ALINAN=0   
    GLN_MSJ=0
   If ALINAN = $0A Then   
        ALINAN=0     
        HSerOut2 ["t2.txt=",34,Dec2 SAATT,":",Dec2 DAKIKA,"-MOTOR OTOMATiK CALISTIRILDI",34,$ff,$ff,$ff]
        GoSub BIP
        SMS_TEL_NO=12346567 
        StrN SMS_MESAJ = "YARLOAC"
        GoSub SMS_GONDER
    EndIf
   
    HSerIn 1,BASLA,[Wait ("+CMTI:"),Wait ("SM")]  '<<< Burada sürekli bekliyor BASLA etiketine hiç dönmüyor   
    GoTo SMS_VARMI
    GoTo BASLA     
End '********************** PROGRAM SONU **************************************

HSerin kısmını silince USART2 kesmesi normal çalışıyor

ete

Çalışır elbette.
Hserin de kesmeye bağlanmalı bence. Bağlamaz isen program gelir orada bir şey alıncaya kadar bekler. Bunu engellemekiçin oraya Timeout koyman gerekir.Koymuşsun ama 1ms de kimse br şeyyapamaz. 1 yerine 10 yaz. Ancak öncesine koyduğun 1000 ms lik gecikme bütün işi berbat eder. O gecikme esnasında veri gelirse nasıl alacak program o veriyi. Gecikmeleri kaldır bence.

Ayrıca son örnekde aşağıdaki satırları görüyorum. En başa ALINAN=0 demişsin aldında IF ALINAN=$0A Then demişsin. Sıfırladığın bir şeyin değer alması ancak mucize olursa olur. Zira sıfırladıktan sonra 2 us -10us arasında bir sürede kesme gelip ALınan değer değiştirirse işin görülür ama bu bence mucize gerektirir. Alınan=0 komutu o işle ilgili çalışman bittiğinde verilmesi gereken bir komuttur.
BASLA: '******************** PROGRAM BAŞLANGICI *************** 
'    ALINAN=0   
    GLN_MSJ=0
   If ALINAN = $0A Then 
  

Ete


mikro29

#8
Hocam Hserin komutu takılıyor. timeout süresini uzattım yine olmuyor ALINAN=0  aktif değil, program işliyormu diye 1000 ms yaptım. protonbasic kendi forumunda komutun sıkıntılı olduğunu söylüyorlar.Buna benzer çok var http://www.protonbasic.co.uk/showthread.php/69056-problem-with-HserIn versiyon 3.5.3.5 normal çalışıyormuş o versiyonu bulamıyorum.
Başka nasıl yapabilirim.

ete

Başka onuda kesme içine alırsan rahat edersin.
Bence en doğru yol bu.
Proton kullanmıyorum. PBP da Hserin ile timeout gayet güzel çalışıyor. Orada çalışmıyorsa ya çalışanını bulacaksın yada kesme içine alacaksın.

Ete

Powered by EzPortal