原创 一个IIC时钟isl1208的AVR驱动

2009-4-26 22:04 4269 15 16 分类: MCU/ 嵌入式

 前段时间写的,一个简单的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

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1407682 2009-4-27 11:45

留爪,看看
相关推荐阅读
用户1478350 2009-09-21 13:57
生成目录树的方法
Tree C:/F >C:\TXT\Filelist.txt...
用户1478350 2009-07-08 12:35
一个CRC32程序
const uint32 crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ 0x00000000, 0x77073096, 0xee0e612c, 0x...
用户1478350 2009-06-04 14:48
一个CRC16程序
 来源于TinyOS的Serial Message手册/*====================================================== 函数: CalculateCRC...
用户1478350 2009-05-08 15:49
刚写了一个中位值滤波程序,无需事先排序的
////------------------------------////  中位值滤波//  //------------------------------//uint16 GetTheMidd...
用户1478350 2009-05-05 15:24
基于ARM7的uc/os II下的SHT7X驱动程序
        在ARM7 LPC2148下做的一个温湿度传感器SHT7X的驱动程序。使用了嵌入式实时操作系统uc/os II。不过实际上的驱动代码与操作系统的关联并不大。应用在别的平台上只需要很小的...
用户1478350 2009-04-29 22:36
一个基于AVR的DataFlash驱动代码
        前段时间需要用到dataflash,选择了atmel的at45db161d,这个代码是我借鉴了别人的代码以后自己写的。功能虽不很完善,但是一些基本的操作还都是有的了。        主...
我要评论
1
15
关闭 站长推荐上一条 /3 下一条