} while (by!=0);
//read CID
// MMCCommand (MMC_READ_CID, 0); // nothing really interesting here
//read CSD Card Specific Data
MMCCommand (MMC_READ_CSD, 0);
//This worked with extrememory MMC and takeMS SD
// SPI_WRITE(0xFF); // ignore response 0xFE
// SPI_WAIT();
// This waiting loop is for SanDisk 256MB SD
// Works with my other cards too
do
{
SPI_WRITE(0xFF);
SPI_WAIT();
} while (SPDR!=0xFE); // wait for card response
for (i=0; i<16; i++) //CSD has 128 bits -> 16 bytes
{
SPI_WRITE(0xFF);
SPI_WAIT();
by=SPDR;
// ShowHex(by);
dirbuf[i]=by;
}
SPI_WRITE(0xFF); // 16 bit crc follows data
SPI_WAIT();
SPI_WRITE(0xFF);
SPI_WAIT();
//here comes the hard stuff!
//calculate disk size and number of last sector
//that can be used on your mmc/sd card
c_size=dirbuf[6] & 0x03; //bits 1..0
c_size<<=10;
c_size+=(unsigned int) dirbuf[7]<<2;
c_size+=dirbuf[8]>>6;
by= dirbuf[5] & 0x0F;
read_bl_len=1;
read_bl_len<<=by;
by=dirbuf[9] & 0x03;
by<<=1;
by+=dirbuf[10] >> 7;
c_size_mult=1;
c_size_mult<<=(2+by);
drive_size=(unsigned long) (c_size+1) * (unsigned long) c_size_mult * (unsigned long) read_bl_len;
maxsect= drive_size / BYTE_PER_SEC;
MMC_CS_ON();
//switch to high speed SPI
// SPR1=0; //SPI Clock = f/4 = 4MHz @16MHz Clock
// SPR0=0; //or f/2 if SPI2X = 1 in SPSR register
SPCR=0x50;
//SPSR SPI Statusregister
// SPI2X=1; //Double speed for SPI = 8MHz @16MHz Clock
SPSR=0x01;
return 0;
}
2) Работа с микросхемой часов реального времени
// #########################################################################
// File: rtc.c
//
// Функции для работы с микросхемой реального времени
#########################################################################
// Compiler: AVR-GCC 4.1.1
// ##################################################################
#include <avr/io.h>
#include «rtc.h»
// инициализируем шину TWI (I2C)
void Init_Timer() {
TWBR = 29;
TWCR = (1<<TWEN); //Enable TWI-interface
}
// декодированиебайтаизформата BCD
unsigned char DECODER (char x) {
unsigned char y;
y=0;
if (x&0x80) y+=80;
if (x&0x40) y+=40;
if (x&0x20) y+=20;
if (x&0x10) y+=10;
if (x&0x08) y+=8;
if (x&0x04) y+=4;
if (x&0x02) y+=2;
if (x&0x01) y+=1;
return y;
}
// кодированиебайтавформата BCD
unsigned char CODER (char x) {
unsigned char y;
y=0;
if (x>79) {y|=0x80; x-=80;}
if (x>39) {y|=0x40; x-=40;}
if (x>19) {y|=0x20; x-=20;}
if (x>9) {y|=0x10; x-=10;}
if (x>7) {y|=0x08; x-=8;}
if (x>3) {y|=0x04; x-=4;}
if (x>1) {y|=0x02; x-=2;}
if (x>0) {y|=0x01; x-=1;}
return y;
}
// чтение времени из RTC – 8564 JE
void Timer_Read() {
unsigned char d;
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //START TWI
while (! (TWCR & (1<<TWINT)));
TWDR=SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //START TWI – repeated start
while (! (TWCR & (1<<TWINT)));
TWDR=SLA_R;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
d=TWDR&0x7f;
clock.sec=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
d=TWDR&0x7f;
clock.min=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
d=TWDR&0x3f;
clock.hour=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
d=TWDR&0x3f;
clock.day=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); //weekdays here
while (! (TWCR & (1<<TWINT)));
d=TWDR&0x1f;
clock.month=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (! (TWCR & (1<<TWINT)));
d=TWDR;
clock.year=DECODER(d);
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
// установка времени в RTC – 8564 JE
void Timer_Set()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //START TWI
while (! (TWCR & (1<<TWINT)));
TWDR=SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0; //adress
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0; //write fist byte
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR =0; //write second byte
TWCR = (1<<TWINT) | (1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.sec);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.min);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.hour);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.day);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=1; //weekdays ignore
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.month);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWDR=CODER (clock.year);
TWCR=(1<<TWINT)|(1<<TWEN);
while (! (TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
3) работа с последовательными портами
// ##################################################################
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include «serial0.h»
#define sbi (portn, bitn) ((portn)|=(1<<(bitn)))
#define cbi (portn, bitn) ((portn)&=~(1<<(bitn)))
//////////////////////////////////////////////////////////////////////////
// // Interrupt handlers
// // Global functions
// //////////////////////////////////////////////////////////////////////////
// // Initialize the serial port
// void SER0Init(void)
{
// Set TxD as output
sbi (TX0_DDR, TX0_PIN);
sbi (TX0_PORT, TX0_PIN);
// Enable RxD/TxD
UCSR0B=(1<<RXEN0) |(1<<TXEN0) | (1<<RXCIE0);
// Set baudrate
UBRR0H=(unsigned char) (UART0_BAUD_SELECT>>8);
UBRR0L=(unsigned char) (UART0_BAUD_SELECT);
// 8bit, 1 stop, no parity
UCSR0C=(1<<UCSZ01) | (1<<UCSZ00);
}
// Send character
// Waits until previous character is transmitted
void SER0Putc (unsigned char c)
{
// Wait until previous character is transmitted
while (bit_is_clear (UCSR0A, UDRE0))
;
UDR0=c;
}
// Send a string
void SER0Puts (unsigned char * s)
{
unsigned char c;
while((c=*s++))
{
if (c == '\n')
{
// Translate \n in \r\n
SER0Putc(0x0D);
SER0Putc(0x0A);
}
else
SER0Putc(c);
}
}
// Send a hexadecimal number
void SER0PutHex (unsigned char by)
{
unsigned char buff;
// High nibble
buff = by >> 4;
if (buff < 10)
buff += '0';
else
buff += 0x37;
SER0Putc(buff);
// Loz nibble
buff = by & 0x0f;
if (buff<10)
buff+='0';
else
buff+=0x37;
SER0Putc(buff);
}
// Get received character from buffer
// when no character is available the function
// will wait
unsigned char SER0Getc(void)
{
unsigned char c;
// Wait until at least 1 character is present
while (bit_is_clear (UCSR0A, RXC0))
;
c = UDR0;
return (c);
}
// Check of there are characters present
// rcnt is 0 when there are no characters
//
unsigned char SER0CharsPresent(void)
{
return bit_is_set (UCSR0A, RXC0);
}