⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 &#8226 控制器(CPU): Atmel AT90S8515 AVR &#8226 MP3解码器: STA013 &#8226 音频 DAC: CS4334 &#8226 IDE 接口
💻 C
字号:
/*
    Copyright 2003 Nasif Akand (nasif@yifan.net)
    http://go.to/zipamp
    http://zipamp.virtualave.net

    This file is part of ZipAmp MP3 software.

    ZipAmp is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    ZipAmp is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this code; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

//This module performs I2C operations for ZipAmp
//Nasif Akand

//If using CodeVision then following includes aren't needed.
//#include "zcontrol.h"
//#include "zfat.h"
//#include "zata.h"
//#include "ztype.h"
#include "i2c.h"
//#include "<delay.h>" //CodeVision AVR internal delay routines

//I2C implementation for STA013

//Port D bit 7 (pin 17) is SDA output while bit 0 (pin 10) is input, Pin 16 is SCL
//SDA input is always at HighZ state. If this pin is pulled up or output high, STA013 will be damaged.

#define SDA	PORTD.7
#define SCL	PORTD.6 
#define SDAIn	PIND.0
#define Out	DDRD.7=1
#define In	DDRD.7=0

#define qDelay		delay_us(3) //According to Phillips I2C specs in all modes..
#define delay		delay_us(3) //..max I2C delay can be 5 micro seconds.
#define Read		0x87  	//STA013 I2C Read address
#define Write		0x86	//STA013 I2C Write Address

void STA013Reset() {
 DDRB.3=1; 	//Set bit3 to Output mode
 PORTB.3=0;	//Set to 0 for reset
 delay_ms(500);	//Wait
 PORTB.3=1;	//Set to 1
 delay_ms(500);	//Wait
}

unsigned char wait_Ack (void) {
//returns 1 if ACK was 0 (meaning transfer was successful). In I2C ACK=0 means success.

 unsigned char t=1;
 delay;	

 // Take clock high
 SCL=1;
 delay;

 // Test of ACK
 delay;
 if (PIND.0) { /*test of SDA level, if high -> problem*/
  t=0;
 }

 delay;
 if (PIND.0) { /*test of SDA level, if high -> problem*/
  t=0;
 }

 // Take clock back low
 delay;
 SCL=0;
 delay;   

 return t;
}
                                               

unsigned char i2cReadAddress(unsigned char adr) {
//Returns data read from register given in adr.
//In most cases we don't have to worry about it. If we don't get ACK, try 10 times before giving up.

 unsigned char data, try=0, ack;
 do {
  i2cStart();           //I2c start
  ack=i2cSend(Write);	//Send i2c write address
  ack &=i2cSend(adr);	//Send register address
  i2cStart();		//i2c re-start
  delay;		//wait
  ack &= i2cSend(Read);	//Send i2c read address
  data=i2cReceive(0);	//Receive data without sending ACK
  i2cStop();		//Stop
  try++;
 }
 while ((ack==0)&&(try<10)); //try 10 times if failed

 return data;
}

unsigned char i2cWriteAddress(unsigned char adr, unsigned char data) {
//Writes data to register adr.
//Returns 1 on successful write, tries 10 times before giving up.

 unsigned char ack,try=0;
 do {
  i2cStart();		//Start
  ack = i2cSend(Write); //Send i2c write address
  ack &= i2cSend(adr);	//Send register address
  delay;  		//wait
  ack &= i2cSend(data); //Send data
  i2cStop();		//Stop
  try++;
 }
 while ((ack==0)&&(try<10)); //give up after 10 tries
 return ack;
}

void i2cInit() {
 DDRD.7=1;  //Set to output mode for SDA
 DDRD.6=1;  //Set to output mode for SCL
}
 
void i2cStart() {
//I2C start condition.

 DDRD.7=1; //SDA output mode
 SDA=1;
 delay;
 SCL=1;
 delay;      
 SDA=0;
 delay;
 SCL=0;
}

unsigned char i2cSend(unsigned char value){
//Sends byte value, and returs ACK from STA013, 1=Success, 0=Fail

 unsigned char i;
 DDRD.7=1;
 for (i=0; i<8; i++) {          
  DDRD.7=1;
  if (((value >> (7-i)) & 0x01)==0x01) SDA=1; //Send bit by bit
  else SDA=0;
  SCL=1;
  delay;
  SCL=0;
  DDRD.7=1;
  SDA=1;
  delay;
 }     
 delay;             
 i=wait_Ack();
 return i;
}                                            

unsigned char i2cReceive(unsigned char ack) {
//Receives data byte. Sends back acknoledge if ack is true

 unsigned char value=0,i;
 DDRD.7=1;
 SDA=1;
 for (i=0; i<8; i++) {
  delay;
  SCL=1;
  delay;
  value = (value << 1) + PIND.0; //leftshift previous value and add one more bit that's read
  delay;
  SCL=0;
 }        
 if (ack) { //send ack if requested
   DDRD.7=1;
   SDA=0;
   delay;
   SCL=1;
   delay;
   SCL=0;
 }
 return value;
}

void i2cStop(){
//I2C stop condition.

 delay; 
 DDRD.7=1; //SDA output mode
 SDA=0;
 delay;
 SCL=1;
 delay;
 SDA=1;
 delay;
}      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -