spero che qualche d'uno possa darmi una mano perché non so più dove sbattere la testa. Io sto facendo un progettino che vede impiegato un PIC 18F87K22 e programmato in C tramite il compilatore mikroc. Questo progettino vede l'utilizzo del RTCC integrato al PIC e purtroppo non posso utilizzare un secondo quarzo per generare il clock da 1 Hz per questioni hardware. Per questo motivo sono costretto ad utilizzare il circuito oscillatore interno al PIC sia per generare l'1Hz e sia per generare i 16MHz per far funzionare il PIC. Ora la mia libreria funziona perfettamente: leggo, scrivo e stampo i valori giusti ma purtorppo il mio orologio guadagna circa 3 secondi per minuto e risulta essere parecchio impreciso. Ecco a voi il mio codice:
MAIN:
- Codice: Seleziona tutto
#define measured_frequency_kz 31.25
#include "__T6963C.h"
#include "Object.h"
#include "GLCD_Drivers.c"
#include "rtcc - Copia.c"
unsigned int x_coord=0, y_coord=0;
unsigned short int position=0;
char process=0, pressed='\0';
char device_status = STATUS_UNLOCKED_ROOT;
void mcuInit();
void devicesInit();
void setDeviceStatus(char status_device_mode);
char getDeviceStatus();
my_time menu_time={0, 42, 0};
my_data menu_data={14, 4, 13, 6};
void main()
{
mcuInit();
devicesInit();
while(1)
{
T6963CprintTimeData(getTime(), getData());
/*if(TP_Press_Detect())
{
if(TP_Get_Coordinates(&x_coord, &y_coord)==0)
process = 1;
}
if(process == 1 && TP_Press_Detect()==0)
{
process=0;
pressed = getPressedButton(x_coord, y_coord, getFontSelected(), getDeviceStatus());
if(pressed>='0' && pressed<='9'
|| pressed=='*' || pressed=='#')
{
T6963C_Write_Char(pressed, position, 3, T6963C_ROM_MODE_XOR);
position+=1;
//setta array password
}
else if(pressed=='K' || pressed=='C')
{
position=0;
//resetta array password
}
} */
}
}
void setDeviceStatus(unsigned short int status_device_mode)
{
device_status = status_device_mode;
}
char getDeviceStatus()
{
return device_status;
}
void devicesInit()
{
LCDInit(); //GLCD & Touchscreen initialize
setScreen(FONT_HOME, getDeviceStatus()); //draw Home screen
setStatusIcon(getDeviceStatus()); //draw status icon
initRTCC(); //RTCC initialize
rtccCalibrate();
setDataTime(menu_data, menu_time);
T6963CprintTimeData(getTime(), getData());
}
void mcuInit()
{
OSCCON = 0b01110110;
OSCCON2.SOSCGO = 1;
OSCTUNE = 0b00100000;
TRISA = 0B00001111;
PORTA = 0B00000000;
LATA = 0B00000000;
TRISB = 0B11100011;
PORTB = 0B00000000;
LATB = 0B00000000;
TRISC = 0B01011000;
PORTC = 0B00000000;
LATC = 0B00000000;
TRISD = 0B00000000;
PORTD = 0B00000000;
LATD = 0B00000000;
TRISE = 0B10000000;
PORTE = 0B00000000;
LATE = 0B00000000;
TRISF = 0B00000000;
PORTF = 0B00000000;
LATF = 0B00000000;
TRISG = 0B00000100;
PORTG = 0B00000000;
LATG = 0B00000000;
TRISH = 0B00000000;
PORTH = 0B00000000;
LATH = 0B00000000;
TRISJ = 0B00000000;
PORTJ = 0B00000000;
LATJ = 0B00000000;
ADCON0 = 0B00001101;
ADCON1 = 0B01110000;
ADCON2 = 0B00000000;
ANCON0 = 0B00000011;
ANCON1 = 0B00000000;
ANCON2 = 0B00000011;
ADC_Init();
CM1CON = 0;
CM2CON = 0;
CM3CON = 0;
}
rtcc - Copia.c
- Codice: Seleziona tutto
#define YEAR 0
#define MONTH 1
#define DAY 2
#define WEEKLY_DAY 3
#define HOURS 4
#define MINUTES 5
#define SECONDS 6
#define _RTCEN 128
#define _RTCDS 0
#define _RTCWREN 64
#define _RTCLOCK 0
#define _RTCSYNC 16
#define _RTCNSYNC 0
#define _HALFSEC 8
#define _SEC 0
#define _RTCOEN 4
#define _RTCODS 0
#define _RTS_SOURCE_CLOCK 4
#define _RTS_SECONDS_CLOCK 2
#define _RES_ALARM_PULSE 0
#define _ALRMEN 128
#define _ALRMDS 0
#define _ALRM_CHIME_EN 64
#define _ALRM_CHIME_DS 0
#ifndef measured_frequency_kz
#error YOU MAST DEFINE THE "measured_frequency_kz" in your main program
#endif
static unsigned short int hrs_u=0, hrs_d=0, min_u=0, min_d=0, sec_u=0, sec_d=0;
static unsigned short int yy_u=0, yy_d=0, dd_u=0, dd_d=0;
static unsigned short int eeprom_value=239;
typedef struct my_time
{
unsigned short int hours;
unsigned short int minutes;
unsigned short int seconds;
}my_time;
typedef struct my_data
{
unsigned short int year;
unsigned short int month;
unsigned short int day;
unsigned short int wkly_day;
}my_data;
static void enableWrite()
{
asm{
movlb 0x0F
bcf INTCON, GIE
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf RTCCFG,RTCWREN
}
}
static void disableWrite()
{
delay_ms(20);
asm{
movlb 0x0F
bcf INTCON, GIE
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bcf RTCCFG,RTCWREN
}
}
static void enableRtcc()
{
enableWrite();
RTCCFG.RTCEN = 1;
disableWrite();
}
static unsigned short int decToBcd(unsigned short int integer)
{
unsigned short int bcd=0, u=0, d=0;
u = integer % 10;
d = (((integer - u)/10)<<4);
bcd = d | u;
return bcd;
}
static unsigned short int bcdToDec(unsigned short int bcd)
{
unsigned short int integer=0, u=0, d=0;
u = bcd & 0x0F;
d = (bcd >> 4)*10;
integer = d + u;
return integer;
}
static char * getCardinalNumber(unsigned short int my_day)
{
if(my_day==1 || my_day==21 || my_day==31)
return "ST";
else if(my_day==2 || my_day==22)
return "ND";
else if(my_day==3 || my_day==23)
return "RD";
else if((my_day>=4 && my_day<=20) || (my_day>=24 && my_day<=30))
return "TH";
}
static char * getMonth(unsigned short int month)
{
switch(month)
{
case 1: return "Jan."; break;
case 2: return "Feb."; break;
case 3: return "Mar."; break;
case 4: return "Apr."; break;
case 5: return "May"; break;
case 6: return "Jun."; break;
case 7: return "Jul."; break;
case 8: return "Aug."; break;
case 9: return "Sep."; break;
case 10: return "Oct."; break;
case 11: return "Nov."; break;
case 12: return "Dec."; break;
}
}
static char * getWeeklyDay(unsigned short int weekly_day)
{
switch(weekly_day)
{
case 0: return "Sunday"; break;
case 1: return "Monday"; break;
case 2: return "Tuesday"; break;
case 3: return "Wednesday"; break;
case 4: return "Thursday"; break;
case 5: return "Friday"; break;
case 6: return "Saturday"; break;
}
}
static unsigned short int getPointer(unsigned short int select)
{
unsigned short int _return = 0;
enableWrite();
switch(select)
{
case YEAR:
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 1;
disableWrite();
_return = RTCVALL;
break;
case MONTH:
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 0;
disableWrite();
_return = RTCVALH;
break;
case DAY:
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 0;
disableWrite();
_return = RTCVALL;
break;
case WEEKLY_DAY:
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 1;
disableWrite();
_return = RTCVALH;
break;
case HOURS:
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 1;
disableWrite();
_return = RTCVALl;
break;
case MINUTES:
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 0;
disableWrite();
_return = RTCVALH;
break;
case SECONDS:
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 0;
disableWrite();
_return = RTCVALL;
break;
}
return bcdToDec(_return);
}
static char setPointer(unsigned short int dec_value, unsigned short int select)
{
unsigned short int bcd_value = 0;
bcd_value = decToBcd(dec_value);
enableWrite();
switch(select)
{
case YEAR:
if(dec_value>=0 && dec_value<=99)
{
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 1;
RTCVALL = bcd_value;
}
else
return 1; //Year is out of range
break;
case MONTH:
if(dec_value>=0 && dec_value<=12)
{
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 0;
RTCVALH = bcd_value;
}
else
return 2; //Month is out of range
break;
case DAY:
if(dec_value>=0 && dec_value<=31)
{
RTCCFG.RTCPTR1 = 1;
RTCCFG.RTCPTR0 = 0;
RTCVALL = bcd_value;
}
else
return 3; //Day is out of range
break;
case WEEKLY_DAY:
if(dec_value>=0 && dec_value<=6)
{
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 1;
RTCVALH = bcd_value;
}
else
return 4; //weekly day is out of range
break;
case HOURS:
if(dec_value>=0 && dec_value<=24)
{
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 1;
RTCVALl = bcd_value;
}
else
return 5; //Hours are out of range
break;
case MINUTES:
if(dec_value>=0 && dec_value<=59)
{
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 0;
RTCVALH = bcd_value;
}
else
return 6; //Minutes are out of range
break;
case SECONDS:
if(dec_value>=0 && dec_value<=59)
{
RTCCFG.RTCPTR1 = 0;
RTCCFG.RTCPTR0 = 0;
RTCVALL = bcd_value;
}
else
return 7; //Seconds are out of range
break;
}
disableWrite();
}
void initRtcc()
{
enableWrite();
RTCCFG.RTCEN = 0;
RTCCFG.RTCWREN=1;
RTCCFG.RTCSYNC=0;
RTCCFG.HALFSEC=0;
RTCCFG.RTCOE=0;
disableWrite();
PADCFG1.RTSECSEL1=0;
PADCFG1.RTSECSEL0=0;
RTCCAL = 0;
}
void setDataTime(my_data set_data, my_time set_time)
{
setPointer(set_data.year, YEAR);
setPointer(set_data.month, MONTH);
setPointer(set_data.day, DAY);
setPointer(set_data.wkly_day, WEEKLY_DAY);
setPointer(set_time.hours, HOURS);
setPointer(set_time.minutes, MINUTES);
setPointer(set_time.seconds, SECONDS);
enableRtcc();
}
my_time getTime()
{
my_time load_time;
load_time.hours = getPointer(HOURS);
load_time.minutes = getPointer(MINUTES);
load_time.seconds = getPointer(SECONDS);
return load_time;
}
my_data getData()
{
my_data load_data;
load_data.year = getPointer(YEAR);
load_data.month = getPointer(MONTH);
load_data.day = getPointer(DAY);
load_data.wkly_day = getPointer(WEEKLY_DAY);
return load_data;
}
static void printWeeklyDay(unsigned short int my_day)
{
switch(my_day)
{
case 0:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Saturday", 196, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Sunday", 196, 55);
break;
case 1:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Sunday", 196, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Monday", 196, 55);
break;
case 2:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Monday", 196, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Tuesday", 196, 55);
break;
case 3:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Tuesday", 185, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Wednesday", 185, 55);
break;
case 4:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Wednesday", 195, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Thursday", 195, 55);
break;
case 5:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Thursday", 198, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_Adv("Friday", 198, 55);
break;
case 6:
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK,
_T6963C_HORIZONTAL);
T6963C_Write_Text_adv("Friday", 196, 55);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE,
_T6963C_HORIZONTAL);
T6963C_Write_Text_adv("Saturday", 196, 55);
break;
}
}
void T6963CprintTimeData(my_time decoded_time, my_data decoded_data)
{
unsigned short int u=0;
char erase_string[10];
erase_string[0] = hrs_d;
erase_string[1] = hrs_u;
erase_string[2] = '.';
erase_string[3] = min_d;
erase_string[4] = min_u;
erase_string[5] = '.';
erase_string[6] = sec_d;
erase_string[7] = sec_u;
erase_string[8] = '\0';
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_BLACK, _T6963C_HORIZONTAL);
T6963C_Write_Text_Adv(erase_string, 190, 25);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE, _T6963C_HORIZONTAL);
//calc hours to print
hrs_u = (decoded_time.hours%10);
hrs_d = ((decoded_time.hours - hrs_u)/10);
hrs_u += 48;
hrs_d += 48;
//calc minutes to print
min_u = (decoded_time.minutes%10);
min_d = ((decoded_time.minutes - min_u)/10);
min_u += 48;
min_d += 48;
//calc seconds to print
sec_u = (decoded_time.seconds%10);
sec_d = ((decoded_time.seconds - sec_u)/10);
sec_u += 48;
sec_d += 48;
//calc year to print
yy_u = (decoded_data.year%10);
yy_d = ((decoded_data.year - yy_u)/10);
yy_u += 48;
yy_d += 48;
//calc day to print
dd_u = (decoded_data.day%10);
dd_d = ((decoded_data.day - dd_u)/10);
dd_u += 48;
dd_d += 48;
//clear font first to write
T6963C_cursor_height(7); // set height pointer to seven
erase_string[0] = hrs_d;
erase_string[1] = hrs_u;
erase_string[2] = '.';
erase_string[3] = min_d;
erase_string[4] = min_u;
erase_string[5] = '.';
erase_string[6] = sec_d;
erase_string[7] = sec_u;
erase_string[8] = '\0';
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_INVERT, _T6963C_HORIZONTAL);
T6963C_Write_Text_Adv(erase_string, 190, 25);
T6963C_Set_Font_Adv(T6963C_defaultFont, T6963C_WHITE, _T6963C_HORIZONTAL);
//print data starting from month to GLCD
T6963C_Write_Text_Adv(getMonth(decoded_data.month), 185, 63);
T6963C_cursor_height(1); // set height pointer to one
T6963C_write_Text_Adv(" 20", 205, 63); //write year
T6963C_Write_Char_Adv(yy_d, 218, 63); //write year
T6963C_Write_Char_Adv(yy_u, 224, 63); //write year
T6963C_Write_Char_Adv(dd_d, 214, 35);
T6963C_Write_Char_Adv(dd_u, 220, 35);
T6963C_Write_Text_Adv(getCardinalNumber(decoded_data.day), 214, 43);
//for(u=0; u<7; u+=1)
{
printWeeklyDay(u); //print weekly day
//Delay_ms(2000);
}
}
void rtccCalibrate()
{
const unsigned short int EEPROM_ADDRESS = 0x02;
char _h, _d, _u, _rd;
eeprom_value = EEPROM_read(EEPROM_ADDRESS);
RTCCAL = eeprom_value;
//254
_u = RTCCAL % 10; //4
_rd = (RTCCAL - _u) / 10; //254-4 = 250/10 = 25
_d = _rd % 10; //5
_h = (_rd - _d)/10; //25-5 = 20 = 20/10 = 2
_u += 48;
_d += 48;
_h += 48;
T6963C_Write_Char_Adv(_h, 120, 35);
T6963C_Write_Char_Adv(_d, 130, 35);
T6963C_Write_Char_Adv(_u, 140, 35);
eeprom_value -= 1;
EEPROM_Write(EEPROM_ADDRESS, eeprom_value);
}
Qualche d'uno sa aiutarmi a risolvere il problema?
Come devo settare l'oscillatore affinchè il clock generato sia giusto?
Spero che qualche d'uno possa aiutarmi perché non so più cosa fare: ho anche creato una funzione (da me scritta) che ad ogni reset della MCU decrementava il valore di RTCCAL, ovvero il registro per la calibrazione dell'orologio. Spento e acceso per 256 volte ho ottenuto lo stesso risultato dove per ogni minuto venivano guadagnati 3 secondi.
Un grazie in anticipo,
lcua31989

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)


instead of
(Anonimo).
ain't
, right?
in lieu of
.
for
arithm.


