UART Haberleşme Problemi

Başlatan SB7, 18 Şubat 2019, 00:04:45

SB7

Selamlar.
XC8 ile Uart haberleşmesi yapmaya çalışıyorum.Kullandığım denetleyici PIC 16f877a .Proteus/ISIS programıyla sonuçları gözlemlemeye çalışıyorum.Ancak virtual terminal ile baktığımda gönderdiğim karakterleri göremiyorum. Baud Rate hatası değil. 19200 baudda haberleşiyorum. Virtual terminal ayarlarındaki baud kısmını 9600 yapınca sürekli "0" değeri okuyorum. Baud rate'i 19200 yapınca aşağıdaki resimdeki gibi oluyor.



pragma config FOSC = XT,  WDTE = OFF, PWRTE = OFF ,  BOREN = OFF, LVP = OFF, CPD = OFF ,WRT = OFF, CP = OFF

#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#define _XTAL_FREQ 4000000
#include "delay.h"
#include "lcd_driver.h"
#include "uart.h"

char a[10]="SB7 = ";
void main(void) {
    TRISB=0x00;
    TRISC=0xF0; // USART pinleri giri? olarak kabul ediliyor
    PORTB=0x00;
    
    lcd_init(); // LCD ilk ayarlar? yap?l?yor
 uart_init(); // USART ilk ayarlar? yap?l?yor
 
 lcd_yaz("  SB7");
 lcd_gotoxy(2,1);
 lcd_yaz("  LCD / USART");
 DelayMs(250);DelayMs(250);DelayMs(250);DelayMs(250);
 lcd_clear();
       
    while(1)
    {
        
        uart_yaz(a);
        DelayMs(250);
    }
}
kodlarım bu şekilde kullandığım uart.c dosyası da budur

#include <xc.h>
#include "uart.h"

void uart_init(void)
{
 unsigned char speed,nine_bits;
 unsigned int divider;
 
 RX_PIN = 1; // Seri iletiþim pinleri giriþ olarak tanýmlanýyor
 TX_PIN = 1;
 
 if(HIGH_SPEED==1) // Hýzlý iletiþim yapýlacaksa
 speed=0x4;
 else // Yaval iletiþim yapýlacaksa
 speed=0x00;
 
 if(NINE==1) // 9 bitlik iletiþim yapýlacaksa
 nine_bits=0x04;
 else // 8 bitlik iletiþim yapýlacaksa
 nine_bits=0x00;
 
 SPBRG = DIVIDER; // Hýz deðeri SPBRG'ye yükleniyor
 RCSTA = (nine_bits|0x90); // Alým kaydedicisi ayarlanýyor
 TXSTA = (speed|nine_bits|0x20); // Gönderim kaydedicisi ayarlanýyor
}

void uart_yaz(unsigned char byte) 
{
 // Tek byte gönder
 while(!TXIF); // Transfer tamponu boþ mu
 
 TXREG = byte; // Tek byte gönderiliyor
}

unsigned char uart_oku(void) 
{
 // Tek byte al
 while(!RCIF); // Alým tamponu boþ mu
 if(OERR) //hata varmý
 {
 CREN=0;
 CREN=1;
 }
 if(FERR)
 asm("MOVF _RCREG,W");
 return RCREG; // Tek byte alýnýyor
}

uart.h:

/*					SB7
 * 				USART Kullaným Klavuzu
 * usart_init(); ile USART'ýn ilk ayarlarýný yap
 * putch('A'); þeklinde tek byte veri gönder
 * A=getch(); ile tek byte'lýk veri al
 *					www.FxDev.org 
*/

#ifndef _XTAL_FREQ   //Kristal hýzý
    #define _XTAL_FREQ 4000000
#endif	

#define BAUD 19200		//Boudrate
#define NINE 0     		//9 bit iletiþim kullanýlacaksa 1 yapýlmalý
#define HIGH_SPEED 1	//Hýzlý iletiþim yapýlacaksa 1 yapýlmalý

#define RX_PIN RC7	//Seri port pinleri
#define TX_PIN RC6

#define DIVIDER 	((unsigned char)((_XTAL_FREQ/(16 * BAUD)) -1)) //baðlantý hýzýný hesapla

extern void uart_init(void);
extern void uart_yaz(unsigned char byte);
extern unsigned char uart_oku(void);

Sorun sizce nerde?

İkinci sorum: stdio.h kütüphanesini eklememe rağmen printf,getch,putc gibi fonksiyonları çalıştıramıyorum. Önceki denemelerimde conio.h kütüphane hatası alıp derleyemiyordum ancak şuan derleniyor ama çalışmıyor.
@sigmoid in XC8 konu başlığında sabitlediği uart.c de şöyle bir yapı kullanılmış

void putch(unsigned char byte)
{
 usart_yaz(byte);
}
bu yapıyı da kullanınca conio.h hatası alıyorum. Bu fonksiyonları uarta nasıl yönlendirebilirim?
-SB7

RaMu

uart_yaz fonksiyonu 1 byte veri gönderecek şekilde yazılmış,
kodundaki kullanımına bakınca böyle bir sonuç alman çok doğal.


uart_yaz(a);
yerine

i=0;
while(a[i] =! null)
{
uart_yaz(a[i]);
i++
}

yada basitçe şöyle deneyebilirsin:
uart_yaz('D');
uart_yaz('E');
uart_yaz('N');
uart_yaz('E');

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

SB7

#2
@RaMu  hocam cevabınız için teşekkürler.Yazdığınız iki yöntemi de denedim ancak sadece gelen simgeler farklılaştı. Baud ve osilatör frekanslarıyla oynadım simgeler sürekli değişim gösterdi. Örneğin XTAL 20MHz olunca sürekli 3 yazıyor. Baud 9600 olunca sürekli 0 yazıyor. Başka kombinasyonlarda da yine attığım resimdeki gibi simgeler geliyor.
Ayrıca printf,putc vs. fonksiyonlarıyla ilgili yorumunuzu da merak ediyorum.
-SB7

SB7

Sorum güncel. Printf fonksiyonunu lcd veya uarta nasıl yönlendirebilirim?
-SB7

Mucit23

STM32F10x için kullanmış olduğum printf fonksiyonu aşağıdaki gibi

/*----------------------------------------------------------------------------
 * Name:    Retarget.c
 * Purpose: 'Retarget' layer for target-dependent low level functions
 * Note(s):
 *----------------------------------------------------------------------------
 * This file is part of the µVision/ARM development tools.
 * This software may only be used under the terms of a valid, current,
 * end user licence from KEIL for a compatible version of KEIL software
 * development tools. Nothing else gives you the right to use this software.
 *
 * This software is supplied "AS IS" without warranties of any kind.
 *
 * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
 *----------------------------------------------------------------------------*/

#include <stdio.h>
#include <rt_misc.h>
#include "stm32f1xx_hal.h"
#include "usart.h"

#pragma import(__use_no_semihosting_swi)


extern int sendchar (int c);
extern int getkey   (void);


struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;


int fputc(int c, FILE *f) {
	uint8_t b[1];
	b[0]=c;
	HAL_UART_Transmit(&huart1, b, 1, 10);
  return (c);
}


int fgetc(FILE *f) {
  //return (getkey());
	return 0;
}


int ferror(FILE *f) {
  /* Your implementation of ferror */
  return EOF;
}


void _ttywrch(int c) {
  uint8_t b[1];
	b[0] = c;
	HAL_UART_Transmit(&huart1, b, 1, 10);
}


void _sys_exit(int return_code) {
label:  goto label;  /* endless loop */
}

Bu kodlar üzerinde gerekli düzenlemeleri yaptıktan sonra printf.c olarak proje dosyanıza ekleyip derleyin.

int fputc(int c, FILE *f) fonksiyonunun içeriğini kendi uart fonksiyonlarınıza göre güncellemelisiniz.

SB7

Teşekkürler @Mucit23 . Daha önce sizden bu dosyayı almıştım. Foruma yazmadan önce denedim sizin dediğinizi ancak struct yapıları biraz faklı olduğundan port edememiştim.
Sorun başka yerdeymiş.Kullandığım kütüphanede burda yazan değerin 16 olarak yazılmasıymış.
#define DIVIDER ((unsigned char)((_XTAL_FREQ/(16 * BAUD)) -1))
Bu kod satırını başka bir kütüphaneden gördüğüm
#define DIVIDER ((unsigned char)((_XTAL_FREQ/(16UL * BAUD)) -1))
satırıyla değiştirince sorun düzeldi.
Ayrıca uart.c de bu kod bloğunu yazıp uart.h da bu fonksiyonu da tanıttım.
void putch(char data)
{
  while(!TXIF);
TXREG = data;
}

Hem normal veri gönderimi hem de printf fonksiyonu çalıştı. Cevaplar için teşekkürler.

-SB7