📄 i2c_sd2405.c
字号:
/*****************************************************
Chip type : ATmega16
Program type : Application
Clock frequency : 12.000000 MHz
*****************************************************/
#include <iom16.h>
#include <inavr.h>
#include <iomacro.h>
#include <intrinsics.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define STR PORTB_Bit0
#define CLK PORTB_Bit1
#define DI PORTB_Bit2
#define TW_START 0x08 // Master
#define TW_REP_START 0x10
#define TW_MT_SLA_ACK 0x18 // Master Transmitter
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_ACK 0x28
#define TW_MT_DATA_NACK 0x30
#define TW_MT_ARB_LOST 0x38
#define TW_MR_ARB_LOST 0x38 // Master Receiver
#define TW_MR_SLA_ACK 0x40
#define TW_MR_SLA_NACK 0x48
#define TW_MR_DATA_ACK 0x50
#define TW_MR_DATA_NACK 0x58
//*************I2C************************
#define SD2405_ADDRESS 0x64
uchar date[7];
//*************************************
//***************I2C**********************
void I2C_init(void)
{
TWSR=0x00; // 2 Wire Bus initialization
TWBR=0x04; // Generate Acknowledge Pulse:On
TWAR=0x00; // 2 Wire Bus Slave Address:0h
TWCR=0x44; // General Call Recognition:Off,Bit Rate: 250.000 kHz
}
/*void I2C_init(void)
{
SCL_Output = 0;
SDA_Output = 0;
SCL_Low;
SDA_Low;
}*/
//产生启动信号
unsigned char I2C_start(void) //产生启动信号
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))){};
return 1;
}
//产生停止信号
void I2C_stop(void) //产生停止信号
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
//向总线写一字节,并返回有无应答
unsigned char I2C_write(unsigned char c) //向总线写一字节,并返回有无应答
{
unsigned char ack=1;
TWDR = c;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))){};
if((TWSR & 0xF8) != TW_MT_SLA_ACK)
ack = 0;
return ack;
}
//读一字节 ack: 1时应答,0时不应答
unsigned char I2C_read(unsigned char ack) //读一字节 ack: 1时应答,0时不应答
{
if (ack)
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
else
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))){};
return(TWDR);
}
/******写SD2400允许程序******/
void WriteTimeOn(void)
{
I2C_start();
I2C_write(SD2405_ADDRESS);// 发写从机写寻址字节 //I2CSendByte(0x64);
//I2CWaitAck();
I2C_write(0x10); // I2CSendByte(0x10);//设置写地址10H
//I2CWaitAck();
I2C_write(0x80); //I2CSendByte(0x80);//置WRTC1=1
//I2CWaitAck();
I2C_stop();
I2C_start();
I2C_write(SD2405_ADDRESS); //I2CSendByte(0x64);
//I2CWaitAck();
I2C_write(0x0f); //I2CSendByte(0x0F);//设置写地址0FH
// I2CWaitAck();
I2C_write(0x84); //I2CSendByte(0x84);//置WRTC2,WRTC3=1
//I2CWaitAck();
I2C_stop();
}
/******写SD2400禁止程序******/
void WriteTimeOff(void)
{
I2C_start();
I2C_write(SD2405_ADDRESS); //I2CSendByte(0x64);
//I2CWaitAck();
I2C_write(0x0f); // I2CSendByte(0x0F);//设置写地址0FH
//I2CWaitAck();
I2C_write(0x0); //I2CSendByte(0x0) ;//置WRTC2,WRTC3=0
//I2CWaitAck();
I2C_write(0x0); //I2CSendByte(0x0) ;//置WRTC1=0(10H地址)
//I2CWaitAck();
I2C_stop();
}
/******写SD2400实时数据寄存器******/
void SD2405_write(unsigned char Addr,unsigned char n, unsigned char* arr)
{
unsigned char i;
WriteTimeOn();
I2C_start(); // 发起始信号
I2C_write(SD2405_ADDRESS); // 发写从机写寻址字节
//I2C_write(Addr>>8); // 发存储单元地址高字节
I2C_write(Addr); // 发存储单元地址低字节
for (i=1;i<=n;i++)
{
I2C_write(*arr); // 写一个字节数据到24C256
arr++;
}
I2C_stop();
I2C_start();
I2C_write(SD2405_ADDRESS);//I2CSendByte(0x64);
//I2CWaitAck();
I2C_write(0x12); // I2CSendByte(0x12);//设置写起始地址
//I2CWaitAck();
I2C_write(0x00); //I2CSendByte(0x00);//清零数字调整寄存器
//I2CWaitAck();
I2C_stop();
WriteTimeOff();
}
//*****************************************
void SD2405_inrupt(void)
{
WriteTimeOn();
I2C_start();
I2C_write(SD2405_ADDRESS);
//I2C_write(0x0e); // address=0x0e
// I2C_write(0x01);
//I2C_write(0x84); //address=0x0f
I2C_write(0x10);
I2C_write(0xa1); //address=0x10;
I2C_write(0xbf); //address=0x11
I2C_stop();
// I2C_write(SD2405_ADDRESS);
//I2C_write(0x07);
// I2C_write(0x01); //address=0x07
WriteTimeOff();
}
//************************************
void SD2405_read(unsigned char Addr,unsigned char n, unsigned char* arr)
{
unsigned char i;
I2C_start(); // 发起始信号
I2C_write(SD2405_ADDRESS); // 发写从机写寻址字节
// I2C_write(Addr>>8); // 发存储单元地址高字节
I2C_write(Addr); // 发存储单元地址低字节
I2C_start(); // 发起始信号
I2C_write(SD2405_ADDRESS | 1); // 发从机读寻址字节
for (i=1;i<=n-1;i++)
{
*arr = I2C_read(1); // 读一个字节数据,返回ACK
arr++;
}
*arr=I2C_read(0); // 读最后一个字节数据,返回NO ACK
I2C_stop(); // 发停止信号
}
//**************************************
void main(void)
{
date[0]=0x0;
date[1]=0x30;
date[2]=0x91;
date[3]=0x02;
date[4]=0x16;
date[5]=0x012;
date[6]=0x08;
SD2405_write(0x0,7, date);
while (1)
{
SD2405_read(0,7,date);
__delay_cycles(450000); //delay time
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -