MPLABX İKİ PİC ARASI HABERLEŞME HAKKINDA

Başlatan elektra, 26 Temmuz 2019, 14:45:52

elektra

Merhabalar

16f690 ile iki pic arası haberleşme yapmak istiyorum. Program proteusta güzel çalışıyor fakat devreyi gerçeklediğimde iki pic'tede bütün diğer işlemler çalışıyor fakat sadece rs232 çalışmıyor. Yani piclerin bozuk olmadığına ve sigorta yapılandırma ayarlarının düzgün olduğuna eminim. Simülasyonda çalışıp gerçekte çalışmamasına anlam veremiyorum birçok farklı yerden baktım araştırdım hep aynı yöntem kullanılıyor. Kodlar şu şekilde;

/*usart.h dosyası*/
#include <xc.h>
#define _XTAL_FREQ 8000000
extern char USART_hazirla(const long int baudrate);
extern void USART_Yolla(char veri);
extern char USART_TSR_kontrol(void);
extern void USART_Yolla_Text(char *text);
extern char USART_Veri_alim_kontrol(void);
extern char USART_Veri_Oku(void);

/*usart.c dosyası*/
#include <xc.h>
#include "rs232_lib.h"

char USART_hazirla(const long int baudrate)
{
    unsigned int x;
    x=(_XTAL_FREQ - baudrate*16)/(baudrate*16);
    BRGH=1;
    if(x<256)
    {
        SPBRG=x;
        SYNC=0;
        SPEN=1;
        CREN=0;
        TXEN=1;
        return 1;
     }
    return 0;
}

void USART_Yolla(char veri)
{
    while(!TRMT);
    TXREG = veri;
}

char USART_Veri_Oku()
{
    while(!RCIF);
    return RCREG;
}

char USART_TSR_kontrol()
{
    return TRMT;
}

void USART_Yolla_Text(char *text)

{
    int i;
    for (i=0;text!='\0';i++)
        USART_Yolla(text);
}

char USART_Veri_alim_kontrol()
{
    return RCIF;
}

verici kodunda yukarıdaki USART_Yolla(veri) fonksiyonunu
alıcı kodunda yukarıdaki PORTX=USART_Veri_Oku() fonksiyonunu kullanıyorum

Birkaç farklı kod daha denedim ama aşağı yukarı hepsi aynı hiçbirini çalıştıramadım.

Teşekkürler Saygılar....

a.zorba

RX TX kabloların yanın'da GND yide taşi aynı devrede farklı yerden gnd olsada haberleşme kablolarının yanında ' da gnd olsun.

elektra

iki yanından da gnd geçirdim özellikle parazit azaltması adına.

elektra

ccs c de ufak bir deneme yaptım aynı bağlantı üzerinden onda çalıştı haberleşme yapabiliyor. ama mplab da bir sıkıntı var.

a.zorba

aşagıda nextion ile çalışan kodlar var senin kod unda ilk gördügüm alım sırasında interrupt ları kapatmamışsın
#include <xc.h>
#include <stdio.h> //sprintf icin gerekli
#include <stdint.h>
#include <string.h>
#define _XTAL_FREQ 20000000
#define BAUDRATE 9600  //bps
#include "lcd_hd44780_pic16.h"

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

void USARTInit();
void USARTWriteByte(char);
void USARTWriteString(const char *);
void USARTWriteLine(const char *);
void USARTWriteInt(int, unsigned char);
void ekranbekle(void);
void procesa_rx();
uint8_t dht11_measure();


#define DH11_DATA_BIT   PORTDbits.RD5
#define DH11_DATA_TRIS  TRISDbits.TRISD5

#define topraknemrole PORTBbits.RB0        // S1  S2     On/Off
#define havanemrole   PORTBbits.RB1          // S3   S4    On/Off
#define isirole       PORTBbits.RB2              // S5  S6     On/Off
#define lambarole     PORTBbits.RB3            // S7   S8    On/Off

uint8_t dht11_data[40];
uint8_t dht11_rh;
uint8_t dht11_temp;

unsigned char s1[20] = "";
char temp[30];
char i = 0;
char flag_rx = 0;
char data = 0;

void delay() {
    uint16_t i;
    for (i = 0; i < 3000; i++) {
        __delay_ms(1);
    }
}

void ADC_Init() {
    ADCON0 = 0x81; //Turn ON ADC and Clock Selection
    ADCON1 = 0x00; //All pins as Analog Input and setting Reference Voltages
    ADCON1bits.ADFM = 1;
}

unsigned int ADC_Read(unsigned char channel) {
    if (channel > 7) //Channel range is 0 ~ 7
        return 0;

    ADCON0 &= 0xC5; //Clearing channel selection bits
    ADCON0 |= channel << 3; //Setting channel selection bits
    __delay_ms(2); //Acquisition time to charge hold capacitor
    GO_nDONE = 1; //Initializes A/D conversion
    while (GO_nDONE); //Waiting for conversion to complete
    return ((ADRESH << 8) + ADRESL); //Return result
}

void BEKLE(int b) {
    for (int d = 0; d >= b; d++) {
        __delay_ms(50);
    }
}

void main() {
    
    USARTInit();
    TRISA = 0xFF; //Analog pins as Input
    TRISB = 0x00; //Analog pins as Input
    ADC_Init(); //Initialize ADC

    __delay_ms(10);
   
    int topraknem;
    int topraknem1;
    int topraknem2;
topraknemrole=1;        // S1  S2     On/Off
havanemrole=1;          // S3   S4    On/Off
isirole=1;               // S5  S6     On/Off
lambarole=1; 

     __delay_ms(200); __delay_ms(200); __delay_ms(200); __delay_ms(200); __delay_ms(200); __delay_ms(200);
    while (1) {
        for( int m=0;m<= 360;m++)
        {
            procesa_rx();
          __delay_ms(200);   __delay_ms(200);  __delay_ms(200);  __delay_ms(200);  __delay_ms(200); 
        }
        if (!dht11_measure()) {
            sprintf(s1, "page0.t0.txt=");
            USARTWriteString(s1);
            USARTWriteByte('"');
            USARTWriteString("NEM HATA");
            USARTWriteByte('"');
            __delay_ms(5);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            __delay_ms(50);
        } else {
            sprintf(s1, "page0.t0.txt=");
            USARTWriteString(s1);
            USARTWriteByte('"');
            USARTWriteString("ARIZA YOK");
            USARTWriteByte('"');
            __delay_ms(1);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            BEKLE(10);
            if (topraknem >= 99) {
                sprintf(s1, "page0.t0.txt=");
                USARTWriteString(s1);
                USARTWriteByte('"');
                USARTWriteString("TOPRAK HATA");
                USARTWriteByte('"');
                __delay_ms(5);
                USARTWriteByte(0xFF);
                USARTWriteByte(0xFF);
                USARTWriteByte(0xFF);
                __delay_ms(50);
            }

            topraknem1 = ADC_Read(0); //Read Analog Channel 0
            topraknem2 = ADC_Read(1); //Read Analog Channel 0

            topraknem1 = topraknem1 / 13;
            topraknem2 = topraknem2 / 13;
            topraknem = topraknem1 + topraknem2;
            topraknem = topraknem / 2;
 
            topraknem  = 100-topraknem;  //  scalay? ters çevirmek için 
            if (topraknem<=1)
            {
            topraknem=1;
            }
             if (topraknem>=99)
            {
            topraknem=99;
            }
            sprintf(s1, "page0.n0.val=%d", topraknem);
            USARTWriteString(s1);
            __delay_ms(5);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            __delay_ms(50);

            sprintf(s1, "page0.n1.val=%d", dht11_rh);
            USARTWriteString(s1);
            __delay_ms(5);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            __delay_ms(100);


            sprintf(s1, "page0.n2.val=%d", dht11_temp);
            USARTWriteString(s1);
            __delay_ms(5);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            USARTWriteByte(0xFF);
            __delay_ms(100);
procesa_rx();
        }
        __delay_ms(100);
        procesa_rx();
    }

}

uint8_t dht11_measure() {
    for (uint8_t i = 0; i < 40; i++) dht11_data[i] = 0;

    DH11_DATA_BIT = 0;
    DH11_DATA_TRIS = 0;

    __delay_ms(20);

    DH11_DATA_TRIS = 1;

    uint8_t counter = 0;

    //wait for falling edge
    while (DH11_DATA_BIT) {
        counter++;
        __delay_us(1);

        if (counter == 80)
            return 0;
    }

    //wait for rising edge
    while (!DH11_DATA_BIT) {
        counter++;
        __delay_us(1);

        if (counter == 180)
            return 0;
    }

    //wait for falling edge
    while (DH11_DATA_BIT) {
        counter++;
        __delay_us(1);

        if (counter == 80)
            return 0;
    }


    for (uint8_t i = 0; i < 40; i++) {
        //wait for rising edge
        while (!(PORTD & (1 << 5)));


        //Setup Timer1
        T1CKPS0 = 1; //Prescaller = 1:2
        TMR1L = 0x00; //Init counter
        TMR1H = 0x00;
        TMR1ON = 1; //Stat timer

        //wait for falling edge
        while ((PORTD & (1 << 5)));

        TMR1ON = 0;

        /**/
        uint16_t time = TMR1L;
        time = time | (TMR1H << 8);

        time = time * 2;

        if (time > 55 && time < 70) {
            //bit is 0
            dht11_data[i] = 0;
        } else if (time > 150) {
            //bit is 1
            dht11_data[i] = 1;

        }
    }

    dht11_rh = dht11_temp = 0;

    for (uint8_t i = 0; i < 8; i++) {
        if (dht11_data[i] == 1)
            dht11_rh |= (1 << (7 - i));
    }

    for (uint8_t i = 0; i < 8; i++) {
        if (dht11_data[16 + i] == 1)
            dht11_temp |= (1 << (7 - i));
    }

    return 1;
}

void ekranbekle() {
    for (int z = 0; z < 5; z++) {
        __delay_ms(100);
    }
    return;
}

void interrupt  kesme(void) {
    di();

    if (RCIF == 1) {
        data = RCREG;
        temp[i] = data;
        if ((i > 3) && (temp[i] == 0xff) && (temp[i - 1] == 0xff) && (temp[i - 2] == 0xff)) // eger 3 den çok veri alm??san  ve bunlar?n içinde son 3 ü  0xff ise 
        {
            flag_rx = 1;
            CREN = 0;
            RCIE = 0;
        }
        i++;
        if (i >= 30) {
            flag_rx = 0;
            i = 0;
        }
    }
    RCIF = 0;
    ei();
}

void procesa_rx() {
    if (flag_rx == 1) {
        if (strstr(temp, "s1=")) {
            topraknemrole=1;
        }
           if (strstr(temp, "s2=")) {
            topraknemrole=0;
        }
        
        
             if (strstr(temp, "s3=")) {
havanemrole=1;
        }
           if (strstr(temp, "s4=")) {
havanemrole=0;
        }
         
        
            if (strstr(temp, "s5=")) {
isirole=1;
        }
           if (strstr(temp, "s6=")) {
isirole=0;
        }
           
        
        
            if (strstr(temp, "s7=")) {
lambarole=1;
        }
           if (strstr(temp, "s8=")) {
lambarole=0;
        }
        

        memset(temp, 0, 30);
        i = 0;
        flag_rx = 0;
        RCIF = 0;
        CREN = 1; //HABILITA LA RECEPCION CONTINUA
        RCIE = 1; //habilita interrpcion
    }
}

void USARTInit() {
    TRISC6 = 1; // TX Pin
    TRISC7 = 1; // RX Pin
    SPBRG = ((_XTAL_FREQ / 16) / BAUDRATE) - 1;
    BRGH = 1; // Fast baudrate
    SYNC = 0; // Asynchronous
    SPEN = 1; // Enable serial port pins
    CREN = 1; // Enable reception
    SREN = 0; // No effect
    TXIE = 0; // Disable tx interrupts
    RCIE = 1; // Enable rx interrupts
    TX9 = 0; // 8-bit transmission
    RX9 = 0; // 8-bit reception
    TXEN = 0; // Reset transmitter
    TXEN = 1; // Enable the transmitter
    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;
    ei();
    return;
}

void USARTWriteByte(char ch) {
    //Wait for TXREG Buffer to become available
    while (!TXIF);
    TXREG = ch;
}

void USARTWriteString(const char *str) {
    while ((*str) != '\0') {
        while (!TXIF);
        TXREG = (*str);
        str++;
    }
}

void USARTWriteLine(const char *ln) {
    USARTWriteString(ln);
    USARTWriteString("\r\n");
}

void USARTWriteInt(int val, unsigned char field_length) {
    if (val < 0) {
        USARTWriteByte('-'); //Write '-' sign for negative numbers.
        val = (val * (-1)); //Make it positive.
    }
    //Convert Number To String and pump over Tx Channel.
    char str[5] = {0, 0, 0, 0, 0};
    int i = 4, j = 0;
    while (val) {
        str[i] = val % 10;
        val = val / 10;
        i--;
    }
    if (field_length > 5)
        while (str[j] == 0) j++;
    else
        j = 5 - field_length;

    for (i = j; i < 5; i++) {
        USARTWriteByte('0' + str[i]);
    }
}


elektra

verdiğiniz kodlara göre düzenlemeleri yaptım configuration ayarları ile ilgili. fakat yine çalışmadı nerede hata var bir türlü bulamadım...

a.zorba


donanımda sorun olmadıgını belirtdiniz.

sizin proje dosyası  ve kod u görmeden bir şey demek zor.

elektra

tabiki göndereyim. Zaten yukarıda belirttiğimin aynısı çok basit bir port gönderme işlemi ama hiç haberleşmiyor.

verici tarafı;

// PIC16F690 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include "rs232_lib.h"
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 8000000

char gonder;
void main (void)
{
    OSCTUNEbits.TUN0=1;
    OSCTUNEbits.TUN1=1;
    OSCTUNEbits.TUN2=1;
    OSCTUNEbits.TUN3=1;
    OSCTUNEbits.TUN4=0;   
    OSCCONbits.IRCF0=1;
    OSCCONbits.IRCF1=1;
    OSCCONbits.IRCF2=1;
    
    TRISC=0x00;
    PORTC=0x00;  
    
    ANSELbits.ANS0=1;
    ANSELbits.ANS1=0;
    ANSELbits.ANS2=1;
    ANSELbits.ANS3=0;
    ANSELbits.ANS4=0;
    ANSELbits.ANS5=0;
    ANSELbits.ANS6=0;
    ANSELHbits.ANS8=0;
    ANSELHbits.ANS9=0;
    ANSELHbits.ANS10=0;
    ANSELHbits.ANS11=0;  
    
    UART_Init(9600);
    while(1)
    { 
      for(int i=0;i<8;i++)
      {
         PORTC=i;
         UART_Write(i);
         __delay_ms(150); 
      }    
    }
}

alıcı taraf
// PIC16F690 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#include "rs232_lib.h"
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 8000000

unsigned char veri;
void main(void)
{
    OSCTUNEbits.TUN0=1;
    OSCTUNEbits.TUN1=1;
    OSCTUNEbits.TUN2=1;
    OSCTUNEbits.TUN3=1;
    OSCTUNEbits.TUN4=0;
    
    OSCCONbits.IRCF0=1;
    OSCCONbits.IRCF1=1;
    OSCCONbits.IRCF2=1;
    
    TRISC=0x00;
    PORTC=0x00;
    UART_Init(9600);    
    do
    { 
        if(UART_Data_Ready())
        PORTC = UART_Read();
    }while(1);
}

uart.h;

#include <xc.h> 
#define _XTAL_FREQ 8000000
char UART_Init(const long int baudrate)
{
   unsigned int x;
   x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
   if(x>255)
   {
      x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
      BRGH = 1;
   }
   if(x<256)
   {
     TRISB7 = 1;
     TRISB5 = 1;
     SPBRG = x;
     SYNC = 0;
     SPEN = 1;
     CREN = 1;
     SREN=0;
     TXIE=0;
     RCIE = 1;
     TX9 = 0; // 8-bit transmission
     RX9 = 0; // 8-bit reception
     TXEN = 0; // Reset transmitter
     TXEN = 1; // Enable the transmitter
     INTCONbits.PEIE = 1;
     INTCONbits.GIE = 1;
     return 1;
   }
   return 0;
}

char UART_TX_Empty()
{
  return TRMT;
}

char UART_Data_Ready()
{
   return RCIF;
}
char UART_Read()
{
 
  while(!RCIF);
  return RCREG;
}

void UART_Read_Text(char *Output, unsigned int length)
{
   unsigned int i;
   for(int i=0;i<length;i++)
      Output[i] = UART_Read();
}

void UART_Write(char data)
{
  while(!TXIF);
  TXREG = data;
}

void UART_Write_Text(char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
     UART_Write(text[i]);
}

elektra

Yok mu yardım edecek hocalarım bilgili arkadaşlarım... Çözemedim bu sorunu

a.zorba

#9
Tris lari kontrol ed cep telefondan gordugum kadar cikis ayarlanmis tx cikis rx giris ayarlanmali.

elektra

ikiside giriş olarak ayarlıydı. şuan dediğiniz gibi tx çıkış rx giriş yaptım yine olmadı.

a.zorba

xc8 hangi versiyon u kullanıyorsun .
syntax ta  uyumsuz olabiliyor 

elektra

Teşekkürler daha yeni bakabildim kusura bakmayın. Sorunumu çözdüm belki başkalarının işine yarar. 16f690'da rx ucu aynı zamanda AN11 analog ucuna denk geldiği için mutlaka ANSELHbits.ANS11=0 biti bu şekilde dijital I/O olarak ayarlanmalı yoksa hiçbir şekilde haberleşme çalışmıyor.

Teşekkürler iyi çalışmalar...


Powered by EzPortal