Bonjour a tous,

j'essaie de mettre en place un soft-uart sur un atmega8 (la finalité étant de porter sur un at90s2313, déjà en place sur son PCB, ce qui ne le laisse pas la possibilité d'utiliser l'uart matériel)

seul l'émission m’intéresse, a un baud rate de 2400 bps.

J'ai trouvé un code non commenté, qui après adaptation et suppression de ce qui ne me semble pas utile (réception notamment) s’avère fonctionner a 2400 bps sur un atmega a 1mhz (fuse non modifiée)

C'est un pur hasard (et je l'ai trouvé grace a mon analyseur logique...), et je cherche comment et calculé le baud rate sur ce code, qui utilise des timers, avec lesquels j’évite malheureusement de me familiariser depuis que j'utilise des µC (mais il va falloir que j'y passe)

Je pense qu'ici, pour jouer avec le baud rate, la seule chose importante est T0_PRELOAD (en rouge dans le code) et les préscaler définis dans le MAIN . Je n'arrive pas a faire la bonne démarche psychologique pour en trouver la relation, pouvez-vous m'aider a comprendre le calcul a faire? Pourquoi en l'état cela fonctionne à 2400bps?

Merci.

Voici le code, j’espère qu'il ne sera pas trop long...

Code:
#define F_CPU 1000000UL
#define   T0_PRELOAD 207		// 1   Bit

#define Tx_M_BIT		(1<<PD3)		// hw-uart TxD pin

volatile unsigned char bTxFlag;		//
#define   TX_M_SEND  		 1			//

volatile unsigned char bTxState;		// current state
#define   TX_C_START		0			// send startbit
#define   TX_C_BITS			1			// send 8 bits
#define   TX_C_STOP			2			// send stopp-bit
#define   TX_C_FINISH		3			// wait 1 bit length (appnote)
#define   TX_C_END			4			// done

volatile unsigned char bTxCount;		// Bit-Counter 0-7

volatile unsigned char bTxByte;		// Byte to send


// ---------------------------------------------------
//   TIME Interrupt
// ---------------------------------------------------
ISR(TIMER0_OVF_vect) 
{
	TCNT0 = T0_PRELOAD;
	if (bTxFlag & TX_M_SEND)
	{
		switch (bTxState)
		{
			case	TX_C_START:
			PORTD	&= ~Tx_M_BIT;      //  Start
			bTxState = TX_C_BITS;
			break;
			case	TX_C_BITS:
			if (bTxByte & 0x01)	PORTD |= Tx_M_BIT;    //     clr Data Bit
			else					PORTD &= ~Tx_M_BIT;      //     Set Data Bit
			bTxByte >>= 1;									// shift right data
			bTxCount++;		    		// count
			if (bTxCount & 0x08)
			bTxState = TX_C_STOP;
			break;
			case	TX_C_STOP:
			PORTD	|= Tx_M_BIT;      		//     STOP
			bTxState = TX_C_FINISH;
			break;
			case	TX_C_FINISH:
			bTxState = TX_C_END;
			break;
			case	TX_C_END:
			default:
			bTxFlag &= ~TX_M_SEND;        	// all done
			break;
		}
	}
}
// --------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------
void _send_one_byte(char bByte)
{
	bTxState 	= TX_C_START;		// state: start
	bTxByte  	= bByte;			// data byte
	bTxCount	= 0;				// count = 0
	TCNT0 	 = T0_PRELOAD;
	TIFR 	&= ~(1<<TOV0);        // clear Timer Ovfl
	TIMSK 	|= (1<<TOIE0);        	// enable T/C0 overflow interrupt
	bTxFlag 	|= TX_M_SEND;		// activate transmission
	while (bTxFlag & TX_M_SEND);		// activate transmission
}
// --------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------

// ---------------------------------------------------
//  M A I N
// ---------------------------------------------------
int main (void)
{
	char	bTxt[24] = "\r\nHello, World\r\n";
	unsigned char bIx;
	unsigned char bLn;
	DDRD 	 =  (1<<DDD3);					// Port as Output	TX
	
	PORTD 	= 0; 				  	// Clear all
	PORTD 	|= Tx_M_BIT;           	// Clear (Line inactive)

	TCCR0 &= ~(1<<CS00); 			// Timer clock = system clock / 8
	TCCR0 |=  (1<<CS01); 			// Timer clock = system clock / 8
	TCCR0 &= ~(1<<CS02); 			// Timer clock = system clock / 8

	UCSRA = 0;
	UCSRB = 0;

	TIFR 	&= ~(1<<TOV0);       	// clear T/C0 overflow flag
	TIMSK 	|= (1<<TOIE0);     	// enable T/C0 overflow interrupt
	TCNT0 	 = T0_PRELOAD;


	// ------------------------------------------------------------
	sei();
	// ------------------------------------------------------------
	bLn = strlen(bTxt);
	for (bIx = 0;bIx < bLn; bIx++)
	_send_one_byte(bTxt[bIx]);
	
	while (1)
	{
		
			_delay_ms(10);
			_send_one_byte(0xaa);	// echo
			_delay_ms(10);
			_send_one_byte('a');	// echo
	}
}