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.
(https://i.ibb.co/RzvfqSK/uart.jpg) (https://ibb.co/RzvfqSK)
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?
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');
@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.
Sorum güncel. Printf fonksiyonunu lcd veya uarta nasıl yönlendirebilirim?
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.
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.
(https://i.ibb.co/GVXDhW8/uart.jpg) (https://ibb.co/GVXDhW8)