RS232 --> AVR --> I2C

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

Reply to
Minsu
Loading thread data ...
Reply to
invalid unparseable

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

Reply to
Minsu
Reply to
invalid unparseable

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....)

Reply to
Piotr

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

Reply to
Minsu

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);

Reply to
Taddy

Taddy napisał(a): (...)

dzięki za kod! :-)

Reply to
Minsu
Reply to
invalid unparseable

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.