2016-01-19 9 views
5

Impossibile ottenere il rilevamento della velocità di trasmissione automatica per funzionare su STM32L0. Sto usando il livello di astrazione hardware (HAL).Rilevamento automatico della velocità di trasmissione per STM32L0

Il mio codice è initilization:

/* USART1 init function */ 
void MX_USART1_UART_Init(void) 
{ 

    huart1.Instance = USART1; 
    huart1.Init.BaudRate = 300; 
    huart1.Init.WordLength = UART_WORDLENGTH_9B; 
    huart1.Init.StopBits = UART_STOPBITS_1; 
    huart1.Init.Parity = UART_PARITY_EVEN; 
    huart1.Init.Mode = UART_MODE_TX_RX; 
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; 
    huart1.Init.OverSampling = UART_OVERSAMPLING_16; 
    huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED; 
    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; 
    huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; 
    huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; 
    HAL_UART_Init(&huart1); 


} 

I byte Sto mandando l'UART1 è:

 0 1 2 3 4 5 6 7 8 
000x 68 0B 0B 68 53 FD 52 FF FF .. etc. 

0x68 = 0b01101000 
0x0B = 0b00001011 
0xFD = 0b11111101 <-- Character starting with 1, baudrate should be detected 


0xFD : 
    start 1 1 ..... 
___ bit __________ 
    ¦______¦ 
... 

Perché la velocità di trasmissione non essere rilevato? Ho provato:

UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT e UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE

Così ho regolato la cronologia di impostazione della modalità e l'abilitazione nel driver da:

/* if required, configure auto Baud rate detection scheme */    
    if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) 
    { 
    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); 
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); 
    /* set auto Baudrate detection parameters if detection is enabled */ 
    if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) 
    { 
     assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); 
     MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); 
    } 
    } 

a

/* if required, configure auto Baud rate detection scheme */    
    if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) 
    { 
    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart- 
    /* set auto Baudrate detection parameters if detection is enabled */ 
    if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) 
    { 
     assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); 
     MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); 
    } 
    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); 
    } 

non fai qualcosa

Anche la seguente sembra soddisfacente:.

frequenza della sorgente

L'orologio deve essere compatibile con la velocità di comunicazione previsto (ove sovracampionamento del 16, la velocità di trasmissione è tra FCK/65535 e FCK/16 quando sovracampionamento di 8, il baud rate è tra fCK/65535 e fCK/8).

sto sovracampionamento del 16, in modo da

fCK= 16000000 

fCK > 16000000/65535 = 244  = 244 Hz 
fCK < 16000000/16 = 1000000 = 1 MHz 

La mia velocità di trasmissione di scelta sono: 19200/ 9600 /2400 /300

+0

"Mi dispiace, non posso farlo, Flying Swissman." –

risposta

3

Se non è possibile specificare il contenuto preciso di un singolo byte da esaminare dall'hardware di rilevamento della velocità di trasmissione automatica dell'STM32L0, è comunque possibile eseguire il rollover del proprio schema di rilevamento automatico della velocità di trasmissione, se le seguenti ipotesi può essere fatto per il vostro sistema:

  • è consentito di scartare un numero arbitrario di caratteri ricevuti contigui durante il processo di rilevamento di trasmissione auto.

  • Durante qualsiasi intervallo arbitrario in cui vengono ricevuti più caratteri, si può presumere che la sequenza di bit 010 o 101 sia un evento relativamente comune.

  • Il dispositivo dispone di una periferica per timer General Purpose che può essere associata allo stesso pin del segnale USX Rx.

Se tutto quanto sopra sono vere, allora si può creare il proprio schema di rilevamento automatico della velocità rate utilizzando la funzione Cattura di ingresso di uno dei generali periferiche Scopo timer sul chip. Questi timer possono essere configurati per utilizzare l'orologio interno da 16 MHz come sorgente di clock. Ogni timer contiene un contatore a 16 bit. Con un orologio a 16 MHz, il timer ha una risoluzione di misurazione dell'impulso (1/16.000.000 Hz) = 62.5 nS.

La durata di un singolo bit a portata di velocità di trasmissione preferita è la seguente:

Baud Microseconds 62.5-nS Clocks 
---- ------------ -------------- 
    300  3,333.3   53,333 
2400  416.7   6,667 
9600  104.2   1,667 
19200   52.1   833 

Si potrebbe impostare il timer in modalità di ripresa di ingresso, e lo hanno contare il numero di orologi tra due transizioni di bordo adiacenti . Eseguire questa operazione per un numero relativamente elevato di campioni, ad esempio 100. Molti di questi campioni rappresenteranno la larghezza di due o più zeri adiacenti o due o più adiacenti. Ma stai cercando il campione più corto. Se ne trovi uno compreso tra 831 e 835, allora puoi essere ragionevolmente sicuro che la velocità di trasmissione sia 19200. Dopo 100 campioni, se il più breve che hai trovato era compreso tra 1665 e 1669, allora puoi supporre che il baud rate sia 9600. E così via.

Durante questo processo, USART è disabilitato mentre il timer è assegnato al pin. Dopo aver determinato la velocità di trasmissione corretta da utilizzare, riconfigurare il pin per assegnarlo alla funzione periferica USART Rx.

+0

grazie mille –

+0

un peccato non posso fare uso dell'hardware .. –

2

Dalla scheda tecnica (This one, pag 759). "Prima di attivare il rilevamento automatico della velocità di trasmissione, è necessario selezionare la modalità di rilevamento della velocità di trasmissione automatica". -> prova a cambiare le linee di:

huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; `

non credo che farà una grande differenza come si avvia il processo init con HAL_UART_Init(&huart1); comunque. Ma vale la pena provare. Puoi anche controllare la frequenza dell'orologio.

+0

il driver non segue la cronologia eppure la sua regolazione non risolve il mio problema –

+0

Beh, questo è strano, la tua configurazione sembra abbastanza sana di adesso. Hai controllato il flag per lo stato di rilevamento? Inoltre, sta funzionando con un baud rate fisso (immagino tu abbia già provato questo)? – Haini

+0

Intendo il flag di errore ABRE. Fondamentalmente non ho idea di cosa potrebbe andare storto da questo punto in poi, mi spiace ... – Haini

2

Poiché si utilizza ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT (modalità velocità di trasmissione automatica 0), il primo carattere ricevuto dopo l'inizializzazione deve disporre di un MSB elevato affinché il meccanismo di baud automatico funzioni correttamente. Ma tu dici che la sequenza di byte di dati è

68 0B 0B 68 53 FD 52 FF FF .. etc. 

Il primo byte in questa sequenza è 0x68, che ha una bassa MSB. Pertanto, l'hardware di rilevamento automatico del baud scriverà un valore errato nel BRR. Cambia il tuo primo byte per avere un MSB alto, e questo dovrebbe risolvere il tuo problema.


Modifica

Lo STM32L0 dispone di 4 modalità di rilevazione velocità di trasmissione automatica, che consente di specificare le diverse caratteristiche del byte che viene misurato. Dalla RM0367 Reference manual:

Queste modalità sono:

  • Modalità 0: Qualsiasi carattere iniziando con un bit a 1. In questo caso l'USART misura la durata del bit di avvio (discesa a risalita bordo).

  • Modalità 1: Qualsiasi carattere che inizia con un motivo a 10 bit. In questo caso, l'USART misura la durata dell'avvio e del primo bit di dati. La misurazione viene eseguita dal lato di discesa al fronte di discesa, garantendo una migliore precisione in caso di pendenze del segnale lente.

  • Modo 2: Un frame di carattere 0x7F (può essere un carattere 0x7F in modalità LSB prima o un 0xFE in modalità MSB prima). In questo caso, il baud rate viene aggiornato prima alla fine del bit di start (BR), quindi alla fine del bit 6 (in base alla misurazione eseguita dal fronte di discesa al fronte di discesa: BR6). I bit da 0 a 6 vengono campionati su BRs mentre ulteriori bit del carattere vengono campionati su BR6.

  • Modalità 3: una cornice di caratteri 0x55. In questo caso, il baud rate viene aggiornato prima alla fine del bit di start (BRs), quindi alla fine del bit 0 (in base alla misurazione eseguita dal fronte di discesa al fronte di discesa: BR0) e infine alla fine del bit 6 (BR6). Il bit 0 viene campionato ai BR, il bit 1 al bit 6 viene campionato in BR0 e ulteriori bit del carattere vengono campionati in BR6. In parallelo, viene eseguito un altro controllo per ogni transizione intermedia della linea RX. Viene generato un errore se le transizioni su RX non sono sufficientemente sincronizzate con il ricevitore (il ricevitore si basa sulla velocità di trasmissione calcolata sul bit 0).

Se non è possibile garantire che il primo byte ricevuto dopo aver attivato il rilevamento automatico della velocità si inserisce una delle modalità di cui sopra, allora temo che il built-in funzione di rilevamento automatico della velocità non funziona per tu.

Tuttavia, non tutti possono essere persi. Vedi la mia seconda risposta alla tua domanda.

+0

Grazie. Non ho controllo sul primo byte, ma non è deterministico. –

+0

Ho aggiunto una sezione "Modifica" e una seconda risposta che potrebbe essere di aiuto. – sifferman

Problemi correlati