Zdravím
začínám s programováním v C mám k Atmega8 připojen RTC DS1302 spolu komunikují, ale na LCD se zobrazují jiné znaky.
Fórum › Mikrokontroléry
DS1302
vetsinou z toho vychazi podle nastaveni binarni nebo BCD kod...
binarni je klasicky zpusob ukladani cisel - abys z nich dostal jednotlive cislice musis delit 10
a bcd je zvlastni v tom, ze mas na kazdou cislici pulku bajtu (4b na prvni a 4 na druhy - nemusi se to pak tak slozite zobrazovat)
Zdravím
dostal sem od kolegy kód k DS1302, ale prostě nemůžu přijít na to jak do těch funkcí narvat a získat ty argumenty data a času. Neuměl by mi prosím někdo znalý pohledem na kód poradit?
/*-------------------------
ds1302.h
-------------------------*/
#ifndef RTC_H
#define RTC_H
//Data type to hold calendar/clock data
typedef struct
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t date;
uint8_t month;
uint8_t day;
uint8_t year;
} dateTime;
/*******************************************************************
Interface function to initialize RTC: 1. Disable Clock Halt
2. Set to 24 hour mode
3. Disable Write Protection
No Calendar/Clock will be changed
********************************************************************/
void rtc_init(void);
//Interface function to read Calendar/Clock value
dateTime get_date_time(void);
//Interface function to set Calendar/Clock value
void set_date_time(dateTime dt);
#endif
/*-------------------------
ds1302.c
-------------------------/
/* SCLK - PC0
I/O - PC1
REST - PC2 */
#define F_CPU 8000000UL //8.000MHz
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include "rtc.h"
//Strobe "pin" on "port" high
#define IO_PIN_STROBE_HIGH(port, pin) \
__asm__ __volatile__ ( \
"sbi %0, %1" \
: /* no output */ \
: "I" (_SFR_IO_ADDR(port)), \
"I" (pin))
//Strobe "pin" on "port" low
#define IO_PIN_STROBE_LOW(port, pin) \
__asm__ __volatile__ ( \
"cbi %0, %1" \
: /* no output */ \
: "I" (_SFR_IO_ADDR(port)), \
"I" (pin))
//Timing requirement between data output and clock strobe high
#define DATA_TO_CLK_SETUP() \
__asm__ __volatile__ ( \
"nop\n\t" \
"nop\n\t" \
::)
//Strobe CE pin of DS1302 high and low
#define CE_STROBE_HIGH() IO_PIN_STROBE_HIGH(PORTC, 5)
#define CE_STROBE_LOW() IO_PIN_STROBE_LOW(PORTC, 5)
//Strobe SCLK pin of DS1302 high and low
#define SCLK_STROBE_HIGH() IO_PIN_STROBE_HIGH(PORTC, 6)
#define SCLK_STROBE_LOW() IO_PIN_STROBE_LOW(PORTC, 6)
//Strobe IO pin of DS1302 high and low
#define IO_STROBE_HIGH() IO_PIN_STROBE_HIGH(PORTC, 7)
#define IO_STROBE_LOW() IO_PIN_STROBE_LOW(PORTC, 7)
//Calendar/Clock burst read and write command
#define DT_BURST_READ 0xbf
#define DT_BURST_WRITE 0xbe
//RTC register seconds byte read and write command
#define DT_SECONDS_READ 0x81
#define DT_SECONDS_WRITE 0x80
//RTC register hours byte read and write command
#define DT_HOURS_READ 0x85
#define DT_HOURS_WRITE 0x84
//RTC register WP write
#define DT_WP_WRITE 0x8e
//Configure port pin directions for read and write DS1302
#define WRITE_MODE() (DDRC |= 0xe0)
#define READ_MODE() (DDRC = (DDRC|0xe0)&0xbf)
//Disable io pull-up in read mode
#define DISABLE_IO_PULLUP() (PORTC &= 0xbf)
//Read i/o value from DS1302
#define IO_READ() (PINC & 0x40)
//Prepare CE and SCLK for new operation
static void reset(void)
{
//Pull both CE and SCLK low to start with
SCLK_STROBE_LOW();
CE_STROBE_LOW();
//Comms. begin with CE stobe high
CE_STROBE_HIGH();
}
//Read one byte of Calendar/Clock data
static uint8_t read_byte(void)
{
uint8_t byte = 0;
uint8_t i;
//Port pins in read mode for data read
READ_MODE();
//Disable internal I/O pull-up
DISABLE_IO_PULLUP();
//Read one byte of Calendar/Clock data
for(i = 0; i != 8; ++i)
{
//Strobe SCLK low to read I/O
SCLK_STROBE_LOW();
_delay_us(1);
if(IO_READ() != 0)
{
byte |= 1<<i;
}
//Strobe SCLK high for next I/O read
SCLK_STROBE_HIGH();
_delay_us(1);
}
return byte;
}
//Write one byte of control or Calendar/Clock data
static void write_byte(uint8_t byte)
{
uint8_t i;
//Port pins in write mode
WRITE_MODE();
//Write one byte of control or Calendar/Clock data
for(i = 0; i != 8; ++i)
{
//Start clock cycle with SCLK low
SCLK_STROBE_LOW();
_delay_us(1);
//Write bit value to I/O pin of DS1302
if(((1<<i)&byte) == 0)
{
IO_STROBE_LOW();
}
else
{
IO_STROBE_HIGH();
}
DATA_TO_CLK_SETUP(); //Data to clock setup
//End clock cycle with SCLK high
SCLK_STROBE_HIGH();
_delay_us(1);
}
}
//Read 7 bytes of Calendar/Clock data
static dateTime read_dt_block(void)
{
uint8_t dt_byte;
uint8_t byte_pos;
dateTime dt = {0};
//Always do a reset before a new operation
reset();
//Write the clock burst read command into DS1302
write_byte(DT_BURST_READ);
//Read each of the 7 Calendar/Clock bytes from DS1302
for(byte_pos = 0; byte_pos != 7; ++byte_pos)
{
//Read one byte of calendar/clock data
dt_byte = read_byte();
//Copy the read byte to the right place
switch(byte_pos)
{
case 0:
dt.second = dt_byte;
break;
case 1:
dt.minute = dt_byte;
break;
case 2:
dt.hour = dt_byte;
break;
case 3:
dt.date = dt_byte;
break;
case 4:
dt.month = dt_byte;
break;
case 5:
dt.day = dt_byte;
break;
case 6:
dt.year = dt_byte;
break;
}
}
//Always end an operation with a reset
reset();
return dt;
}
//Write 8 bytes of Calendar/Clock data
static void write_dt_block(dateTime dt)
{
uint8_t dt_byte;
uint8_t byte_pos;
//Always do a reset before a new operation
reset();
//Write burst write command byte to DS1302
write_byte(DT_BURST_WRITE);
//Write each of the 7 Calendar/Clock byte to DS1302
for(byte_pos = 0; byte_pos != 7; ++byte_pos)
{
//Copy the right byte to write
switch(byte_pos)
{
case 0:
dt_byte = dt.second;
break;
case 1:
dt_byte = dt.minute;
break;
case 2:
dt_byte = dt.hour;
break;
case 3:
dt_byte = dt.date;
break;
case 4:
dt_byte = dt.month;
break;
case 5:
dt_byte = dt.day;
break;
case 6:
dt_byte = dt.year;
break;
}
//Write one byte of Calendar/Clock data
write_byte(dt_byte);
}
//Must write the 8th byte of the Calendar/Clock register
write_byte(0);
//Always end an operation with a reset
reset();
}
/*******************************************************************
Interface function to initialize RTC: 1. Disable Clock Halt
2. Set to 24 hour mode
3. Disable Write Protection
No Calendar/Clock will be changed
********************************************************************/
void rtc_init(void)
{
uint8_t byte_second;
uint8_t byte_hour;
//Disable Clock Halt
reset();
write_byte(DT_SECONDS_READ);
byte_second = read_byte();
reset();
write_byte(DT_SECONDS_WRITE);
write_byte(byte_second & 0x7f);
reset();
//Set to 24 hour mode
write_byte(DT_HOURS_READ);
byte_hour = read_byte();
reset();
write_byte(DT_HOURS_WRITE);
write_byte(byte_hour & 0x7f);
reset();
//Disable Write Protection
write_byte(DT_WP_WRITE);
write_byte(0);
reset();
}
//Interface function to read Calendar/Clock value
dateTime get_date_time(void)
{
dateTime dt;
//Read raw calendar/clock block from DS1302
dt = read_dt_block();
/*************************************************************
Convert from the raw BCD Calendar/Clock data to normal decimal
values. Hour is treated differently in 24 and AM/PM mode.
Also the day of week is left as is.
**************************************************************/
dt.second = (((dt.second&0x70)>>4)*10) + (dt.second&0x0f);
dt.minute = (((dt.minute&0x70)>>4)*10) + (dt.minute&0x0f);
if((dt.hour&0x80) == 0)
{
dt.hour = (((dt.hour&0x30)>>4)*10) + (dt.hour&0x0f);
}
dt.date = (((dt.date&0x30)>>4)*10) + (dt.date&0x0f);
dt.month = (((dt.month&0x10)>>4)*10) + (dt.month&0x0f);
dt.year = (((dt.year&0xf0)>>4)*10) + (dt.year&0x0f);
return dt;
}
//Interface function to set Calendar/Clock value
void set_date_time(dateTime dt)
{
/**************************************************************
Convert from normal decimal Calendar/Clock value to BCD. Hour
is treated differently in 24 and AM/PM mode. Also the day of
week is left as is.
***************************************************************/
dt.second = ((dt.second/10)<<4) | (dt.second%10);
dt.minute = ((dt.minute/10)<<4) | (dt.minute%10);
if((dt.hour&0x80) == 0)
{
dt.hour = ((dt.hour/10)<<4) | (dt.hour%10);
}
dt.date = ((dt.date/10)<<4) | (dt.date%10);
dt.month = ((dt.month/10)<<4) | (dt.month%10);
dt.year = ((dt.year/10)<<4) | (dt.year%10);
write_dt_block(dt);
}
no přece normálně, budeš volat jednotlivé funkce ... co přesně na tom nechápeš? Vždyť to máš i okomentované .... co by jsi k tomu ještě chtěl?
#include "ds1302.h"
dateTime mydt;
mydt = get_date_time();
/*
a pak pristup k polozkam struktury napr.
mydt.minute precte minuty
*/
hu
Ahoj, jen takovej tip,já sem se na zdroják nekoukal, ale ted se mi stalo s DS1302 když byla uplně nová, že z ní nešly načíst data (vracelo to pořád stejnou hodnotu času), a když jsem do ní nejprve zapsal - nastavil čas tak se teprve rozjela. Už si napamatuju co bylo v datasheetu...jestli je nutno nějakým nastavením spustit hodiny nebo nějak její činnost...
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
DS1302 - krystal — založil morganzd
Moderátoři diskuze