Elektronik Hobi Devreleri

Taşınabilir UART Veri Alıcısı / Test Cihazı

Evrensel Asenkron Alıcı / Verici (UART) mikrodenetleyicide kullanılan en yaygın noktadan noktaya (eş) seri iletişim arayüzüdür. İki gömülü cihaz arasında seri veri iletimi için saat sinyali veya herhangi bir ana cihaz gerektirmeyen basit bir iki kablolu arayüzdür. Hata tespiti için bir eşlik bitinin sağlanmasıyla değişken uzunluktaki (5 ila 9 bit) veri paketlerini iletebilir. Bu nedenle, hemen hemen tüm mikroişlemcilerde USART veya en azından UART çevre birimi yerleşik vardır. 

UART iletişiminde, iki cihaz verileri doğrudan birbiriyle iletir. Bu veri iletişimi simpleks (bir cihazın alıcı, diğerinin verici olduğu yerlerde), tam çift yönlü (her iki cihazın aynı anda birbirine veri alıp gönderdiği) veya yarı çift yönlü (her iki cihaz birbirine veri gönderip alabilir) olabilir. her seferinde bir tane). UART çevre birimine sahip bir cihaz, doğrudan (her iki cihaz da TTL mantık seviyelerinde çalışıyorsa) veya bir seri sürücü yongası aracılığıyla (bir veya her iki cihaz da TTL’den başka sinyal seviyelerinde çalışıyorsa) UART çevre birimine sahip başka bir cihazla iletişim kurabilir. Seri sürücü protokolleri, uzun süreli veri iletişimini kolaylaştırmak için geliştirilmiştir. En sık kullanılan üç UART seri sürücü protokolü vardır – 


1-) RS-232

RS-232 seri sürücü protokolünde -25 V ila + 25V aralığında bir voltaj sinyali -25 V ila -3V sinyalinin YÜKSEK mantığa eşdeğer olduğu (bit durumu 1) veri iletişimi için kullanılır ve +3 V ila + 25V sinyal, LOW mantığına eşittir (bit durumu 0). RS-232 sürücü yongası (MAX232 gibi), bu voltaj seviyelerini (bir PC’den gelen gibi) UART çevre birimine sahip (bir mikrodenetleyici gibi) bir TTL cihazına iletmek için TTL voltaj seviyelerine (0 – 5V) dönüştürür. Sürücü çipi ( MAX-232 gibi) benzer şekilde UART çevre birimine sahip (bir mikrodenetleyici gibi) TTL cihazından TTL mantık seviyelerinde bitleri alır ve bunları RS-232 arayüzlü (PC gibi) cihaza iletmek için RS-232 standart sinyal seviyelerine dönüştürür. RS-232, tam dubleks noktasının iki cihaz arasında UART iletişimini göstermesini sağlar. RS-232 sürücü yongası, RS-232 portu veya bir cihazın arayüzü ile arabirim oluşturmak için en az üç kablo (Tx, RX ve Ortak Toprak) kullanır. RS-232 protokolünde, bir UART vericisi yalnızca bir UART alıcısına veri iletebilir.       


2-) RS-422

RS-422 seri sürücü protokolünde, veri iletişimi için -6 V ila + 6V aralığında voltaj sinyali kullanılır, burada -6 V ila -2V sinyali YÜKSEK mantığa eşittir (bit durumu 1) ve +2 V ila + 6V sinyali LOW mantığına eşittir (bit durumu 0). RS-422 sürücü yongası, bu voltaj seviyelerini, UART çevre birimine sahip TTL cihazına aktarım için TTL voltaj seviyelerine (0 – 5V) dönüştürür. 

Sürücü çipi benzer şekilde TTL mantık seviyesindeki bitleri, UART çevre birimine sahip TTL cihazından RS-422 arayüzüne sahip cihaza iletmek için RS-422 standart sinyal seviyelerine dönüştürür. RS-422, iki cihaz arasında tam çift yönlü ve yarı çift yönlü UART iletişimine izin verir. RS-422 protokolü daha iyi sinyal-gürültü özelliğine sahip uzun menzilli veriler sunmak için diferansiyel sinyalleri (iletim için iki hat üzerinde iki ters çevrilmiş sinyal ve ayrıca son cihazda veri alımı) kullanır. 

Bu nedenle, RS-422 sürücü yongası bir cihazın RS-422 portuna bağlanmak için en az 5 kablo kullanır (iki Tx, iki Rx ve ortak toprak). RS-422 protokolünde bir UART vericisi, verileri iki UART alıcısına iletebilir.  


3-) RS-485

RS-485, RS-422 protokolünün yarı çift yönlü versiyonudur. Genel olarak, RS-422 sürücü yongaları ayrıca RS-485 modunda da çalışabilir. RS-485 protokolünde, bir UART vericisi birçok UART alıcısına veri iletebilir. 

UART çevre birimlerine sahip cihazlar, verileri eşzamansız olarak iletir. Herhangi bir saat sinyali kullanmak yerine, bir başlangıç ​​biti ile başlayan ve bir durdurma biti ile biten bir veri paketinde UART çevresel çerçeve verisine (5b ila 9bit uzunluğunda) sahip cihazlar. UART alıcısı başlangıç ​​bitini tespit ettiğinde, veri paketlerini baud hızı adı verilen önceden belirlenmiş bir frekansta almaya başlar. Baud hızı, saniye başına iletilen veri paketleri veya sözcükler anlamına gelen saniye başına baudlar olarak ifade edilir. 

İdeal olarak, UART çevre birimleri aracılığıyla veri ileten iki cihaz aynı baud hızına sahip olmalıdır. UART çevre birimleri, baud oranlarındaki maksimum yüzde 10 toleransı yönetebilir. Veri iletişiminde herhangi bir hatayı tespit etmek için UART veri paketine isteğe bağlı bir eşlik biti gönderilebilir. Veri paketleri, aşağıdaki şekilde gösterildiği gibi UART cihazları tarafından çerçevelenmiştir – 


Şekil 1: UART Seri Protokolünde Veri Paketinin Formatı

Bu projede, bir UART vericisinden veri okuyabilen (500 bayta kadar) ve kullanıcının karakter LCD’sinde iletilen verileri incelemesine izin veren taşınabilir bir cihaz tasarlanmıştır. Kullanıcı, UART vericisiyle eşleşmesi için baud hızını, bir dizi veri bitini, eşliği ve cihazdaki durdurma bitini ayarlayabilir. Kullanıcı, ekranda doğru veri paketleri gözlenene kadar bu parametreleri cihaz üzerinde ayarlayabilir. Bu şekilde, bir kullanıcı baud hızını, veri bitlerinin sayısını, UART vericisinin parite ve durma bitini tanımlayabilir ve aynı parametreleri yapılandırılmamış bir UART alıcısına ayarlayabilir.    

Genellikle, USART iletimini mikrodenetleyici tabanlı bir gömülü aygıttan kontrol etmek için, denetleyiciden gelen Rx ve Tx pimleri bir PC’nin COM PORT’una bir seri sürücü yongası (RS-232 protokolü için MAX232 gibi) ile bağlanır. Ardından, veri iletimini kontrol etmek için HyperTerminal gibi programlar kullanılır. Bu yöntemde, bilgisayar ekranında yazdırılamayan karakterleri kontrol etmek / tanımlamak yine de zordur. Bu projede tasarlanan cihaz, yazdırılamayan karakterlerin kolay tanımlanması için okunan veri paketlerini karakter LCD’sinde bir metin, onaltılık, ondalık ve sekizli formatlarda gösterir. Bu cihaz ayrıca, alıcı cihazın düzgün çalışıp çalışmadığını belirlemek için bir UART alıcısına sabit bir veri paketi akışını (A-to-Z karakterlerini içeren bir test dizesi ve 0’dan 9’a kadar rakamlar) iletme yeteneğine de sahiptir. 

Bu cihaz AVR ATMega8 mikrodenetleyici kullanılarak tasarlanmıştır. 

ATMega8 programlanabilir Seri USART’a sahiptir, böylece diğer herhangi bir mikrodenetleyicinin UART veya USART çevre birimi ile kolayca iletişim kurabilir. ATMega8, inceleme için bir UART vericisinden 500 bayta kadar seri veri toplamak için kullanılan 512 bayt dahili EEPROM’a sahiptir. Alınan UART veri paketlerini görüntülemek ve incelemek için 20X4 karakter LCD ekran ATMega8 ile arayüzlendi.  

Bu cihazın endüstriyel bir ortamda kullanılması amaçlanmıştır, bu nedenle ATMega8, MAX485 seri sürücü çipiyle arayüzlenmiştir. MAX485, RS-422 veya RS-485 arayüze sahip cihazlarla UART iletişimi için kullanılabilen bir UART seri sürücü yongasıdır. Cihaz ayrıca bir TTL cihazının USART / UART arayüzü ile de doğrudan iletişim kurabilir (diğer mikro kontrolörler gibi). RS-232 arayüzlü cihazlardan gelen verileri okumak için, MAX-232 harici olarak bu cihazla arayüzlenmelidir.   


Gerekli Bileşenler;

Bileşen AdıMiktar
Atmega8 veya Atmega8A Mikro Denetleyici1
MAX485 Entegre1
20×4 Karakter LCD Ekran1
11.0592 Mhz Kristal Osilatör1
5kΩ Trimpot1
3mm LED3
Basmalı Düğme Anahtarı6
22pF Disk (Mercimek) Kondansatör2
0.1 uF Disk (Mercimek) Kondansatör2
10kΩ 0,25W Direnç7
4,7kΩ 0,25W Direnç1
3,3kΩ 0,25W Direnç1
2,2kΩ 0,25W Direnç2
470Ω Direnç1
100Ω Direnç 1
28-Pin Dip Soket1
8-Pin Dip Soket1
6 Pin Konektör1
Erkek Header (İng. Berg Strip) 1
Dişi Header 1
PCB veya Delikli Plaket1
AVR Programcısı1

Devre Şeması

Şekil 2: AVR ATmega8 Tabanlı Üniversal UART Veri Alıcısı ve UART Test Cihazının Devre Şeması

Devre Bağlantıları;

Bu cihaz AVR ATMega8’e dayanmaktadır. ATMega8, 16 MHz saatte 16 MIPS Çıkışa kadar çalışabilen 8 bitlik bir mikrodenetleyicidir. ATMega8, cihazı yapmak için 20X4 karakter LCD ve MAX485 Seri Sürücü Çipi ile arayüzlenmiştir. LCD’nin kontrastını ayarlamak için kullanılan bir Trimpot (devre şemasında VR1 olarak gösterilmiştir) vardır. 

Cihazın çalıştığını belirtmek için kullanılan tüm devreye paralel paralel bir Sarı LED vardır. Cihazın bir UART alıcısına test verileri gönderdiğini belirtmek için kullanılan Atmega8 Port D’nin 2. bitinde arabirim kırmızı bir LED vardır. ATMega8’nin D Port’unun 7. bitinde arabirimde, mikrokontrolörün aktif olduğunu ve yanıp sönerek bir menü düğmesine basılmasını beklediğini gösteren beyaz bir LED var.Kullanıcı girişi için ATMega8’in B portunda arayüzlü 6 adet buton düğmesi vardır. 

Cihaz iki modda çalışabilir –

1) Baud hızını, veri bitlerini, pariteyi ve biti durdurmayı gösteren Menü Modu ve

2) Alınan veri paketlerini bir UART vericisinden arabelleğinde görüntüleyen Görüntü Modu. Basmalı düğme anahtarları modu değiştirmek ve cihazı iki modda çalıştırmak için kullanılır. Basmalı düğmeler mikrodenetleyici pimlerinde altı çekme direnci ile birbirine bağlanır.  

Seri Veri ayarları ve kontrolü bu altı basma düğmeyi kullanarak çalıştırılabilir (devre şemasında SW1 – SW6 olarak gösterilmiştir). B portunun 5 bitinde (devre şemasında SW6 olarak gösterilir) arabirimde bulunan düğme, Görünüm modu ile Menü modu arasında geçiş yapmak için kullanılan bir geçiş anahtarıdır. SW2, SW3, SW4 ve SW5 basma düğmelerinin her iki modda da farklı işlevleri vardır. SW1, yalnızca bir UART alıcısına test verileri göndermek için VIEW MODE’da çalışır.   

ATmega8’in Rx ve Tx pinleri, herhangi bir mikrodenetleyicinin USART / UART veri iletiminden veri paketleri almak için kullanılabilir. ATmega8’in Rx ve Tx pimi de MAX485 Seri Sürücü IC ile arayüzlenir. MAX485, UART verilerini RS-485 veya RS422 arayüzü olan herhangi bir cihazdan alabilir. RS-485 ve RS-422, endüstrilerde kullanılan en yaygın kullanılan seri iletişim protokolleridir. RS-232 arayüzünden UART verileri almak için, bu cihazın harici olarak MAX232 IC ile arayüzlenmesi gerekir.    

Tüm devre, 7805 IC kullanarak 5V ayarlı güç kaynağıyla 5V güç bankasından veya 9V pilden elde edilebilen 5V DC üzerinde çalışır. Test sırasında doğru baud hızına sahip olmak için ATmega8 ile 11.0592 MHz frekansında bir kristal kullanılır. 


Devre nasıl çalışıyor ?

Devrenin montajından sonra, ATmega8’in ISP portu herhangi bir AVR programlayıcısına bağlanmalı ve mikrodenetleyicide SerialDataTester.HEX dosyası flash lanmalıdır . Ardından, devreyi AVR programlayıcısından ayırın. Şimdi cihaz çalışmaya hazır.  

Cihaz AÇIK duruma getirildiğinde, Flaşör LED’i ve RX-MODE LED’leri bir süre yanar ve LCD, projenin Başlığını ve mevcut USART ayarlarını göstermeye başlar. Birkaç saniye sonra, bir UART vericisinden veri alınmadıysa, LCD NO DATA veya BUFFER EMPTY mesajı görüntüler.  

Artık cihaz, bir UART vericisinden seri verileri test etmek veya örnek veri paketleri göndererek bir UART alıcısını test etmek için kullanılabilir. SW1 – SW6 basma düğmeleri Görünüm modu ve Menü modunda gezinmek için kullanılabilir. Görünüm modu, bir UART vericisinden alınan seri verileri gösterirken, Menü modu UART ayarlarının ince ayar yapmasına izin verir. 

1)Menü Modu

Bir UART vericisinden seri verilerin test edilmesi için, öncelikle kullanıcının, UART ayarlarını cihazda yapması gerekir. Veri paketlerini doğru almak için baud hızı, veri bitlerinin sayısı, cihazın parite ve durma bit ayarları UART vericisiyle aynı olmalıdır. Beklenen baud hızı, veri bitlerinin sayısı, parite ve durdurma bitinin menü moduna gidilerek ayarlanması gerekir. Kullanıcı, SW6 düğmesine basarak menü moduna girebilir. 

Düğmeye basıldığında, LCD, geçerli değerlere sahip parametreleri (Baud Hızı, Veri bitleri, Parite ve Durdurma Uçları) olan USART menüsünü görüntüler. Bir parametre seçmek için SW4 düğmesine basılmalıdır. Seçilen parametre yanıp sönen imleç ile gösterilir. 

Parametre değerini değiştirmek için, SW5 düğmesine seçilen parametreye karşı basılmalıdır. Parametreler SW4 ve SW5 düğmeleri kullanılarak istenen değerlerle ayarlanabilir. Parametreler ayarlandıktan sonra, değerleri SW3 düğmesine basılarak kaydedilebilir. Bu değerler, mikro denetleyicinin dahili EEPROM’una kalıcı olarak kaydedilir. 

Değerleri değiştirmek için, gerekirse, kullanıcının bir kez daha SW6 düğmesine basarak menü moduna gitmesi gerekir. Baud hızı, veri bitleri, parite ve durma biti için varsayılan parametre ayarları sırasıyla 9600, 8, 0 ve 1’dir. Kullanıcı SW2 düğmesine basarak varsayılan USART ayarlarına (9600, 8, 0, 1) sıfırlayabilir. Baud hızı, veri bitleri, parite ve durma biti için varsayılan parametre ayarları sırasıyla 9600, 8, 0 ve 1’dir. Kullanıcı SW2 düğmesine basarak varsayılan USART ayarlarına (9600, 8, 0, 1) sıfırlayabilir. 

Baud hızı, veri bitleri, parite ve durma biti için varsayılan parametre ayarları sırasıyla 9600, 8, 0 ve 1’dir. Kullanıcı SW2 düğmesine basarak varsayılan USART ayarlarına (9600, 8, 0, 1) sıfırlayabilir.

2) Görüntüleme Modu

Alınan seri verileri görüntülemek için varsayılan moddur. Menü modundan Görünüm moduna geçmek için, kullanıcının bir kez daha SW6 tuşuna basması veya herhangi bir tuşa basmadan 10 saniye beklemesi gerekir. Görünüm modunda, alınan verilerin dört veri paketi, LCD karakterinin dört satırında gösterilir. Her satır, arabellekte alınan seri veri paketinin konumu, karakteri, onaltılık kodu, ondalık kodu ve sekizlik kodundan oluşur. Alınan veri paketi yazdırılabilir bir karakter değilse, karakter yerinde bir nokta görüntülenir. ATmega8 512 bayt yerleşik EEPROM’a sahip olduğundan, tamponun maksimum boyutu 500 bayta ayarlanır. Alınan toplam bayt sayısı (tamponda) LCD’nin sol alt köşesinde görüntülenir. 

Görünüm modunda, alınan veri paketleri SW5 ve SW4 düğmelerine basılarak yukarı ve aşağı kaydırılabilir. SW3 düğmesine basıldığında, ekranda arabellekte alınan ilk veri paketindeki veriler gösterilir. SW2 düğmesine basıldığında, alınan arabellek silinir ve LCD ekranda “VERİ YOK veya BUFFER EMPTY” mesajı görüntülenir.  

3) Bir UART Alıcısının Test Edilmesi;

test etme – Bir UART alıcısını test etmek için, kullanıcının SW1 düğmesine basması gerekir. Bu düğmeye basıldığında, A-to-Z ve 0-to-9 karakterlerini içeren bir test dizisi, Tx pimi ve MAX485’in A ve B pimleri vasıtasıyla iletilir. Bu anahtara basıldığında alınan tampon yeni veri alımı için de silinir. Kırmızı LED kısa bir süre için yanar; bu, verilerin bir mikro kontrol cihazından UART alıcısına iletildiğinin bir göstergesidir.

Şekil 3: ATmega8 tabanlı UART Seri Veri Test Cihazının Menü Modunu gösteren resim
Şekil 4: ATmega8 Tabanlı UART Seri Veri Test Cihazının Görüntüleme Modunu Gösteren Görüntü

Programlama Rehberi

Bu cihaz AVR ATmega8’e dayanmaktadır ve AVR Studio 4 kullanılarak gömülü C ile programlanmıştır. Atmel Studio veya Notepad ++ gibi diğer programlama araçları da kodu yazmak ve derlemek için kullanılabilir. ATmega8, kullanıcıdan UART ayarlarını basma düğmeleri yoluyla almak ve buna göre bir UART vericisinden seri veri almak için programlanmıştır. 

Alınan veri tamponu, alınan veri paketlerinin yukarı ve aşağı kaydırılabildiği 20X4 karakter LCD ekranda görüntülenir. ATmega8 ayrıca herhangi bir UART alıcısını bir test dizesi göndererek test etmek için programlanmıştır.  

Kodda kullanılan sabitler

  • #define F_CPU 11059200L: – MCU’nun saat frekansını tanımlamak için kullanılan sabit.
  • #define F_CPU_BY_100 F_CPU / 100: – Baud hızı hesaplaması için frekansın 100’e bölünmesi. 
  • #define UMS 500: – Dizi için USART Mesaj Boyutu başlatma 
  • #define LCD_P PORTC: – LCD’yi arayüzlemek için C portu 
  • #define LCD_EN 0b00010000 : – C Portunun 4. pimine bağlı LCD’nin En pimi 
  • #define LCD_RS 0b00100000: – 5. Bağlantı Noktası C’ye bağlanan LCD’nin Rs pimi
  • #define BTN_SW6 0b00100000: – B bağlantı noktasının 5. pimine bağlı anahtar 6
  • #define BTN_SW1 0b00000001: – B Portunun 0ncı pimine bağlı 1 anahtarı.
  • #define BTN_SWS 0b00011110: – 4 iğneli anahtarı 2,3,4,5
  • #define BTN_SW5 0b00010000 : – B Portunun 4. pimine bağlı 5 anahtarı.
  • #define BTN_SW4 0b00001000: – B Portunun 3. pimine bağlı Anahtar 4.
  • #define BTN_SW3 0b00000100: – B Portunun 2. pimine bağlı Anahtar 3
  • #define BTN_SW2 0b00000010: – B Portunun 1. pimine bağlı 2. Anahtar
  • #define TX_L 0b00000100: – D bağlantı noktasının 2. pimine bağlı Tx LED  
  • #define TX_C 0b00001000: – MAX485’te RX veya TX modu etkinleştirme
  • #define BLK 0b10000000: – MCU’nun çalıştığını gösteren 7. D bağlantı noktasına bağlı yanıp sönen LED. 

Kodda kullanılan Değişkenler

  • unsigned char URD[UMS+1];  :– Bu Dizi USART’dan veri okumak için kullanılır
  • char USD[] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”; :– Bu dizi, USART’a veri göndermek için kullanılır
  • char HEX[16] = {‘0′,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9’, ‘A’,’B’,’C’,’D’,’E’,’F’}; :– Bu dizi alma verilerini hex’e dönüştürmek için kullanılır
  • int UBRL[12]={ 3, 6, 12, 24, 48, 96, 144, 192, 288, 384, 576, 768}; // X 100 :– değişecek baud oranları 
  • uint8_t U_B=5;       :– baud rate için typedef imzasız karakter 8bit
  • uint8_t U_D=8;      :– veri bitleri için typedef işaretsiz karakter 8 bit
  • uint8_t U_P=1;      :– parite için typedef imzasız karakter 8bit
  • uint8_t U_S=1;      :– Stop biti için typedef imzasız karakter 8 bit
  • unsigned char USART_RXD=0;  :– veri alımının değişken amacı 
  • int URDP = 0;            :– Pimden veri okumak için
  • int USDP = 0;            :– Pimden veri göndermek için
  • uint8_t USCH = 1;    :– USART verilerini güncellemek için
  • uint8_t VCCH = 1;    :– görünüm modunu güncellemek için

Başlık dosyası ve kodda kullanılan kütüphaneler;

  • #include <avr / io.h>: – Giriş / çıkış için standart AVR başlığı
  • #include <util / delay.h>: – Zaman gecikmeleri sağlayan standart AVR başlığı
  • #include <avr / interrupt.h>: – Kesintiler için standart AVR başlığı  
  • #include <avr / eeprom.h>: – EEPROM verisini kullanmak için standart AVR başlığı

Kodda kullanılan işlevler;

  • getString  : – LCD’de yazdırmak için dize işlemek
  • rdE            : – EEPROM’dan verileri okuyun
  • wrE            : – EEPROM’a veri yazmak
  • P_init        : – kullanım için portların başlatılması
  • LCD_E      : – LCD’nin E pinini etkinleştirir
  • LCD_WN : – RS modunu etkinleştirmek ve devre dışı bırakmak için
  • LCD_WCM : – Kablo komutlarına
  • LCD_init : – LCD’yi başlatmak için 
  • LCD_WC : – Karakter yaz 
  • LCD_WS : – Dize Yaz
  • LCD_CS : – Ekranı temizlemek için
  • LCD_POS : – İmleci duraklat 
  • USART_init: – USART’ı başlat 
  • USART_SC : – Karakter göndermek için
  • USART_SM : – Menü modunu ayarlamak için
  • ISR : – Veri almak için 
  • VUSCR : – Ekran kurulumunu görüntüle   
  • USART_UPD : – USART veri güncellemesi
  • USART_SD : -USART veri gönderme
  • USART_MN : – USART menüsü anahtarla değiştirilebilir
  • VWL : – tampon verilerini anahtarlarla kontrol eder 

Algoritma:

Bu taşınabilir UART veri alıcısı / test cihazının kodu aşağıdaki şekilde çalışır – 1) Seri veri test devresi çalıştırıldığında, her şeyden önce, B portunu giriş olarak, C portunu çıkış olarak ve D portunun 7 pinini çıkış olarak ayarlayan portlar başlatılır. Aynı zamanda LOW yapmak için sıfır biti ”TX_C, TX_L, LCD_RS, LCD_EN“ e geçirir. 

void P_init ( ) 
{
DDRB = 0x00;
DDRC = 0xFF;
DDRD = 0xFE;
PORTD &= (~TX_C);
PORTD &= (~TX_L);
LCD_P &= (~LCD_RS);
LCD_P &= (~LCD_EN ); 
}

2) Portların başlatılmasından sonra, TX_L LED ve BLK LED 2000 milisaniye boyunca açılır ve programın başladığını gösteren kapanır. 

PORTD |= BLK;
PORTD |= TX_L;
_delay_ms ( 2000 );
PORTD &= ~BLK;
PORTD &= (~TX_L); 

3) LCD başlatılır ve LCD’nin düzgün çalıştığını kontrol etmek için görüntülenen bir hoş geldiniz mesajı basar.  

LCD_init(  );
LCD_CS ( );
LCD_POS (1,1);
LCD_WS ( " SERIAL DATA TESTER ");
LCD_POS (2,1);
LCD_WS ( "====================");
LCD_POS (3,1);
LCD_WS ( "for USART & MAX485  ");
LCD_POS (4,1);
LCD_WS ( "      communications");

4) Şimdi menü modunu güncellemek için mevcut EEPROM değerlerini okur ve ardından USART’ta alınan arabellek değerini ayarlar.

_delay_ms ( 3000 );
rdE ( );
_delay_ms ( 100 );
USART_SM (  ); 
sei();
_delay_ms ( 2000 ); 

5) Bir süre döngü içinde, çalışmaya hazır olduğunu göstermek için yanıp sönen led yanar. Burada, USART verileri güncellenir ve görünüm modu LCD’de de güncellenir. Artık kullanıcı EEPROM’da tampon verilerini ve kaydedilmiş seri iletişim verilerini görebilir. 

if ( USCH )
USART_UPD ( );
if ( VCCH )
{
VUSCR ( );
_delay_ms ( 200 );
}

6) Görünüm modunda 1 düğmesine basıldığında, verileri USART’a gönderir. Kullanıcı verileri LCD’de ve bağlı bir bilgisayarın seri terminali gibi UART alıcısında görebilir.

if ( ( PINB & BTN_SW1 ) == 0 )
USART_SD ( );

7) 6 düğmesine basıldığında, kullanıcı baud hızını, veri bitlerini, eşliği ve bit biti ayarlarını değiştirebilmesi için menü modunu görüntüler. 6 düğmesine tekrar basıldığında, arabellek verilerinin gösterildiği modu görüntülemek için cihazı menü modundan değiştirir. 

if ( ( PINB & BTN_SW6 ) == 0 )
isMenuPressed = 1;
if ( isMenuPressed )
{
USART_MN ( );
LCD_WCM ( 0x0C ); 
}
else
VWL ( );

Kodun tamamını inceleyin ve bu heyecan verici projeyi hemen oluşturmaya başlayın. 
//Program to
/*
filename : SerialDataTester.C
author : fhn
Dtd : 22-mar-2018
MCU : ATmega8 (A) @ 11.0592 MHz
display ; LCD 4 rows X 20 columns
others: menu driven
buttons : 6
*/

#define F_CPU 11059200L
#define F_CPU_BY_100  F_CPU/100
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#define UMS 500  
#define LCD_P PORTC
#define LCD_EN   0b00010000 
#define LCD_RS   0b00100000  
#define BTN_SW6 0b00100000 
#define BTN_SW1 0b00000001 
#define BTN_SWS 0b00011110 
#define BTN_SW5 0b00010000 
#define BTN_SW4 0b00001000 
#define BTN_SW3 0b00000100 
#define BTN_SW2 0b00000010  
#define TX_L 0b00000100  
#define TX_C 0b00001000  
#define BLK 0b10000000  

//=============================================================================

unsigned char URD[UMS+1];
char USD[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char HEX[16] = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F'};
int UBRL[12]={ 3, 6, 12, 24, 48, 96, 144, 192, 288, 384, 576, 768}; // X 100
uint8_t U_B=5;
uint8_t U_D=8;
uint8_t U_P=1;
uint8_t U_S=1;
unsigned char USART_RXD=0;
int URDP = 0;
int USDP = 0;
uint8_t USCH = 1;
uint8_t VCCH = 1;

//=============================================================================

void getString ( long val, char *str, char fc, int width ) 
{
long v=val,i=0;
int nst=0, p=0;
long hvl=1;
for ( int w=0; w<width; w++ )
hvl *= 10;
v = v % (hvl);
for ( i=hvl/10; i>=1 ; i=i/10 )
{
if( (v/i)>=1 && nst==0 )
nst = 1;
if ( nst==1 )
{
str[p++] = (v/i) + '0';
}
else
{
str[p++] = fc; 
}
v = v%i;
}

str[p]=0;
if (str[p-1]==' ')
{ str[p-1]='0'; }
}

//=============================================================================

void rdE ( )
{
int rval = 0;
rval = eeprom_read_byte ( (void *)1); 
if ( rval<1 || rval>2 )
return;
U_S = rval;
rval = eeprom_read_byte ( (void *)2);
if ( rval<0 || rval>2 )
return;
U_P = rval;
rval = eeprom_read_byte ( (void *)3); 
if ( rval<5 || rval>8 )
return;
U_D = rval;
rval = eeprom_read_byte ( (void *)4); 
if ( rval<0 || rval>13 )
return;
U_B = rval;
}

//=============================================================================

void wrE ( )
{
eeprom_write_byte ( (void *)1, U_S); 
_delay_ms(10);
eeprom_write_byte ( (void *)2, U_P ); 
_delay_ms(10);
eeprom_write_byte ( (void *)3, U_D); 
_delay_ms(10);
eeprom_write_byte ( (void *)4, U_B);; 
_delay_ms(10);
}

//=============================================================================

void P_init ( ) 
{
DDRB = 0x00;
DDRC = 0xFF;
DDRD = 0xFE;
PORTD &= (~TX_C);
PORTD &= (~TX_L);
LCD_P &= (~LCD_RS);
LCD_P &= (~LCD_EN ); 
}

//=============================================================================

void LCD_E ( )
{
LCD_P |= LCD_EN; 
_delay_us(10);
   LCD_P &= (~LCD_EN ); 
   _delay_us(15);
}

//=============================================================================

void LCD_WN ( unsigned char nibl , unsigned char RS)
{
LCD_P &= 0xF0;  
_delay_us(5);
if ( nibl > 0b00001111)
LCD_P |= ( (nibl>>4) & 0x0F);   
else
LCD_P |= (nibl & 0x0F); 
if (RS)
LCD_P |= LCD_RS;
else
LCD_P &= (~LCD_RS);
LCD_E ( );
}

//=============================================================================

void LCD_WCM ( unsigned char cmd )
{
LCD_WN ( cmd & 0xF0 , 0);
LCD_WN ( cmd & 0x0F , 0);
_delay_us(2);
}

//=============================================================================

void LCD_init(  )
{
unsigned char initval = 0x20; 
_delay_ms ( 50 ); 
LCD_WN  ( 0x30 , 0);
_delay_ms ( 20 );
LCD_WN ( 0x30 , 0);
_delay_us ( 200 ); 
LCD_WN  ( 0x30 , 0);
_delay_ms ( 100 );
LCD_WN  ( 0x20 , 0 );
_delay_ms ( 25 );
initval |= 0b00001000;  
initval |= 0b00000100;  
LCD_WCM ( initval ); 
_delay_ms ( 25 );
LCD_WCM ( 0x0C ); 
_delay_ms ( 25 );
LCD_WCM ( 0x06 ); 
_delay_ms ( 250 );
}

//=============================================================================

void LCD_WC ( unsigned char c )
{
LCD_WN ( c & 0xF0 , 1);
LCD_WN ( c & 0x0F , 1);
_delay_us(1);
}

//=================================================

void LCD_WS ( char s[] )
{
for (int i=0; s[i]!=0; i++)
{
LCD_WC ( s[i] );
_delay_us ( 5 ); 
}
}

//=============================================================================

void LCD_CS ( )
{
LCD_WCM ( 0x01 );
_delay_ms(3);
}

//=================================================

void LCD_POS ( unsigned char R, unsigned char C )
{
switch (R)
{
case 3: LCD_WCM ( 0x94 + C-1 );  break;
case 4: LCD_WCM ( 0xD4 + C-1  ); break;
case 2: LCD_WCM ( 0xC0 + C-1 ); break;
case 1:
default: LCD_WCM ( 0x80 + C-1 ); break;
}
_delay_ms ( 3 );
}

//=============================================================================

int USART_init ( int bd, int db, int prt, int stb)
{
int ubrr = 0;
int bd_rate=bd;  
unsigned int ucsrc = (1<<URSEL);
ubrr   = (int)( F_CPU_BY_100 / (8*bd_rate) ) -1;
UCSRA |= (1<<U2X); 
if (ubrr>=0)
{
UBRRL = ubrr;
UBRRH = (ubrr>>8);
}
else
return (-1);
UCSRB = (1<<RXEN) | (1<<TXEN); 
UCSRB |= (1 << RXCIE);       
switch ( db )
{
case 5: break;
case 6: ucsrc |= (1<<UCSZ0); break;
case 7: ucsrc |= (2<<UCSZ0); break;
case 8: ucsrc |= (3<<UCSZ0); break;
default:  return (-1);
}
if (stb==2)  
ucsrc |= (1<<USBS);
if (prt==2) 
ucsrc |= (1<<UPM1);
if (prt==1) 
ucsrc |= (1<<UPM1) | (1<<UPM0);
UCSRC = ucsrc;  
return ( 0 );
}  

//=============================================================================

char USART_SC ( unsigned char ch )
{
while ( ! (UCSRA & (1<<UDRE) ) ) 
{
_delay_us ( 1 ); 
}
UDR = ch;
return ( 0 );
}

//=============================================================================

void USART_SM (  )
{
char str[10];
LCD_CS ( );
LCD_POS ( 1,1 );
LCD_WS ( "BaudRate : ");
LCD_POS ( 1,12 ); 
getString(UBRL[U_B], str,' ', 3); 
LCD_WS ( str ); LCD_WS ( "00" );
LCD_POS ( 2,1 ); 
LCD_WS ( "DataBits : "); 
LCD_POS ( 2,12 );
LCD_WC ( U_D+'0');
LCD_POS ( 3,1 );
LCD_WS ( "Parity   :  " );
LCD_POS ( 3,12 );
switch( U_P )
{
case 1: LCD_WS ( "ODD " );  break;
case 2: LCD_WS ( "EVEN" );  break;
default:LCD_WS ( "NONE" );  break;
}
LCD_POS ( 4,1 );
LCD_WS ( "StopBits :  " );
LCD_POS ( 4,12 );
LCD_WC ( U_S+'0');
LCD_POS ( 1,12 );
}

//=============================================================================

ISR ( USART_RXC_vect )
{
USART_RXD = UDR;  
if ( URDP < UMS )
{
URD[URDP++] = USART_RXD;
}
 }

//=============================================================================

void VUSCR ( )
{
char str[10];
LCD_CS ( );
if ( URDP<=0)
{
LCD_POS (2,1);
LCD_WS ( "NO DATA or" );
LCD_POS (3,1);
LCD_WS ( "BUFFER EMPTY" );
return;
}
for ( int i=0; i<4 && URDP>(USDP+i); i++ )
{
LCD_POS ( i+1 , 1 );
LCD_WC ( '@' );
getString(USDP+i, str,'0',3); 
LCD_WS ( str ); 
LCD_WS ( "= " );
if ( URD[USDP+i]<32 ||
URD[USDP+i]>126 )
LCD_WC ( '.' );
else 
LCD_WC ( URD[USDP+i] );
LCD_WC ( ' ' );
LCD_WC ( HEX[URD[USDP+i]/16] ); 
LCD_WC ( HEX[URD[USDP+i]%16] ); 
LCD_WS ( "h " ); 
getString(URD[USDP+i], str,'0',3); 
LCD_WS ( str ); 
LCD_WS ( "d " );
int n = URD[USDP+i];
LCD_WC ( n/64 + '0' ); 
n = n%64;
LCD_WC ( n/8 + '0' ); 
LCD_WC ( n%8 + '0' ); 
}
LCD_POS(4,1);
LCD_WC ( '[' );
getString(URDP, str,'0', 3); 
LCD_WS ( str ); 
LCD_WC ( ']' );
}

//=============================================================================

void USART_UPD ( )
{
USART_init ( UBRL[U_B],
U_D,
U_P,
U_S );
URDP=0;
USDP = 0;
VCCH = 1;
wrE ( );
rdE ( );
}

//=============================================================================

void USART_SD ( )  
{
LCD_CS ( );
PORTD |= BLK;
LCD_POS (1,1);
LCD_WS ( "SENDING.... " );
PORTD |= TX_C;
PORTD |= TX_L;
_delay_ms(10);
LCD_POS ( 2,1 );
for ( int i=0; USD[i]!=0 ;i++)
{
if ( i==18 )
LCD_POS ( 3,1 );
LCD_WC ( USD[i] );
USART_SC (  USD[i] );
_delay_ms(1);
}
_delay_ms(50);
PORTD &= (~TX_C);
LCD_POS (4,1);
LCD_WS ( "SENT (Check LSB)" );
_delay_ms(50);
PORTD &= (~TX_L);
_delay_ms(1500);
VCCH = 1;
}

//=============================================================================

void USART_MN ( )
{
uint8_t wtl = 100;
uint8_t btn_sws = 0;
uint8_t editpos = 0;
char str[10];
uint8_t sU_B = U_B;
uint8_t sU_D = U_D;
uint8_t sU_P = U_P;
uint8_t sU_S = U_S;
USART_SM (  );
_delay_ms ( 300 );
LCD_WCM ( 0x0F ); 
while ( wtl > 0)
{
PORTD ^= BLK;
LCD_POS (editpos+1,12);
btn_sws = PINB & BTN_SWS;
if ( btn_sws != BTN_SWS)
{
wtl = 100;
_delay_ms ( 300 );
if ( ( btn_sws & BTN_SW4 ) ==0 )
{
editpos++;
if (editpos>3)
editpos = 0;
_delay_ms ( 300 );
}
else if ( ( btn_sws & BTN_SW5 ) ==0 )
{
switch (editpos)
{
case 0:
sU_B++;
if (sU_B>11)
sU_B=0;
LCD_POS ( 1,12 ); 
getString(UBRL[sU_B], str, ' ', 3); 
LCD_WS ( str ); LCD_WS ( "00" );
break;
case 1:
sU_D ++;
if ( sU_D>8)
sU_D=5;
LCD_POS ( 2,12 );
LCD_WC ( sU_D +'0' );
break;
case 2:
sU_P++;
if ( sU_P>2)
sU_P=0;
LCD_POS ( 3,12 );
switch( sU_P )
{
case 1: LCD_WS ( "ODD " ); break;
case 2: LCD_WS ( "EVEN" ); break;
default:LCD_WS ( "NONE" ); break;
}
break;
case 3:
sU_S ++;
if ( sU_S>2)
sU_S=1;
LCD_POS ( 4,12 );
LCD_WC ( sU_S +'0' );
break;
default:
break;
}
}
else if ( ( btn_sws & BTN_SW3 ) ==0 )
{
U_B = sU_B;
U_D = sU_D;
U_P = sU_P;
U_S = sU_S;
USCH = 1;
USART_SM (  );
LCD_POS ( 4,15 );
LCD_WS ( "SAVED" );
_delay_ms ( 2000 );
return;
}
else if ( ( btn_sws & BTN_SW2 ) ==0 )
{
U_B = 5;
U_D = 8;
U_P = 1;
U_S = 1;
USCH = 1;
USART_SM (  );
LCD_POS ( 4,15 );
LCD_WS ( "RESET" );
_delay_ms ( 2000 );
return;
}
}
else
{
wtl--;
}
if ( ( PINB & BTN_SW6 ) == 0 )
{
wtl = 0;
_delay_ms ( 300 );
}
_delay_ms ( 100 );
}
VCCH = 1;
}

//=============================================================================

void VWL ( ) 
{
int btn_sws = 0;
PORTD ^= BLK;
btn_sws = PINB & BTN_SWS;
if (( btn_sws & BTN_SW2 ) == 0 )
{
URDP=0;
USDP = 0;
VCCH = 1;
_delay_ms ( 100 );
}
else if ( ( btn_sws & BTN_SW4 ) == 0 )
{
USDP += 3;
if ( USDP>=URDP)
USDP = URDP-1;
VCCH = 1;
_delay_ms ( 100 );
}
else if ( ( btn_sws & BTN_SW5 ) == 0 )
{
USDP -= 3;
if ( USDP<0)
USDP = 0;
VCCH = 1;
_delay_ms ( 100 );
}
else if ( ( btn_sws & BTN_SW3 ) == 0 )
{
USDP = 0;
VCCH = 1;
_delay_ms ( 100 );
}
}

//=============================================================================

int main ( )
{
int isMenuPressed = 0;
int usart_recd_data_pos = -1;
P_init ( );
PORTD |= BLK;
PORTD |= TX_L;
_delay_ms ( 2000 );
PORTD &= ~BLK;
PORTD &= (~TX_L);
LCD_init(  );
LCD_CS ( );
LCD_POS (1,1);
LCD_WS ( " SERIAL DATA TESTER ");
LCD_POS (2,1);
LCD_WS ( "====================");
LCD_POS (3,1);
LCD_WS ( "for USART & MAX485  ");
LCD_POS (4,1);
LCD_WS ( "      communications");
_delay_ms ( 3000 );
rdE ( );
_delay_ms ( 100 );
USART_SM (  );
USCH = 1;
VCCH = 1;
sei();
_delay_ms ( 2000 ); 
while ( 1 )
{
PORTD ^= BLK;
if (usart_recd_data_pos != URDP)
VCCH = 1;
usart_recd_data_pos = URDP;
if ( USCH )
USART_UPD ( );
if ( VCCH )
{
VUSCR ( );
_delay_ms ( 200 );
}
isMenuPressed = 0;
USCH = 0;
VCCH = 0;
_delay_ms ( 50 ); 
if ( ( PINB & BTN_SW1 ) == 0 )
USART_SD ( ); 
if ( ( PINB & BTN_SW6 ) == 0 )
isMenuPressed = 1;
if ( isMenuPressed )
{
USART_MN ( );
LCD_WCM ( 0x0C ); 
}
else
VWL ( );
}
return 0;
}

//=============================================================================

###

Bu makale buradan çevrilmiştir.

Related posts

Zamanlayıcı kullanarak Yağmur Alarmı

Ömer Ersin

VNA SSS: Giriş

Ömer Ersin

NodeMCU ile 4 cihaza kadar kontrol

Ömer Ersin