Witam,
Czy ktoś ma namiar na projekt oparty o AVR, robiący za przejściówke RS232-I2C? Ewentualnie jakieś porady, jak to szybko ugryźć?
Chciałbym przy pomocy takiego BOX-a mieć możliwość komunikacji z układami I2C z PC/laptopa.
pozdrawiam
Witam,
Czy ktoś ma namiar na projekt oparty o AVR, robiący za przejściówke RS232-I2C? Ewentualnie jakieś porady, jak to szybko ugryźć?
Chciałbym przy pomocy takiego BOX-a mieć możliwość komunikacji z układami I2C z PC/laptopa.
pozdrawiam
Michał T napisał(a):
Tylko nie powiedziałem o jednej zasadniczej rzeczy. Bardzo prosto zrobić przejściówkę hmmm... "softową" - przekonwertować poziomy i programowo sterować liniami bit-po-bicie. Nie wchodzi to w gre w sytuacji, gdy samo RS jest po USB - samo opóżnienie magistrali da mi fatalny transfer, a chodzi o np. wgrywanie softu o wielkości rzędu 1MB.
Przejściówka musi zatem realizować sama wysłanie np. bloku danych o rozsądnej wielkości.
pozdrawiam
Minsu napisał(a):
Robiłem cos takiego od A do Z (konwerter USB na I2C - ATMEGA16 i USBN9603) juz bardzo dawno, przy SCL=800kHz transfer po USB 64kB/s w trybie ISOC, prszy mniejszych czestotliwosciach zegara wykorzystałem przekaz masowy. Biorąc pod uwage ze USBN9603 to starosc radziłbym terz wykorzystac FT2232C (gotowe API udostepnia prod. dla tych co znaja C++ lub Delphi i lubią cos własnego nasmarowac) albo ARM'a AT91SAM7S64- z wykorzystaniem CDC wtedy nie trzeba pisac driver'a a urzadznie widziane jest jako wirtualny com, to co sobie zrobisz po stronie procesora to juz konwersja na dowolna magistrale (no prawie....)
Piotr napisał(a):
Dzięki... Właśnie myślałem o FT232 bo jest tani i działa sprawnie. Napisanie kodu do ATMegi w C++ dużo zajmie czasu początkującemu w AVR (dotychczas robiłem na MCS51, ale tym razem potrzebuję czegoś szybszego)?
pozdrawiam
Moze to ponizej sobie przerob/dostosuj. Kiedys robilem cos takiego - ale nie moge znalezc wersji ostatecznej - tylko tyle mi zostalo.
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <string.h>
#include <avr/delay.h>
#define BAUD 5 //F_CPU/((115200 * 16) - 1) //wpis do UBRR dla UART (5 -
11059200 lub 3 - 7372800)#define TTS_BS 256 #define STT_BS 512
#define ADDRESS 0x21 // adres slave I2C
#define LED1_ON PORTB |= 0x01 #define LED1_OFF PORTB &= 0xFE
#define LED2_ON PORTB |= 0x02 #define LED2_OFF PORTB &= 0xFD
#define IRQ_LINE_ON PORTD&=0xFB //0b1111 1011 #define IRQ_LINE_OFF PORTD|=0x04 //0b0000 0100
volatile unsigned char twi_state; volatile unsigned char twi_reg = 0; volatile unsigned char tts_head = 0; volatile unsigned char tts_tail = 0; volatile unsigned int stt_head = 0; volatile unsigned int stt_tail = 0; //Pointers to circle buffers
volatile unsigned char twi_to_ser[TTS_BS]; //Buffer for TWI->SERIAL volatile unsigned char ser_to_twi[STT_BS]; //Buffer for SERIAL->TWI
//************************************************************************************** //I2C void I2C_init(void) { TWAR = ADDRESS<<1 ; TWBR = 0x01; TWCR = 0x45; TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); }
//************************************************************************************** void port_init(void) { DDRB = 0x03; PORTB = 0x00;
DDRC = 0x00; PORTC = 0x00;
DDRD = 0x06; PORTD = 0x05; }
//************************************************************************************** //RS void USART_Init(void) {
UBRRH = 0; UBRRL = BAUD;
/* Set frame format: 8data, 1stop bit */ UCSRC = (1<<URSEL)|(3<<UCSZ0);
/* Enable receiver and transmitter */ UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); }
//************************************************************************************** void delay_ms(unsigned long ms) {
unsigned long i; ms *= 1000; for (i=0; i < ms; i++) { _delay_us(1); } }
//************************************************************************************** int main (void) { port_init(); twi_state = 255;
LED1_ON; LED2_ON;
USART_Init(); I2C_init();
sei();
while(1) { _delay_ms(500); _delay_ms(500); LED1_OFF; LED2_OFF; }
return(0); } /* void send_data (unsigned char c) { twi_to_ser[tts_head] = c;
tts_head++; if (tts_head > TTS_BS) tts_head = 0; if (tts_head == tts_tail) { tts_tail++; if (tts_tail > TTS_BS) stt_tail = 0; } UCSRB |= (1<<UDRIE); }
*///************************************************************************************** INTERRUPT /*SIGNAL*/ (SIG_2WIRE_SERIAL) { unsigned char status = (TWSR & 0xFC);
//SLAVE TRANSMITTER MODE //odebrano bit startu + adres + bit R if (status == 0xA8) { if (twi_reg == 0) { if (stt_head != stt_tail) { TWDR = ser_to_twi[stt_tail++]; stt_tail &= (STT_BS - 1); if (stt_head == stt_tail) { IRQ_LINE_OFF; }
} else TWDR = 0x00; } else { if (stt_head == stt_tail) TWDR = 0; else TWDR = 1; twi_reg = 0; } }
//SLAVE RECEIVER MODE //odebrano bit startu + adres + bit W if (status == 0x60) { twi_state = 0; //odebrano SLA+W }
// odebrano DATA if (status == 0x80) { if (twi_state == 0) //skoro bylo SLA+W teraz odebrano rejestr { twi_reg = TWDR; twi_state = 1; } else //skoro poprzednio byl rejestr teraz jest dana do podanego rejestru { if (twi_reg == 0) { twi_to_ser[tts_head++] = TWDR; //tts_head &= (TTS_BS - 1); if (tts_head == tts_tail) { tts_tail++; //tts_tail &= (TTS_BS - 1); } UCSRB |= (1<<UDRIE); } if (twi_reg == 2) { UBRRL = TWDR; twi_reg = 0; } } }
LED2_ON; TWCR |= 0x80; }
//************************************************************************************** SIGNAL (SIG_UART_RECV) { ser_to_twi[stt_head++] = UDR;
stt_head &= (STT_BS - 1); if (stt_head == stt_tail) { stt_tail++; stt_tail &= (STT_BS - 1); } LED1_ON; IRQ_LINE_ON; }
//************************************************************************************** SIGNAL (SIG_UART_DATA) {
if (tts_head != tts_tail) { UDR = twi_to_ser[tts_tail++];
//tts_tail &= (TTS_BS - 1);
LED1_ON; } else UCSRB &= ~(1<<UDRIE);
Taddy napisał(a): (...)
dzięki za kod! :-)
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.