新闻  |   论坛  |   博客  |   在线研讨会
一个IIC时钟isl1208的AVR驱动
0750long | 2009-04-27 17:19:41    阅读:2876   发布文章

一个IIC时钟isl1208的AVR驱动

 

 前段时间写的,一个简单的iic时钟,采用的软件模拟的iic总线。单片机是atmega168,8m晶振。中文手册见附件。代码如下:

#include <iom168pv.h>
#include <macros.h>
#include "MyHeader.h"
#include "RTC.h"
//---------------------------------------------------------
//
//  IIC起始
//
//---------------------------------------------------------
 
void IIC_Start(void)
{
         RTC_SCL_OUT();
          RTC_SDA_OUT();
          RTC_SDA_1();
          RTC_SCL_H();
          N_NOP(80);
          RTC_SDA_0();
          N_NOP(80);
          RTC_SCL_L();
          N_NOP(80);
}
//---------------------------------------------------------
//
//  IIC结束
//
//---------------------------------------------------------

void IIC_Stop(void)
{
          RTC_SDA_OUT();
          RTC_SDA_0();
          RTC_SCL_H();
          N_NOP(80);
          RTC_SDA_1();
          N_NOP(80);
}
//---------------------------------------------------------
//
//  发出一个ACK
//
//---------------------------------------------------------

void IIC_SentACK(void)
{
          RTC_SDA_OUT();
          RTC_SDA_1();
          RTC_SCL_L();
          N_NOP(80);
          RTC_SDA_0();
          N_NOP(80); 
          RTC_SCL_H();
          N_NOP(80);
          N_NOP(80);
          RTC_SCL_L();
          N_NOP(80);
}
//---------------------------------------------------------
//
//  等待一个ACK
//
//---------------------------------------------------------

unsigned char IIC_GetAck(void)
{
          unsigned char ReturnFlag="NOT";
          RTC_SDA_IN();
          RTC_SCL_L();
          N_NOP(80);
          RTC_SCL_H();
          N_NOP(80);
          if ( RTC_SDA()==0x00 )
          {
                    ReturnFlag = YES;
          }
          else
          {
                    ReturnFlag = NOT;
                    IIC_Stop();
                    return ReturnFlag;
          }
          N_NOP(80);
          RTC_SCL_L();
          N_NOP(80);
          return ReturnFlag;
}
//---------------------------------------------------------
//
//  写入一个字节
//
//---------------------------------------------------------

void IIC_WriteByte(unsigned char Data)
{
          unsigned char i;
          unsigned char Shift = 0x80;
          RTC_SDA_OUT();
          for ( i="0";i<8;i++ )
          {
                    RTC_SCL_L();
                    N_NOP(80);
           if ( (Data&Shift)!=0x00 )
           {
                     RTC_SDA_1();
           }
           else
           {
                     RTC_SDA_0();
           }
           Shift >>= 1;
           N_NOP(80);
           RTC_SCL_H();
           N_NOP(80);
           N_NOP(80);
           RTC_SCL_L();
           N_NOP(80);
          }
}
//---------------------------------------------------------
//
//  移出一个字节
//
//---------------------------------------------------------

unsigned char IIC_ReadByte(void)
{
          unsigned char i;
          unsigned char Shift = 0x80; 
          unsigned char Data = 0x00;
 
          RTC_SDA_IN();
          for ( i="0";i<8;i++ )
          {
                    RTC_SCL_L();
                    N_NOP(80);
                    N_NOP(80);
                    RTC_SCL_H();
                    N_NOP(80);
                    if ( RTC_SDA()!=0x00 )
                    {
                               Data |= Shift;
                    }
                    else
                    {
                    }
                    Shift >>= 1;
                    N_NOP(80);
                    RTC_SCL_L();
                    N_NOP(80);
          }
          return Data;
}
//---------------------------------------------------------
//
//  写入RTC寄存器
//
//---------------------------------------------------------
void Write_RTC_Reg(unsigned char Address,unsigned char Data)
{
          IIC_Start();
          IIC_WriteByte(RTC_WRITE_ADDR);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          { 
          }
          IIC_WriteByte(Address);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          {
          }
          IIC_WriteByte(Data);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          {
          }
          IIC_Stop();
}
//---------------------------------------------------------
//
//  读出RTC寄存器
//
//---------------------------------------------------------

unsigned char Read_RTC_Reg(unsigned char Address)
{
          unsigned char Data;
          IIC_Start();
          IIC_WriteByte(RTC_WRITE_ADDR);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          {
          }
          IIC_WriteByte(Address);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          {
          }
          IIC_Start();
          IIC_WriteByte(RTC_READ_ADDR);
          if ( IIC_GetAck()==YES )
          {
          }
          else
          {
          }
          Data = IIC_ReadByte();
          IIC_Stop();

          return Data;
}
//---------------------------------------------------------
//
//  RTC初始化
//
//---------------------------------------------------------

void RTC_Init(void)
{
          unsigned char i;

          Write_RTC_Reg(0x07,0x91);  //允许外部32768Hz的时钟
          Write_RTC_Reg(0x08,0xca);  //频率输出为1HZ
}
//---------------------------------------------------------
//
//  写入时间:秒分时日月年
//
//---------------------------------------------------------

void RTC_SET_Timer(unsigned char *pointer)
{
          unsigned char i;

          for ( i="0";i<7;i++ )
          {
                    Write_RTC_Reg(0x00+i,*(pointer+i));
          }
}
//---------------------------------------------------------
//
//  得到时间:秒分时日月年
//
//---------------------------------------------------------

void RTC_GET_Timer(unsigned char *pointer)
{
          unsigned char i;
 
          for ( i="0";i<7;i++ )
          {
                    *(pointer+i) = Read_RTC_Reg(0x00+i);
          }
}
//---------------------------------------------------------
//
//  不精确短延时
//
//---------------------------------------------------------

void N_NOP(unsigned char times)
{
          unsigned char i;
          for ( i="0";i<times;i++ )
          {
                    NOP();
          }
}

头文件RTC.h如下

#ifndef _RTC_H_
#define _RTC_H_
//根据需要改变相应的IO口
#define  RTC_SCL_OUT()  SET(DDRC,5)
#define  RTC_SCL_L()   CLR(PORTC,5)
#define  RTC_SCL_H()   SET(PORTC,5)
#define  RTC_SDA_OUT()  SET(DDRC,4)
#define  RTC_SDA_IN()  CLR(DDRC,4)
#define  RTC_SDA_0()   CLR(PORTC,4)
#define  RTC_SDA_1()   SET(PORTC,4)
#define  RTC_SDA()   (PINC&BIT(4))

#define  RTC_WRITE_ADDR  0xde
#define  RTC_READ_ADDR  0xdf
  
void IIC_Start(void);
void IIC_Stop(void);
void IIC_SentACK(void);
unsigned char IIC_GetAck(void);
void IIC_WriteByte(unsigned char Data);
unsigned char IIC_ReadByte(void);
void Write_RTC_Reg(unsigned char Address,unsigned char Data);
unsigned char Read_RTC_Reg(unsigned char Address);
void RTC_Init(void);
void RTC_SET_Timer(unsigned char *pointer);
void RTC_GET_Timer(unsigned char *pointer);
void N_NOP(unsigned char times);

#endif

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客