📄 twi.c
字号:
****************************************************************************/
int8 rtc_set_date(int8 date, int8 month, int16 year)
{
int8 date_array[4];
int8 ret_val;
date_array[0] = _FF_bin2bcd(date);
date_array[1] = 0;
date_array[2] = _FF_bin2bcd(month);
if(year > 1999)
{
date_array[2] |= 0x80;
year -= 2000;
}
else if(year > 1900)
year -= 1900;
date_array[3] = _FF_bin2bcd((uint8) year);
_FF_cli();
ret_val = twi_write(0x05, 4, date_array);
_FF_sei();
return(ret_val);
}
/****************************************************************************
**
** Gets the time and date from a Philips PCF8563 real-time clock
**
** Parameters: *hour, Pointer to where the RTC's hour will be stored
** *min, Pointer to where the RTC's minute will be stored
** *sec, Pointer to where the RTC's seconds value will be stored
** *date, Pointer to where the RTC's day value will be stored
** *month, Pointer to where the RTC's month value will be stored
** *year, Pointer to where the RTC's year value will be stored
**
** Returns: 0 - Time/Date received successfully
** 1 - An error occurred
**
****************************************************************************/
int8 rtc_get_timeNdate(int8 *hour, int8 *min, int8 *sec, int8 *date, int8 *month, int16 *year)
{
int8 time_array[8];
int8 ret_val;
ret_val = twi_read(0x02, 7, time_array);
if(ret_val != TWI_SUCCESS)
return(TWI_ERROR);
twi_read(0x02, 7, time_array);
*sec = _FF_bcd2bin(time_array[0] & 0x7F);
*min = _FF_bcd2bin(time_array[1] & 0x7F);
*hour = _FF_bcd2bin(time_array[2] & 0x3F);
*date = _FF_bcd2bin(time_array[3] & 0x3F);
*month = _FF_bcd2bin(time_array[5] & 0x1F);
*year = _FF_bcd2bin(time_array[6]);
if(time_array[5] & 0x80)
*year += 2000;
else
*year += 1900;
return(ret_val);
}
/*****************************************************************************
**
** LOCAL FUNCTIONS
**
*****************************************************************************/
/****************************************************************************
**
** Sends a two wire interface command
**
** Parameters: twcr_mask, Command to be sent
** status, Flag to see if we need to wait for the status
**
** Returns: 0 - Command sent successfully
** 1 - An error occurred
**
****************************************************************************/
int8 twi_step(uint8 twcr_mask, uint8 status)
{
uint8 twi_status;
TWCR = twcr_mask | TWI_ENABLE;
if(status != TWI_NO_WAIT)
{
TWITimer = 0;
while(((TWCR & 0x80) == 0) && (TWITimer < 100))
;
twi_status = (TWSR & 0xFC);
if((status != TWI_IGNORE_STATUS) && ((twi_status != status) || ((TWCR & 0x80) == 0)))
{
TWCR = TWI_SEND_STOP | TWI_ENABLE;
TWITimer = 0;
while(((TWCR & 0x80) == 0) && (TWITimer < 100))
;
return(TWI_ERROR);
}
}
return(TWI_SUCCESS);
}
/****************************************************************************
**
** Reads the input number of bytes from the two wire interface
**
** Parameters: addr, Address on the TWI bus the data will be read from
** num_bytes, Number of bytes to read
** *pntr, Pointer to the buffer that the data will be stored to
**
** Returns: 0 - Data read successfully
** 1 - An error occurred
**
****************************************************************************/
int8 twi_read(int8 addr, int8 num_bytes, int8 *pntr)
{
int8 cnt;
if(twi_step(TWI_SEND_START,0x08) != TWI_SUCCESS)
return(TWI_ERROR);
TWDR = 0xA2; /* put in the address of the pfc */
if(twi_step(TWI_CLOCK_DATA, 0x18) != TWI_SUCCESS)
return(TWI_ERROR);
TWDR = addr; /* put in word address */
if(twi_step(TWI_CLOCK_DATA,0x28) != TWI_SUCCESS)
return(TWI_ERROR);
if(twi_step(TWI_SEND_START,0x10) != TWI_SUCCESS) /* send start...... */
return(TWI_ERROR);
TWDR = 0xA3; /* put in the address of the pfc for read */
if(twi_step(TWI_CLOCK_DATA,0x40) != TWI_SUCCESS)
return(TWI_ERROR);
for(cnt = 0; cnt < num_bytes; cnt++)
{
if(cnt != (num_bytes - 1))
{
if(twi_step(TWI_ACK_DATA, TWI_IGNORE_STATUS) != TWI_SUCCESS)
return(TWI_ERROR);
}
else
{
if(twi_step(TWI_CLOCK_DATA, TWI_IGNORE_STATUS) != TWI_SUCCESS)
return(TWI_ERROR);
}
#ifdef _IAR_EWAVR_
*pntr = TWDR;
pntr++;
#else
*pntr++ = TWDR;
#endif
}
twi_step(TWI_SEND_STOP, TWI_NO_WAIT); /* send stop */
return(TWI_SUCCESS);
}
/****************************************************************************
**
** Writes the input number of bytes to the two wire interface
**
** Parameters: addr, Address on the TWI bus the data will be written to
** num_bytes, Number of bytes to write
** *pntr, Pointer to the buffer that the data will be written
** from
**
** Returns: 0 - Data written successfully
** 1 - An error occurred
**
****************************************************************************/
int8 twi_write(int8 addr, int8 num_bytes, int8 *pntr)
{
int8 cnt;
if(twi_step(TWI_SEND_START, 0x08) != TWI_SUCCESS)
return(TWI_ERROR);
TWDR = 0xA2; /* put in the address of the pfc */
if(twi_step(TWI_CLOCK_DATA, 0x18) != TWI_SUCCESS)
return(TWI_ERROR);
TWDR = addr; /* put in word address */
if(twi_step(TWI_CLOCK_DATA, 0x28) != TWI_SUCCESS)
return(TWI_ERROR);
for(cnt = 0; cnt < num_bytes; cnt++)
{
#ifdef _IAR_EWAVR_
TWDR = *pntr;
pntr++;
#else
TWDR = *pntr++;
#endif
if(twi_step(TWI_CLOCK_DATA, 0x28) != TWI_SUCCESS)
return(TWI_ERROR);
}
twi_step(TWI_SEND_STOP, TWI_NO_WAIT);
return(TWI_SUCCESS);
}
/****************************************************************************
**
** Changes a binary value to a BCD value
**
** Parameters: binval, The input binary valued byte
**
** Returns: The BCD equivalent to the binary input
**
****************************************************************************/
int8 _FF_bin2bcd(uint8 binval)
{
int8 temp_val;
if(binval > 99)
return((int8) EOF);
temp_val = binval / 10;
temp_val <<= 4;
temp_val |= (binval % 10) & 0x0F;
return(temp_val);
}
/****************************************************************************
**
** Changes a BCD value to a binary value
**
** Parameters: bcdval, The input BCD valued byte
**
** Returns: The binary equivalent to the BCD input
**
****************************************************************************/
uint8 _FF_bcd2bin(uint8 bcdval)
{
uint8 temp_val;
temp_val = ((bcdval >> 4) & 0x0F) * 10;
temp_val += (bcdval & 0x0F);
return(temp_val);
}
/*****************************************************************************
**
** EOF
**
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -