Code:
#include <TID.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#define _PORT PORTD
#define _DDR DDRD
#define _PIN PIND
#define _SCL_out 0
#define _SCL_in 1
#define _MRQ_out 2
#define _MRQ_in 3
#define _SDA_out 4
#define _SDA_in 5
#define _AA 6
#define _address 0x4A
#define _step 128
char string[9] = "TEST ";
volatile char symbol[2], buffer[10];
volatile uint8_t state, mark, bitToSend, ByteToSend, cyclesRem;
void MRQ_high(void){
_PORT &= ~(1<<_MRQ_out);
}
void MRQ_low(void){
_PORT |= (1<<_MRQ_out);
}
void SCL_high(void){
_PORT &= ~(1<<_SCL_out);
}
void SCL_low(void){
_PORT |= (1<<_SCL_out);
}
void SDA_high(void){
_PORT &= ~(1<<_SDA_out);
}
void SDA_low(void){
_PORT |= (1<<_SDA_out);
}
uint8_t get_MRQ(void){
return (_PIN & (1<< _MRQ_in));
}
uint8_t get_SCL(void){
return (_PIN & (1<< _SCL_in));
}
uint8_t get_SDA(void){
return (_PIN & (1<< _SDA_in));
}
void init_DDR(void){
_DDR = (0<< _MRQ_in | 1<< _MRQ_out | 0<< _SCL_in | 1<< _SCL_out | 0<< _SDA_in |1<< _SDA_out | 1<<_AA);
}
void init_timer(void){
TCCR2 = (0<<FOC2 | 0<<WGM20 | 0<<COM21 | 0<<COM20 | 0<<WGM21 | 1<<CS22 | 1<<CS21 | 1<<CS20); //normal operation, prescaler 1024
TIMSK &= ~(1<<TOIE2 | 1<<OCIE2); //timer2 overflow/output compare interrupt disabled
}
void enable_timer_int(void){
TIMSK |= (1<<TOIE2); //timer2 overflow interrupt enabled
}
void disable_timer_int(void){
TIMSK &= ~(1<<TOIE2); //timer2 overflow interrupt disabled
}
void start_timer_ns(uint16_t ns){
uint16_t steps = (ns/_step);
cyclesRem=steps/256;
TCNT2=(steps-(cyclesRem*256));
enable_timer_int();
}
void start_timer_us(uint16_t us){
uint16_t steps = (1000*(us/_step));
cyclesRem=steps/256;
TCNT2=(steps-(cyclesRem*256));
enable_timer_int();
}
void delay_50us(uint8_t i){
for(;i>0;i--){
_delay_us(50);
}
}
void TID_on(void){
_PORT |= (1 << _AA); //set bit
for(uint8_t i=0; i<100;i++){ //warte 1sec
_delay_ms(10);
}
state=1;
}
void TID_off(void){
_PORT &= ~(1<< _AA); //clear bit
state=0;
}
void TID_init(void){
init_DDR();
init_timer();
SDA_high();
SCL_high();
MRQ_high();
sei();
}
void send_start(void){
PORTC=1;
MRQ_low();
while(get_SDA()); //warte bis SDA low
delay_50us(2);
MRQ_high();
PORTC=2;
while(!get_SDA()); //warte bis SDA high
delay_50us(2);
SDA_low();
delay_50us(3);
SCL_low();
delay_50us(3);
PORTC=3;
}
void send_stop(void){
SDA_low();
delay_50us(2);
MRQ_high();
delay_50us(2);
SCL_high();
delay_50us(2);
SDA_high();
delay_50us(2);
}
void send_bit(uint8_t bit){
if(bit){ //put bit on bus
SDA_high();
}else{
SDA_low();
}
_delay_us(5);
SCL_high(); //set bit valid
while(!get_SCL()); //wait for slave
delay_50us(1); //wait
SCL_low();
_delay_us(50);
}
uint8_t end_Byte(void){
uint8_t ack;
SDA_high();
delay_50us(1);
SCL_high();
while(!get_SCL());
ack=get_SDA();
delay_50us(1);
SDA_low();
while(!get_SDA());
delay_50us(2);
return ack;
}
void send_Byte(char Byte){
uint8_t parity=1;
for(uint8_t i=6; i>0; i--){
if((Byte & ~(1<<i))){
parity = !parity;
}
send_bit((Byte & ~(1<<i)));
}
send_bit(parity);
PORTC=end_Byte();
}
void TID_update(void){
TID_init();
TID_on();
symbol[0]=0x10;
symbol[1]=0x01;
send_start();
send_Byte(_address);
delay_50us(2);
MRQ_low();
delay_50us(2);
for(uint8_t i=0; i<2;i++){
send_Byte(symbol[i]);
}
for(uint8_t i=0; i<8;i++){
send_Byte(string[i]);
}
send_stop();
}
hier ist er
schaltung ist einfach immer ein ausgang um mit einem transistor die jeweilige leitung auf gnd zu ziehen und ein eingang um den pegel abzugreifen.
es müsste uach durch umschalten des ddr gehen aber das hab ich noch nicht implementiert
mfg
Lesezeichen