|
PSoC CY8C27443-24PXI, DS1337
RTC ve TMP04 çipleri kullanılarak yapılmış dijital saat örneğidir. Saatin yanı
sıra tarih ve gün bilgileride LCD den okunabilir. Dijital saatin bir alarmı,
ortam seviyesine göre değişebilen ekran aydınlatması, TMP04 ile
gerçekleştirilmiş birde termometresi bulunmaktadır. Saatin tüm ayarları sadece 2
buton ile yapılır.
PSoC RTC örneğinde
7 adet dijital PSoC bloğu ve 2 adet analog PSoC bloğu kullanılmaktadır.
Dijital bloklardan
biri yaklaşık 2kHz üreten saat başı beep görevini üstlenen PWM bloğudur. Alarm
anında ise bir başka PWM bloğu üzerinden modüle edilerek kesik beep sesleri elde
edilir. Bir diğer PWM modülü ise ekram parlaklığını ayarlanması için
kullanılmıştır. LDR üzerinden alınan analog gerilim bilgisi bir analog blok olan
ve kazancı 1 olan PGA üzerinden diğer bir analog bloğu olan ADC a beslenir. ADC
çıkış değeri ekran parlaklığını ayarlayan PWM modülünün darbe boşluk oranını
belirler. Ayrıca ADC 1 analog blok kullandığı gibi 2 dijital bloğu da işgal
eder. Geriye kalan 2 dijital bloğu ise 16 bitlik bir sayıcı kullanır. TMR04
sensöründen gelen sıcaklık bilgisinin çözümlenmesi için kullanılır.


Kaynak kodları:
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
/*GPIO interruptini gerçeklestirmek için
-boot.tpl dosyasinda 1Ch adresine "ljmp PSoC_GPIO_ISR"
-psocgpioint.asm dosyasinda PSoC_GPIO_ISR: ve reti arasina "ljmp _PSoC_GPIO_ISR_C"
-main.c dosyasinda "#pragma interrupt_handler PSoC_GPIO_ISR_C" interrupt
fonksiyonunda ise
"void PSoC_GPIO_ISR_C()" ifadesini kullanın!!!
*/
//-----------------------------------------------------------------------------
#include <m8c.h>
#include "PSoCAPI.h"
#include <string.h>
#include <stdlib.h>
#pragma interrupt_handler PSoC_GPIO_ISR_C
char lcdclear=0;
char set=0;
char buffer[8];
float temperature;
float T1;
float T2;
BYTE rxBuf[8];
BYTE setBuf[];
BYTE almBuf[]={0x00,0x00,0x00,0x00}; //alarm saat, alarm dakika, alarm set,
alarm aktif
BYTE i; //geçici
değişken
const BYTE txCBuf[] = {
0x00, // DS1337 internal
sub-address
0x55,0x59,0x23, // saniye dakika saat
0x06, // haftanın günü
0x24,0x11,0x06, // gün ay yıl
0x93}; // Enable RTC
#define ALM_SET almBuf[2]
#define ALM_ACTIVE almBuf[3]
void PSoC_GPIO_ISR_C()
{
//string eşleme
setBuf[0]=0x00;
setBuf[8]=0x93;
for(i = 0; i < 6; i++) setBuf[i+1]=rxBuf[i];
if((PRT1DR&0x04)==4)
{
//ayarlar
//saat ayarı
if(set==1) {
setBuf[3]++;
if(setBuf[3]==0x0A) setBuf[3]=0x10;
if(setBuf[3]==0x1A) setBuf[3]=0x20;
if(setBuf[3]==0x24) setBuf[3]=0x00;
}
//dakika ayarı
if(set==2) {
setBuf[2]++;
if(setBuf[2]==0x0A) setBuf[2]=0x10;
if(setBuf[2]==0x1A) setBuf[2]=0x20;
if(setBuf[2]==0x2A) setBuf[2]=0x30;
if(setBuf[2]==0x3A) setBuf[2]=0x40;
if(setBuf[2]==0x4A) setBuf[2]=0x50;
if(setBuf[2]==0x5A) setBuf[2]=0x00;
}
//saniye ayarı
if(set==3) {
setBuf[1]++;
if(setBuf[1]==0x0A) setBuf[1]=0x10;
if(setBuf[1]==0x1A) setBuf[1]=0x20;
if(setBuf[1]==0x2A) setBuf[1]=0x30;
if(setBuf[1]==0x3A) setBuf[1]=0x40;
if(setBuf[1]==0x4A) setBuf[1]=0x50;
if(setBuf[1]==0x5A) setBuf[1]=0x00;
}
//haftanın günü
if(set==4) {
setBuf[4]++;
if(setBuf[4]==0x08) setBuf[4]=0x01;
}
//gün ayarı
if(set==5) {
//31 çeken aylar
if((setBuf[6]==0x01)||(setBuf[6]==0x03)||(setBuf[6]==0x05)||
(setBuf[6]==0x07)||(setBuf[6]==0x08)||(setBuf[6]==0x10)||(setBuf[6]==0x12))
{
setBuf[5]++;
if(setBuf[5]==0x0A) setBuf[5]=0x10;
if(setBuf[5]==0x1A) setBuf[5]=0x20;
if(setBuf[5]==0x2A) setBuf[5]=0x30;
if(setBuf[5]==0x32) setBuf[5]=0x01;
}
//30 çeken aylar
if((setBuf[6]==0x04)||(setBuf[6]==0x06)||(setBuf[6]==0x09)||(setBuf[6]==0x11))
{
setBuf[5]++;
if(setBuf[5]==0x0A) setBuf[5]=0x10;
if(setBuf[5]==0x1A) setBuf[5]=0x20;
if(setBuf[5]==0x2A) setBuf[5]=0x30;
if(setBuf[5]==0x31) setBuf[5]=0x01;
}
//28 çeken aylar
if(setBuf[6]==0x02)
{
setBuf[5]++;
if(setBuf[5]==0x0A) setBuf[5]=0x10;
if(setBuf[5]==0x1A) setBuf[5]=0x20;
if(setBuf[5]==0x29) setBuf[5]=0x01;
}
}
//ay ayarı
if(set==6) {
setBuf[6]++;
if(setBuf[6]==0x0A) setBuf[6]=0x10;
if(setBuf[6]==0x13) setBuf[6]=0x01;
}
//yıl ayarı
if(set==7) {
setBuf[7]++;
if(setBuf[7]==0x0A) setBuf[7]=0x10;
if(setBuf[7]==0x1A) setBuf[7]=0x20;
if(setBuf[7]==0x2A) setBuf[7]=0x30;
if(setBuf[7]==0x3A) setBuf[7]=0x40;
if(setBuf[7]==0x4A) setBuf[7]=0x50;
if(setBuf[7]==0x5A) setBuf[7]=0x00;
}
I2Cm_1_bWriteBytes(0x68, setBuf, 9, I2Cm_1_CompleteXfer);
lcdclear=1;
//alarm ayarı saat
if(set==8) {
almBuf[0]++;
if(almBuf[0]==0x0A) almBuf[0]=0x10;
if(almBuf[0]==0x1A) almBuf[0]=0x20;
if(almBuf[0]==0x24) almBuf[0]=0x00;
ALM_SET=0x01;
}
//alarm ayarı dakika
if(set==9) {
almBuf[1]++;
if(almBuf[1]==0x0A) almBuf[1]=0x10;
if(almBuf[1]==0x1A) almBuf[1]=0x20;
if(almBuf[1]==0x2A) almBuf[1]=0x30;
if(almBuf[1]==0x3A) almBuf[1]=0x40;
if(almBuf[1]==0x4A) almBuf[1]=0x50;
if(almBuf[1]==0x5A) almBuf[1]=0x00;
ALM_SET=0x01;
}
}
else set++;
// alarm çalma anında herhangi bir butona basılırsa alarmı sustur
if(ALM_ACTIVE==0x01) { ALM_SET=0x00; ALM_ACTIVE=0x00; PWM8_2_Stop(); set=0; }
if(set==10) set=0;
lcdclear=1;
return;
}
void main()
{
//modülleri başlat
PGA_1_Start(PGA_1_LOWPOWER);
ADCINC12_1_Start(ADCINC12_1_HIGHPOWER);
ADCINC12_1_GetSamples(0);
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
M8C_EnableGInt;
Counter16_1_EnableInt();
Counter16_1_Start();
PWM8_1_Start();
PWM8_3_Start();
LCD_1_Start();
LCD_1_Init();
//I2C haberleşmesi
I2Cm_1_Start();
I2Cm_1_bWriteCBytes(0x68, txCBuf, 9, I2Cm_1_CompleteXfer);
//sonsuz döngü
do{
I2Cm_1_bWriteCBytes(0x68, txCBuf, 1, I2Cm_1_NoStop);
I2Cm_1_fReadBytes(0x68, rxBuf, 7, I2Cm_1_RepStart);
I2Cm_1_fSendStart(0x68, I2Cm_1_WRITE);
I2Cm_1_fWrite(0x00);
I2Cm_1_fSendRepeatStart(0x68, I2Cm_1_READ);
for(i = 0; i < 6; i++)
{
rxBuf[i] = I2Cm_1_bRead(I2Cm_1_ACKslave);
}
rxBuf[7] = I2Cm_1_bRead(I2Cm_1_NAKslave);
I2Cm_1_SendStop();
//LCD ye yazmaya başla
if((set==1)||(set==2)||(set==3)||(set==8)||(set==9)) LCD_1_Position(0, 3);
else LCD_1_Position(0, 1);
//zamanı yaz
for(i=0;i<3;i++)
{
if(((set==1)||(set==8))&&(i==0)) LCD_1_PrCString("[");
if(((set==2)||(set==9))&&(i==1)) LCD_1_PrCString("[");
if((set==3)&&(i==2)) LCD_1_PrCString("[");
//if(rxBuf[2-i]<10) LCD_1_PrCString("0");
if(set==8||set==9) {if((almBuf[i]<10)&&(i<2)) LCD_1_PrCString("0");
itoa(buffer, almBuf[i], 16);}
else { if(rxBuf[2-i]<10) LCD_1_PrCString("0");
itoa(buffer, rxBuf[2-i], 16); }
if(((set==8)||(set==9))&&(i==2)) {}
else LCD_1_PrString(buffer);
if(((set==1)||(set==8))&&(i==0)) LCD_1_PrCString("]");
if(((set==2)||(set==9))&&(i==1)) LCD_1_PrCString("]");
if((set==3)&&(i==2)) LCD_1_PrCString("]");
//if(i!=2) LCD_1_PrCString(":");
if((set<8)&&(i!=2)) LCD_1_PrCString(":");
if((set>7)&&(i==0)) LCD_1_PrCString(":");
}
//gün değişimlerini LCD de kayan yazı şeklinde göster
LCD_1_Position(1,0);
if(set==4) LCD_1_PrCString("[");
if(rxBuf[3]==1) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("n ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("on ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Mon");
}
if(rxBuf[3]==2) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("e ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("ue ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Tue");
}
if(rxBuf[3]==3) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("d ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("ed ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Wed");
}
if(rxBuf[3]==4) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("u ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("hu ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Thu");
}
if(rxBuf[3]==5) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("i ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("ri ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Fri");
}
if(rxBuf[3]==6) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("t ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("at ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Sat");
}
if(rxBuf[3]==7) {
if((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59)) LCD_1_PrCString(" ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0)) LCD_1_PrCString("n ");
if((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1)) LCD_1_PrCString("un ");
if(!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==0))&&
!((rxBuf[2]==0)&&(rxBuf[1]==0)&&(rxBuf[0]==1))&&
!((rxBuf[2]==0x23)&&(rxBuf[1]==0x59)&&(rxBuf[0]==0x59))) LCD_1_PrCString("Sun");
}
if(set==4) LCD_1_PrCString("]");
if((set==4)||(set==5)||(set==6)||(set==7)) LCD_1_PrCString(" ");
else LCD_1_PrCString(" ");
//tarih
for(i=4;i<7;i++)
{
if((set==5)&&(i==4)) LCD_1_PrCString("[");
if((set==6)&&(i==5)) LCD_1_PrCString("[");
if((set==7)&&(i==6)) LCD_1_PrCString("[");
if((rxBuf[i]<10)&&(i!=6)) LCD_1_PrCString("0");
if((i==6)&&rxBuf[6]<10) LCD_1_PrCString("200");
if((i==6)&&rxBuf[6]>9) LCD_1_PrCString("20");
itoa(buffer, rxBuf[i], 16);
LCD_1_PrString(buffer);
if((set==5)&&(i==4)) LCD_1_PrCString("]");
if((set==6)&&(i==5)) LCD_1_PrCString("]");
if((set==7)&&(i==6)) LCD_1_PrCString("]");
if(i!=6) LCD_1_PrCString(".");
}
//set veya LCD takılı kalırsa ekranı temizle
if((rxBuf[0]==0)&&(set!=0))
{
LCD_1_Start();
set=0;
}
if(lcdclear==1)
{
LCD_1_Start();
lcdclear=0;
}
//saat başı beep
if((rxBuf[0]==0)&&(rxBuf[1]==0))
{
PWM8_2_WritePulseWidth(100);
PWM8_2_Start();
}
else if(ALM_ACTIVE==0) PWM8_2_Stop();
//alarm ayarlanmış ise LCD de göster
if(ALM_SET==0x01)
{
LCD_1_Position(0,0);
LCD_1_PrCString("`");
}
if(set==8||set==9)
{
LCD_1_Position(0,13);
LCD_1_PrCString("alm");
}
//alarm çalma rutini
if((rxBuf[2]==almBuf[0])&&(rxBuf[1]==almBuf[1])&&(ALM_SET==0x01)&&(set==0))
{
PWM8_2_WritePulseWidth(5);
PWM8_2_Start();
ALM_ACTIVE=0x01;
}
if((ALM_SET==0x01)&&(rxBuf[0]==0x59)&&(ALM_ACTIVE==0x01))
{
LCD_1_Start();
ALM_SET=0x00;
ALM_ACTIVE=0x00;
PWM8_2_Stop();
}
//sıcaklık ölçme rutini
if((PRT0DR&0x80)==0x80)
{
while((PRT0DR&0x80)==0x80);
T1=Counter16_1_wReadCounter();
while((PRT0DR&0x80)==0x00);
T1=T1-Counter16_1_wReadCounter();
T2=Counter16_1_wReadCounter();
while((PRT0DR&0x80)==0x80);
T2=T2-Counter16_1_wReadCounter();
if((rxBuf[0]==0x00)||(rxBuf[0]==0x15)||(rxBuf[0]==0x30)||(rxBuf[0]==0x45))
temperature=235-(400*T2/T1);
}
//15 saniyede bir sıcaklık
bilgisini tazele
if((set==0)&&(rxBuf[0]!=0x00)&&(rxBuf[0]!=0x15)&&(rxBuf[0]!=0x30)&&(rxBuf[0]!=0x45))
{
if(temperature<10) LCD_1_Position(0,13);
else LCD_1_Position(0,12);
itoa(buffer, temperature, 10);
LCD_1_PrString(buffer);
LCD_1_WriteData(0xDF);
LCD_1_PrCString("C");
}
//LCD parlaklığı
while(ADCINC12_1_fIsDataAvailable()==0);
ADCINC12_1_ClearFlag();
PWM8_3_WritePulseWidth(ADCINC12_1_iGetData()/16);
} while(1);
}
PSoC designer projesi olarak kaynak kodlarını indir. ( hex
dosyası içerir! )
Saat 2 butonla ayarlanır. Bir
buton ile ayarlara girilir diğeri ile artırma yöntemiyle saat istenilen
değerlere ayarlanır. Alarmın kurulması için alarm değişkenleri olan saat veya
dakikanın değiştirilmesi yeterlidir. bu durumda alarm kurulmuş olacak ve LCD de
"`" şeklinde gösterilecektir. Alarm zamanı geldiğinde saat çalacaktır. Çalma
herhangi bir butona basıldığında ise alarm susturulur. Her 15 saniyede bir ortam
sıcaklık bilgisi tazelenir ve saat ayar modunda olmadığı sürece gösterilir. Gün
değişimleri kısaltılmış gün ismi LCD de kayarak değiştirilir. LCD arka plan
aydınlatması LDR üzerine düşen ışık şiddetiyle ters orantılı olarak değişim
gösterir. Aydınlık ortamda LCD arka plan ışık şiddeti azaltılırken karanlık
ortamda artırılır. Yaklaşık çözünürlüğü 100 dür.

PSoC RTC örneği için donanım
kısmı bağlantı şeması yukarıda verilmiştir.
|