Merhabalar. Elimde NXP'nin PCF85063A RTC entegresi bulunuyor. Zamanı set edip saniye saniye zamanı okuyabiliyorum onda sorun yok. Fakat alarm için interrupt alamıyorum malesef. set_alarm() diye bir fonksiyonum var. Saniye,dakika,saat,gün,haftanın günü şeklinde parametreleri veriyorum. Keil'de watch ekranında set ettiğim değerleri görebiliyorum.
Fonksiyonlar bu şekilde burada. RTC_ALARM 0x80 şeklinde define edilmiş. Constrain fonksiyonu o değeri verilen aralığın dışında olduğu takdirde sınır değerler eşitliyor.
Enable alarm fonksiyonu da şöyle.
main fonksiyonu içinde de zamanı set ettim ve 15 saniye sonra için alarm kurdum. Alarm interruptı alabilmek için entegrenin INT bacağını işlemcimin INT2 bacağına bağladım ve interrupt fonksiyonu içinde de basit bir şekilde led yakıyorum. Osiloskopta INT bacağını izliyorum fakat bir şey göremiyorum. Debug modda çalıştırıp interrupt içine breakpoint koydum fakat kod interrupta gitmiyor. Şematik olarak da SDA, SCL ve INT bacaklarında 4.7k pull up dirençleri var.
Entegrenin PDF'inde alarm fonksiyonu şu şekilde açıklanmış. Ben kodu adım adım okuduğumda bu açıklamadaki gibi yapıldığını düşünüyorum.
Neden alarm interruptı alamıyorum acaba?
C:
void PCF85063A::set_alarm(uint8_t alarm_hour, uint8_t alarm_minute, uint8_t alarm_second, uint8_t alarm_day, uint8_t alarm_weekday)
{
//uint8_t setAlarm[5];
if (alarm_second <99) // second
{
alarm_second = constrain(alarm_second, 0, 59);
alarm_second = decToBcd(alarm_second);
alarm_second &= ~RTC_ALARM;
}
else
{
alarm_second = 0x0;
alarm_second |= RTC_ALARM;
}
if (alarm_minute <99) // minute
{
alarm_minute = constrain(alarm_minute, 0, 59);
alarm_minute = decToBcd(alarm_minute);
alarm_minute &= ~RTC_ALARM;
}
else
{
alarm_minute = 0x0;
alarm_minute |= RTC_ALARM;
}
if (alarm_hour <99)
{ // hour
alarm_hour = constrain(alarm_hour, 0, 23);
alarm_hour = decToBcd(alarm_hour);
alarm_hour &= ~RTC_ALARM;
}
else
{
alarm_hour = 0x0;
alarm_hour |= RTC_ALARM;
}
if (alarm_day <99)
{ // day
alarm_day = constrain(alarm_day, 1, 31);
alarm_day = decToBcd(alarm_day);
alarm_day &= ~RTC_ALARM;
}
else
{
alarm_day = 0x0;
alarm_day |= RTC_ALARM;
}
if (alarm_weekday <99)
{ // weekday
alarm_weekday = constrain(alarm_weekday, 0, 6);
alarm_weekday = decToBcd(alarm_weekday);
alarm_weekday &= ~RTC_ALARM;
}
else
{
alarm_weekday = 0x0;
alarm_weekday |= RTC_ALARM;
}
enable_alarm();
setAlarm[0] = alarm_second;
setAlarm[1] = alarm_minute;
setAlarm[2] = alarm_hour;
setAlarm[3] = alarm_day;
setAlarm[4] = alarm_weekday;
I2C_WriteMultiBytesOneReg(I2C0,I2CADDR,RTC_SECOND_ALARM,setAlarm,5);
}
void PCF85063A::read_alarm()
{
//uint8_t readAlarm[5];
I2C_ReadMultiBytesOneReg(I2C0,I2CADDR,RTC_SECOND_ALARM,readAlarm,5);
readAlarm[0] = alarm_second;
readAlarm[1] = alarm_minute;
readAlarm[2] = alarm_hour;
readAlarm[3] = alarm_day;
readAlarm[4] = alarm_weekday;
if(RTC_ALARM & alarm_second) // check is AEN = 1 (second alarm disabled)
{
alarm_second = 99; // using 99 as code for no alarm
}
else
{ // else if AEN = 0 (second alarm enabled)
alarm_second = bcdToDec(alarm_second & ~RTC_ALARM); // remove AEN flag and convert to dec number
}
if(RTC_ALARM & alarm_minute)
{
alarm_minute = 99;
}
else
{
alarm_minute = bcdToDec(alarm_minute & ~RTC_ALARM);
}
if(RTC_ALARM & alarm_hour)
{
alarm_hour = 99;
}
else
{
alarm_hour = bcdToDec(alarm_hour);
}
if(RTC_ALARM & alarm_day)
{
alarm_day = 99;
}
else
{
alarm_day = bcdToDec(alarm_day);
}
if(RTC_ALARM & alarm_weekday)
{
alarm_weekday = 99;
}
else
{
alarm_weekday = bcdToDec(alarm_weekday);
}
}
Fonksiyonlar bu şekilde burada. RTC_ALARM 0x80 şeklinde define edilmiş. Constrain fonksiyonu o değeri verilen aralığın dışında olduğu takdirde sınır değerler eşitliyor.
Enable alarm fonksiyonu da şöyle.
C:
void PCF85063A::enable_alarm()
{
control_2 = RTC_CTRL_2_DEFAULT | RTC_ALARM_AIE; // enable interrupt
control_2 &= ~RTC_ALARM_AF; // clear alarm flag
I2C_WriteByteOneReg(I2C0,I2CADDR,RTC_CTRL_2,control_2);
}
C:
//saat-dakika-saniye-haftanin günü-gün-ay-yil
TSMRTC.set_time(16,20,0,Friday,14,10,22);
//saat-dakika-saniye-gün-haftanin günü
TSMRTC.set_alarm(16,20,15,14,Friday);
main fonksiyonu içinde de zamanı set ettim ve 15 saniye sonra için alarm kurdum. Alarm interruptı alabilmek için entegrenin INT bacağını işlemcimin INT2 bacağına bağladım ve interrupt fonksiyonu içinde de basit bir şekilde led yakıyorum. Osiloskopta INT bacağını izliyorum fakat bir şey göremiyorum. Debug modda çalıştırıp interrupt içine breakpoint koydum fakat kod interrupta gitmiyor. Şematik olarak da SDA, SCL ve INT bacaklarında 4.7k pull up dirençleri var.
Entegrenin PDF'inde alarm fonksiyonu şu şekilde açıklanmış. Ben kodu adım adım okuduğumda bu açıklamadaki gibi yapıldığını düşünüyorum.
Neden alarm interruptı alamıyorum acaba?