AVR I2C TC74
Boldak Boldak
hw.news.hw@gmail.com
Neděle Březen 7 17:25:41 CET 2010
Dobry podvecer,
po celodennim boji s I2C to vzdavam a prosim zdejsi profiky o pomoc.
Mam ATtiny 2313 a k tomu pripojeny teplotni senzor TC74, ktery
komunikuje pomoci I2C. SCL je pripojeno na PB7 a SDA je na PDB5.
Oba vodice jsou pres odpory 10k pripojeny na Vdd.
Otazecka pro zacatek, kdyz prijimam ACK pripadne byte z TC74,
musi byt SDA nastaven jako vstupni myslim tim DDRB &= ~(1<<sda)?
Nebo prikaz (PINB,sda) precte skutecnou hodnotu na pinu..??
Diky za kazde nakopnuti..
Zde posilam kod k nahlednuti.
PS: komentaru si zatim nevsimejte.. :)
#include <stdint.h>
#include <avr/io.h>
#include <avr/iotn2313.h>
#include <avr/interrupt.h>
#define F_CPU 11059200
#define scl PB7
#define led PB6
#define sda PB5
#include <util/delay.h>
void I2CInit(){
PORTB |= (1<<sda)|(1<<scl); //sda=1, scl=1
_delay_us(10); //wait 5us
}
void I2CStart(){
PORTB |= (1<<scl); //scl=1
_delay_us(10); //wait 5us
PORTB &= ~(1<<sda); //sda=0
_delay_us(10); //wait 5us
PORTB &= ~(1<<scl); //scl=0
_delay_us(2);
}
void I2CSend(unsigned char Data){
unsigned char i;
for(i=0;i<8;i++){
PORTB &= ~(1<<scl); //scl=0
_delay_us(10); //wait 5us
if((Data&0x80)==0){
PORTB &= ~(1<<sda); //sda = 0;
_delay_us(2); //wait 2us
}
else {
PORTB |= (1<<sda); //sda = 1;
_delay_us(2); //wait 2us
}
PORTB |= (1<<scl); //scl = 1;
_delay_us(10); //wait 5us
Data<<=1; //posune MSB doleva, prvni se vysila MSB
}
PORTB &= ~(1<<scl); //scl = 0;
PORTB |= (1<<sda); //sda = 1;
_delay_us(2); //wait 1us
}
unsigned char I2CRead(){
unsigned char i, data=0;
for(i=0;i<8;i++){
_delay_us(2);
PORTB &= ~(1<<scl); //scl = 0
_delay_us(10);
PORTB |= (1<<scl); //scl = 1
_delay_us(10);
if(PINB,sda){
data |= 1;
}
data<<=1;
}
PORTB &= ~(1<<scl); //scl = 0
PORTB |= (1<<sda); //sda = 1
return (data);
}
void I2CAck(){
PORTB &= ~(1<<sda); //sda = 0
_delay_us(10); //ceka 10us
PORTB |= (1<<scl); //scl = 1
_delay_us(10); //ceka 10us
PORTB &= ~(1<<scl); //scl = 0
_delay_us(2); //ceka 2us
PORTB |= (1<<sda); //sda = 1
}
void I2CNack(){
PORTB |= (1<<sda); //sda = 1
_delay_us(10);
PORTB |= (1<<scl); //scl = 1
_delay_us(10);
PORTB &= ~(1<<scl); //scl = 0
}
/*
void blik (void) {
unsigned char i;
for (i=0;i<1;i++) {
PORTB |= (1<<led);
_delay_ms(100);
PORTB &= ~(1<<led);
_delay_ms(100);
}
}
*/
/*
void svit (void) {
PORTB |= (1<<led);
_delay_ms(500);
}
*/
int main (void)
{
unsigned char aa;
int sto, deset, jedna, pom;
cli(); //zakate preruseni
DDRB |= (1<<sda)|(1<<scl)|(1<<led); //nastavi sda a scl jako vystup
PORTB &= ~(1<<led);
DDRD |= 0xFF; //nastavi led jako vystup
PORTD |= 0xFF; //led zhasne
I2CInit(); //init I2C
I2CStart(); //start
I2CSend(0x91); //vysle addressu TC74 0b10010001, posledni bit0 signalizuje
READ
I2CAck(); //ack ???
aa=I2CRead();
// I2CNack();
pom = aa;
pom /= 100;
sto = pom; //sto = ulozene stovky
pom = 136;
pom -= 100;
pom /= 10;
deset = pom; //deset = desitky
pom = aa;
pom -= 100;
pom -= (deset*10);
jedna = pom; //jedna = jednotky
//deset = 5;
if (deset == 0) {
PORTD = 0b10000001; //0
_delay_ms(50);
}
else if (deset == 1) {
PORTD = 0b1100111; //1
_delay_ms(50); //ceka 50ms
}
else if (deset == 2) {
PORTD = 0b10010010; //2
_delay_ms(50); //ceka 50ms
}
else if (deset == 3) {
PORTD = 0b11000010; //3
_delay_ms(50); //ceka 50ms
}
else if (deset == 4) {
PORTD = 0b11100100; //4
_delay_ms(50); //ceka 50ms
}
else if (deset == 5) {
PORTD = 0b11001000; //5
_delay_ms(50); //ceka 50ms
}
else if (deset == 6) {
PORTD = 0b10001000; //6
_delay_ms(50); //ceka 50ms
}
else if (deset == 7) {
PORTD = 0b11100011; //7
_delay_ms(50); //ceka 50ms
}
else if (deset == 8) {
PORTD = 0b10000000; //8
_delay_ms(50); //ceka 50ms
}
else {
PORTD = 0b11000000; //9
_delay_ms(50); //ceka 50ms
}
return(0);
}
------------- dal?í ?ást ---------------
HTML p?íloha byla odstran?na...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20100307/6030f081/attachment.htm>
More information about the Hw-list
mailing list