[an error occurred while processing this directive]
Ответ: Держи.
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
миниатюрный аудио-видеорекордер mAVR

Отправлено Bill 30 июля 2002 г. 15:07
В ответ на: Если только на СИ на АСМе есть отправлено СашенькаА 30 июля 2002 г. 15:04

#include "I2Cmaster.h"

/* Function ptototypes */

static void _delay(void),
_delay2(void);
static void I2CStart(void);
static void _txByte(char);
static void I2C_WrAddr(void);
static void I2CStop(void);

/* Global variables definition */

volatile char I2C_Flags; // I2C flags
volatile char I2C_Slave; // I2C slave device address
volatile unsigned I2C_Addr; // I2C device data address
volatile char I2C_Buffer[8]; // Buffer

//
// ** I2CInit -- the routine to initiate I2C ports
//
void I2CInit(void)
{
I2C_Flags = 0; // Reset flags
I2C_Output |= (SDA_BIT | SCL_BIT);
I2C_DDR |= (SDA_BIT | SCL_BIT);
}
//
// ** I2C_Rd1Byte -- Read 1st byte from I2C
//
char I2C_Rd1Byte(void)
{
I2C_WrAddr(); // Write the required address info
I2CStart(); //
_txByte(I2C_Slave | 0x01); // Specify READ mode for the slave device
return I2C_RdByte(1); // Read data
}
//
// ** I2C_RdByte -- the routine receives 8 data bits
//
char I2C_RdByte(char _flag)
{
char _count = 8, _byte = 0;

I2C_DDR &= ~SDA_BIT; // Make SDA line as input
I2C_Output |= SDA_BIT; // Enable pull-up resistor
do { // Reception
_byte <<= 1;
I2C_Output |= SCL_BIT; // Set clock to high
_delay(); //
if (I2C_Input & SDA_BIT)//
_byte |= 0x01;
I2C_Output &= ~SCL_BIT; // Return clock to low
_delay(); //
}
while (--_count);
I2C_DDR |= SDA_BIT; // Make SDA line as output
_delay(); //
if (!_flag) // For the last received byte send NACK signal
I2C_Output |= SDA_BIT;
else // otherwise send ACK signal
I2C_Output &= ~SDA_BIT;
I2C_Output |= SCL_BIT; // Set clock to high
_delay();
I2C_Output &= ~SCL_BIT; // Return clock to low
_delay();
return _byte;
}
//
// ** I2C_RdLastByte -- the routine reads the last byte from I2C
//
char I2C_RdLastByte(void)
{
char _byte;

_byte = I2C_RdByte(0); // Read the data
I2CStop(); // Generate STOP condition
return _byte; // and return
}
//
// ** I2C_Wr1Byte -- Write 1st byte to I2C
//
void I2C_Wr1Byte(char _byte)
{
I2C_WrAddr(); // Write the required address info
_txByte(_byte); // Write the data
}
//
// ** I2C_Wr1LastByte -- Write only 1 byte to I2C
//
void I2C_Wr1LastByte(char _byte)
{
I2C_Wr1Byte(_byte); // Write the byte
I2CStop(); // Generate STOP condition
}
//
// ** I2C_WrLastByte -- Write last byte to I2C
//
void I2C_WrLastByte(char _byte)
{
_txByte(_byte); // Write the data
I2CStop(); // Generate STOP condition
}
//
// ** I2C_WrAddr -- Write the Slave and Slave data addresses to I2C
//
static void I2C_WrAddr(void)
{
I2CStart(); // Generate START bit
_txByte(I2C_Slave); // Send the slave device address
if (I2C_Flags & FLASH_BIT ) // Flash memory access
_txByte(I2C_Addr>>8); // then send the flash data address high
_txByte(I2C_Addr); // then low
}
//
// ** _txByte -- the routine transmits 8 data bits
//
static void _txByte(char _byte)
{
char _count;

I2C_Output &= ~SCL_BIT; // Set clock to low
_count = 8;
I2C_DDR |= SDA_BIT; // Make SDA line as output
do { // Transmission
_delay();
if (_byte & (1<<7))
I2C_Output |= SDA_BIT;
else
I2C_Output &= ~SDA_BIT;
_byte <<= 1; _NOP(); _NOP();
I2C_Output |= SCL_BIT; // Set clock to high
_delay(); //
I2C_Output &= ~SCL_BIT; // Return clock to low
}
while (--_count);
_delay(); //
I2C_DDR &= ~SDA_BIT; // Make SDA line as input
_byte = 0;
I2C_Output |= SCL_BIT; // Set clock to high
_delay(); //
if (I2C_Input & SDA_BIT)// For ACK high
_byte = 0xFF;
I2C_Output &= ~SCL_BIT; // Return clock to low
// return _byte;
}
//
// ** I2CStart -- the function asserts start condition
//
static void I2CStart(void)
{
I2C_Output |= SDA_BIT; // Make sure SDA is high
I2C_DDR |= SDA_BIT; // Return SDA line to output state
I2C_Output &= ~SCL_BIT; // Set SCL low
_delay(); //
I2C_Output |= SCL_BIT; // Set SCL high
_delay(); //
I2C_Output &= ~SDA_BIT; // SDA goes low during SCL high
_delay(); //
I2C_Output &= ~SCL_BIT; // Set SCL low
}
//
// ** I2CStop -- the function asserts stop condition
//
static void I2CStop(void)
{
I2C_DDR |= SDA_BIT; // Return SDA line to output state
I2C_Output &= ~SCL_BIT; // Force SCL
I2C_Output &= ~SDA_BIT; // and SDA low
_delay(); // Half period delay
I2C_Output |= SCL_BIT; // Set SCL high
_delay(); // Quarter period delay
I2C_Output |= SDA_BIT; // Set SDA high
_delay(); // Half period delay
}
//
// ** _delay2 -- I2C clock half period delay
//
static void _delay2(void)
{
_delay();
_delay();
}
//
// ** _delay -- I2C clock quarter period delay
//
static void _delay(void)
{
char _count = 9;
while (--_count);
}
//
// ** I2C_RdBlock -- the routine reads a data block (8 bytes)
// from a I2C slave device to I2C buffer
//
void I2C_RdBlock(void)
{
char *_cp = I2C_Buffer, // a pointer to buffer
_cnt = 6; // and byte counter

*_cp++ = I2C_Rd1Byte(); // Read the 1st byte
do {
*_cp++ = I2C_RdByte(1); // Read all others excluding the last byte
}
while (--_cnt);
*_cp = I2C_RdLastByte(); // Read the last byte
}

//
// ** I2C_WrBlock -- the routine writes a data block (8 bytes)
// to a I2C slave device to I2C buffer
//
void I2C_WrBlock(void)
{
char *_cp = I2C_Buffer, // a pointer to buffer
_cnt = 6; // and byte counter

I2C_Wr1Byte(*_cp++); // Write the 1st byte
do {
_txByte(*_cp++); // Write all others excluding the last byte
}
while (--_cnt);
I2C_WrLastByte(*_cp); // Write the last byte
}


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru