SPI (Serial Peripheral Interface)

Atmega8 bir SPI (Serial Peripheral Interface) donanımına sahiptir. SPI veri iletişiminde işlemcinin MOSI(PB3), MISO(PB4), SCK(PB5) ve SS(PB2) bacakları kullanılmaktadır. SPI slave (yönetilen) ve master (yöneten) konumunda çalışır. Bu sayede bir master kendisine paralel olarak bağlanmış çok sayıda slave cihazı kontrol edebilir. SPI modülünde işlemci kristal hızının yarısına kadar, yani 16Mhz kristal hızında çalışan bir işlemcide 8Mhz'lik veri hızına erişilebilir.

Bu projede SPI modülünün nasıl çalıştığını göreceğiz. Piyasada bol miktarda bulacağınız Nokia 3310 ekranını SPI veri yolunu kullanarak kontrol edeceğiz. Ekranı kontrol etmeyi öğrendikten sonra önceki projelerde öğrendiğimiz üzere projeye bir LM35 sıcaklık sensörü ekleyerek şık bir termometre ya da DS1307 ekleyerek küçük bir masa saati yapabilirsiniz.

Nokia 3310 ekranları 3 voltta, Atmega8 ise el kitabına göre 5 voltta çalışmaktadır. Normal koşullarda ya Atmega8L sürümünü (düşük voltajla çalışan sürüm) bulmak zorunda kalacak ya da LCD'yi ve işlemciyi opto-kuplörlerle birbirlerinden izole edecektik. Ama bunlara gerek kalmayacak; çünkü Atmega8 düşük kristal hızlarında 3 voltda sorunsuz çalışıyor. Biz de Atmega8'i 1Mhz dahili kristal hızında çalıştırdığımız için devremizi doğrudan 3 voltda çalıştırabiliriz. ÖNEMLİ: Bu devrenin 3 Voltta çalıştırılması gerektiğini bir kez daha hatırlatmak isterim, devreye 5 Volt vermeniz halinde işlemcinize ve/veya Sıvı Kristal Ekrana zarar gelebilir.

Nokia 3310 Likit Kristal Ekran işlemciye Resim5'deki gibi bağlanır; farklı bir bağlantı yaparsanız, N3310.h başlık dosyasında gerekli değişiklikleri yapmayı unutmayın.

/*
* Cem Berik
* www.berik.net */

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "N3310.h"
#include "image.h"
#include "font.h"

const prog_uint8_t *Font;
const prog_uint8_t *Bitmap;
static void delay_ms(uint16_t ms){
for(uint16_t x=0;x<ms;x++){
_delay_ms(1);
}
}

static void glcdn_TestA(void){
glcdn_PutStrXLine("www.berik.net", 0, 1);
glcdn_PutStrXLine("abcdefghijklmn", 0, 2);
glcdn_PutStrXLine("opqrstuvwxyz", 0, 3);
glcdn_PutStrXLine("ABCDEFGHIJKLMN", 0, 4);
glcdn_PutStrXLine("OPQRSTUVWXYZ", 0, 5);
glcdn_PutStrXLine("0123456789", 0, 6);
}

int main(void){
Font=Font5x7;
Bitmap=resim;
glcdn_InitDisplay();
while(1){
glcdn_ShowImage(Bitmap);
delay_ms(3000);
glcdn_ClearLcd();
glcdn_TestA();
delay_ms(3000);
glcdn_ClearLcd();
}
}

Atmega8'in el kitabından da göreceğiniz üzere, SPI modülünü master olarak kullanmak için gereken fonksiyonlar şöyledir:

void SPI_MasterInit(void){
/* MOSI ve SCK çıkış, diğerleri giriş olsun */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* SPI modülünü etkinliştir, Master konumu, saat hızı fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData){
/* veri aktarımını başlat */
SPDR = cData;
/* aktarım tamalanıncaya kadar bekle */
while(!(SPSR & (1<<SPIF)));
}

SPI modülünün kullanımı için el kitabından SPCR, SPSR ve SPDR yazmaçlarının ayrıntılarını ve kullanımlarını öğrenmenizi tavsiye ederim.

Ana programımız son derece basittir, 3310 LCD ile ilgili tüm fonksiyonlar Thomas Weger tarafından yazılmış olan N3310.c ve N3310.h dosyalarında bulunmaktadır. Bir projedeki birden fazla dosyada kullanılacak olan değişkenlerin nasıl deklare edildiklerine dikkat ediniz. Projemizde bu şekilde iki pointer bulunmaktadır: Program hafızasına tanımlanmış işaretsiz byte cinsinden Font ve Bitmap. Bu iki pointer programın o safhasında hangi fontun ve hangi resmin seçili olduğunu göstermektedir. Bu yüzden örneğin Font değişkeni hem main.c hem de N3310.c dosyaları tarafından tanınmalıdır. Bu gibi durumlarda, bir dosya içinde tanımlanan bir değişken, diğer dosyada extern ifadesi ile yeniden tanımlanır, böylece derleyici ikinci dosyada deklare edilen aynı isimdeki değişkenin başka bir C dosyasında tanımlandığını anlar.

Proje Dosyaları

Proje Dosyaları