Witam
Postanowiłem pobawić się trochę układem DS1305. Ogólnie układ wydaje się działać, jednak kiedy bliżej przyjrzeć się temu w jaki sposób zliczany jest czas pojawia się pewne dziwne zjawisko. Mianowicie co jakiś (co 10 sekund/minut) czas zamiast inkrementacji sekund/minut o 1 inkrementują się one o 7 np. z 25 na 32. Poza tym wszystko wydaje się być w porządku, ogólna liczba sekund się zgadza, tylko nie są zliczane do 59 a do 80kilku (w wyniku tej dziwnej inkrementacji). Problem leży raczej gdzieś w części programowej, gdyż korzystam z modułu Mmega02 firmy Propox, w którym RTC jest montowany fabrycznie. Całość jest wyświetlana na LCD ze sterownikiem Toshiba T6963C. Poniżej zamieszczam listing programu głównego oraz inicjalizację SPI i DSa, z góry dziękuję za pomoc.
SPI :
DS1305 :
Dodano po 1 [minuty]:
problem rozwiązany, pisze odpowiedź bo może komuś się przydać. W funkcji ltoa jako podstawę trzeba dać 16 (system szesnastkowy) zamiast 10 (system dziesiętny).
Postanowiłem pobawić się trochę układem DS1305. Ogólnie układ wydaje się działać, jednak kiedy bliżej przyjrzeć się temu w jaki sposób zliczany jest czas pojawia się pewne dziwne zjawisko. Mianowicie co jakiś (co 10 sekund/minut) czas zamiast inkrementacji sekund/minut o 1 inkrementują się one o 7 np. z 25 na 32. Poza tym wszystko wydaje się być w porządku, ogólna liczba sekund się zgadza, tylko nie są zliczane do 59 a do 80kilku (w wyniku tej dziwnej inkrementacji). Problem leży raczej gdzieś w części programowej, gdyż korzystam z modułu Mmega02 firmy Propox, w którym RTC jest montowany fabrycznie. Całość jest wyświetlana na LCD ze sterownikiem Toshiba T6963C. Poniżej zamieszczam listing programu głównego oraz inicjalizację SPI i DSa, z góry dziękuję za pomoc.
#include <avr/io.h>
#include <avr/iom128.h>
#include <stdlib.h>
#include "T6963C.h"
#include "graphic.h"
#include "DS1305.h"
#include "SPI.h"
void setup(void)
{
SPI_init(); // Initialize SPI
DS1305_init(); // Initialize RTC SPI
}
// wyswietlenie liczby
void lcd_sendnumber(unsigned int number,unsigned char wyr,char znak)
{
char buf[8]=" ";
ltoa(number,buf,10); // zamiana liczby na string (syst. dziesietny)
if (wyr !=0)
{
unsigned char b;
for (b=wyr;b>1;b--)
if (buf[b]==' ') GLCD_WriteChar(znak); // dodanie spacji na poczatek
}
GLCD_WriteString(buf); // wyswietlenie na LCD
}
int main(void)
{
unsigned char hours,minutes,seconds;
setup();
DDRE = 0xff;
GLCD_Initalize(); // Initalize LCD
GLCD_ClearText(); // Clear text area
GLCD_ClearCG(); // Clear character generator area
GLCD_ClearGraphic(); // Clear graphic area
// Eneble oscillator note: after power up oscillator is atopped
DS1305_write_byte(0x8f,0x00); // disable write protection
DS1305_write_byte(0x8f,0x00); // Enable oscilator
/*
// Ustawianie zegara
DS1305_write_byte(0x80,0b00000000); // sekundy
DS1305_write_byte(0x81,0b00100101); // minuty
DS1305_write_byte(0x82,0b00000000); // godziny
DS1305_write_byte(0x83,0b00000010); // dzien tygodnia
DS1305_write_byte(0x84,0b00001010); // dzien miesiaca
DS1305_write_byte(0x85,0b00001000); // miesiac
DS1305_write_byte(0x86,0b00010000); // rok
*/
for(;;)
{
// Read time from RTC DS1305
hours=DS1305_read_byte(0x02); // read hours
minutes=DS1305_read_byte(0x01); // read minutes
seconds=DS1305_read_byte(0x00); // read seconds
PORTE = seconds;
GLCD_TextGoTo(0,0);
lcd_sendnumber(hours,2,'0');
GLCD_TextGoTo(4,0);
lcd_sendnumber(minutes,2,'0');
GLCD_TextGoTo(8,0);
lcd_sendnumber(seconds,2,'0');
}
return 0;
}
//-------------------------------------------------------------------------------------------------
//
// Delay function
//
//-------------------------------------------------------------------------------------------------
void delay(void)
{
volatile unsigned char i;
for(i = 0; i < (F_CPU/1000000); i++)
{
asm("nop");
}
}
//-------------------------------------------------------------------------------------------------
//
// Ports intalization
//
//-------------------------------------------------------------------------------------------------
void GLCD_InitalizeInterface(void)
{
GLCD_DATA_DDR = 0xFF;
GLCD_CTRL_DDR = ((1 << GLCD_WR) | (1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD) | (1 << GLCD_RESET) | (1 << GLCD_FS));
GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD) | (1 << GLCD_RESET) | (1 << GLCD_FS));
}
//-------------------------------------------------------------------------------------------------
//
// Reads dispay status
//
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ChceckStatus(void)
{
uint8_t tmp;
GLCD_DATA_DDR = 0x00;
GLCD_CTRL_PORT &= ~((1 << GLCD_RD) | (1 << GLCD_CE));
delay();
tmp = GLCD_DATA_PIN;
GLCD_DATA_DDR = 0xFF;
GLCD_CTRL_PORT |= ((1 << GLCD_RD) | (1 << GLCD_CE));
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Writes instruction
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteCommand(unsigned char command)
{
while(!(GLCD_ChceckStatus()&0x03));
GLCD_DATA_PORT = command;
GLCD_CTRL_PORT &= ~((1 << GLCD_WR) | (1 << GLCD_CE));
delay();
GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_CE));
}
//-------------------------------------------------------------------------------------------------
//
// Writes data
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteData(unsigned char data)
{
while(!(GLCD_ChceckStatus()&0x03));
GLCD_DATA_PORT = data;
GLCD_CTRL_PORT &= ~((1 << GLCD_WR) | (1 << GLCD_CE) | (1 << GLCD_CD));
delay();
GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_CE) | (1 << GLCD_CD));
}
//-------------------------------------------------------------------------------------------------
//
// Reads data
//
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadData(void)
{
uint8_t tmp;
while(!(GLCD_ChceckStatus()&0x03));
GLCD_DATA_DDR = 0x00;
GLCD_CTRL_PORT &= ~((1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));
delay();
tmp = GLCD_DATA_PIN;
GLCD_CTRL_PORT |= ((1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));
GLCD_DATA_DDR = 0xFF;
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Sets address pointer for display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_SetAddressPointer(unsigned int address)
{
GLCD_WriteData(address & 0xFF);
GLCD_WriteData(address >> 8);
GLCD_WriteCommand(T6963_SET_ADDRESS_POINTER);
}
//-------------------------------------------------------------------------------------------------
//
// Clears text area of display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_ClearText(void)
{
int i;
GLCD_SetAddressPointer(GLCD_TEXT_HOME);
for(i = 0; i < GLCD_TEXT_SIZE; i++)
{
GLCD_WriteDisplayData(0);
}
}
//-------------------------------------------------------------------------------------------------
//
// Clears characters generator area of display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_ClearCG(void)
{
unsigned int i;
GLCD_SetAddressPointer(GLCD_EXTERNAL_CG_HOME);
for(i = 0; i < 256 * 8; i++)
{
GLCD_WriteDisplayData(0);
}
}
//-------------------------------------------------------------------------------------------------
//
// Clears graphics area of display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_ClearGraphic(void)
{
int i;
GLCD_SetAddressPointer(GLCD_GRAPHIC_HOME);
for(i = 0; i < GLCD_GRAPHIC_SIZE; i++)
{
GLCD_WriteDisplayData(0x00);
}
}
//-------------------------------------------------------------------------------------------------
//
// Writes a single character (ASCII code) to display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteChar(char charCode)
{
GLCD_WriteDisplayData(charCode - 32);
}
//-------------------------------------------------------------------------------------------------
//
// Writes null-terminated string to display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteString(char * string)
{
while(*string)
{
GLCD_WriteChar(*string++);
}
}
//-------------------------------------------------------------------------------------------------
//
// Writes null-terminated string from program memory to display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteStringPgm(prog_char * string)
{
char ch;
while((ch = pgm_read_byte(string++)))
{
GLCD_WriteChar(ch);
}
}
//-------------------------------------------------------------------------------------------------
//
// Sets display coordinates
//
//-------------------------------------------------------------------------------------------------
void GLCD_TextGoTo(unsigned char x, unsigned char y)
{
unsigned int address;
address = GLCD_TEXT_HOME + x + (GLCD_TEXT_AREA * y);
GLCD_SetAddressPointer(address);
}
//-------------------------------------------------------------------------------------------------
//
// Writes single char pattern to character generator area of display RAM memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_DefineCharacter(unsigned char charCode, unsigned char * defChar)
{
unsigned int address;
unsigned char i;
address = GLCD_EXTERNAL_CG_HOME + (8 * charCode);
GLCD_SetAddressPointer(address);
for(i = 0; i < 8 ; i++)
{
GLCD_WriteDisplayData(*(defChar + i));
}
}
//-------------------------------------------------------------------------------------------------
//
// Set (if color==1) or clear (if color==0) pixel on screen
//
//-------------------------------------------------------------------------------------------------
void GLCD_SetPixel(unsigned char x, unsigned char y, unsigned char color)
{
unsigned char tmp;
unsigned int address;
address = GLCD_GRAPHIC_HOME + (x / GLCD_FONT_WIDTH) + (GLCD_GRAPHIC_AREA * y);
GLCD_SetAddressPointer(address);
GLCD_WriteCommand(T6963_DATA_READ_AND_NONVARIABLE);
tmp = GLCD_ReadData();
if(color)
tmp |= (1 << (GLCD_FONT_WIDTH - 1 - (x % GLCD_FONT_WIDTH)));
else
tmp &= ~(1 << (GLCD_FONT_WIDTH - 1 - (x % GLCD_FONT_WIDTH)));
GLCD_WriteDisplayData(tmp);
}
//-------------------------------------------------------------------------------------------------
//
// Writes display data and increment address pointer
//
//-------------------------------------------------------------------------------------------------
void GLCD_WriteDisplayData(unsigned char x)
{
GLCD_WriteData(x);
GLCD_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
}
//-------------------------------------------------------------------------------------------------
//
// Sets graphics coordinates
//
//-------------------------------------------------------------------------------------------------
void GLCD_GraphicGoTo(unsigned char x, unsigned char y)
{
unsigned int address;
address = GLCD_GRAPHIC_HOME + (x / GLCD_FONT_WIDTH) + (GLCD_GRAPHIC_AREA * y);
GLCD_SetAddressPointer(address);
}
//-------------------------------------------------------------------------------------------------
//
// Displays bitmap from program memory
//
//-------------------------------------------------------------------------------------------------
void GLCD_Bitmap(unsigned char * bitmap, unsigned char x, unsigned char y, unsigned char width, unsigned char height)
{
unsigned char i, j;
for(j = 0; j < height; j++)
{
GLCD_GraphicGoTo(x, y + j);
for(i = 0; i < width/GLCD_FONT_WIDTH; i++)
{
GLCD_WriteDisplayData(pgm_read_byte(bitmap + i + (GLCD_GRAPHIC_AREA * j)));
}
}
}
//-------------------------------------------------------------------------------------------------
//
// Display initalization
//
//-------------------------------------------------------------------------------------------------
void GLCD_Initalize(void)
{
GLCD_InitalizeInterface();
GLCD_CTRL_PORT &= ~(1 << GLCD_RESET);
_delay_ms(1);
GLCD_CTRL_PORT |= (1 << GLCD_RESET);
#if (GLCD_FONT_WIDTH == 8)
GLCD_CTRL_PORT &= ~(1 << GLCD_FS);
#endif
GLCD_WriteData(GLCD_GRAPHIC_HOME & 0xFF);
GLCD_WriteData(GLCD_GRAPHIC_HOME >> 8);
GLCD_WriteCommand(T6963_SET_GRAPHIC_HOME_ADDRESS);
GLCD_WriteData(GLCD_GRAPHIC_AREA);
GLCD_WriteData(0x00);
GLCD_WriteCommand(T6963_SET_GRAPHIC_AREA);
GLCD_WriteData(GLCD_TEXT_HOME);
GLCD_WriteData(GLCD_TEXT_HOME >> 8);
GLCD_WriteCommand(T6963_SET_TEXT_HOME_ADDRESS);
GLCD_WriteData(GLCD_TEXT_AREA);
GLCD_WriteData(0x00);
GLCD_WriteCommand(T6963_SET_TEXT_AREA);
GLCD_WriteData(GLCD_OFFSET_REGISTER);
GLCD_WriteData(0x00);
GLCD_WriteCommand(T6963_SET_OFFSET_REGISTER);
GLCD_WriteCommand(T6963_DISPLAY_MODE | T6963_GRAPHIC_DISPLAY_ON | T6963_TEXT_DISPLAY_ON /*| T6963_CURSOR_DISPLAY_ON*/);
GLCD_WriteCommand(T6963_MODE_SET | 0);
}
SPI :
//ATmega103/128
#define SPI_PORT PORTB
#define SPI_PORT_DIR DDRB
#define SPI_SS PB0
#define SPI_SCK PB1 // SPI signals
#define SPI_MOSI PB2
#define SPI_MISO PB3
void SPI_init(void)
{
SPI_PORT_DIR|=((1<<SPI_SCK) | (1<<SPI_MOSI) | (1<<SPI_SS)); // set SPI lines as input or output
SPI_PORT_DIR|=~(1<<SPI_MISO);
SPCR = 0x5f; // set SPI configuration
}
void spi_wait(void) // wait for data from SPI
{
while (!SPSR);
}
DS1305 :
#define DS1305_CS_BIT PB5
#define DS1305_CS_PORT PORTB
#define DS1305_CS_PORT_DIR DDRB
void DS1305_init(void)
{
DS1305_CS_PORT_DIR|= 1<<DS1305_CS_BIT;
DS1305_CS_PORT&= ~(1<<DS1305_CS_BIT);
}
unsigned char DS1305_read_byte(unsigned char address)
{
DS1305_CS_PORT |= 1<<DS1305_CS_BIT;
SPDR = address;
while (!SPSR);
SPDR = 0;
while (!SPSR);
DS1305_CS_PORT &= ~(1<<DS1305_CS_BIT);
return (SPDR);
}
void DS1305_write_byte(unsigned char address,unsigned char data)
{
DS1305_CS_PORT |= 1<<DS1305_CS_BIT;
SPDR = address;
while (!SPSR);
SPDR = data;
while (!SPSR);
DS1305_CS_PORT &= ~(1<<DS1305_CS_BIT);
}
Dodano po 1 [minuty]:
problem rozwiązany, pisze odpowiedź bo może komuś się przydać. W funkcji ltoa jako podstawę trzeba dać 16 (system szesnastkowy) zamiast 10 (system dziesiętny).