2017-11-27 08:47 AM
Dear all,
I am trying to acquire analog signal and sample it through ADC (12 bit) at a rate of 8KHz and stream the data through USART.
/* USARTx configured as follows:
- BaudRate = 921600 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitStructure.USART_BaudRate = 921600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;/* USART initialization */
USART_Init(USART2, &USART_InitStructure);/* Enable USART */
USART_Cmd(USART2, ENABLE);I have tried increasing the BaudRate to the maximum possible value, yet, I miss the samples at such a high sampling rate.
How do I fix this? Kindly give me some suggestions.
Thanks.
2017-11-27 08:56 AM
>>How do I fix this? Kindly give me some suggestions.
Don't do everything one sample at a time? Do 100 or 1000, and don't overwrite the buffer you are sending out.
Use some packetizing protocol so you can see where data loss comes from and can resynchronize to the packet boundaries if required.
If the data volume is too high consider more efficient ways of encoding it. ie pack a pair of 12-bit samples into 3-bytes, or do some delta coding.
2017-11-27 03:52 PM
you only have 1 primary concern and that is the timing of the ADC sample.
you code should be setting a timer to direct the ADC to sample periodically.
that code can fill a circular buffer say 20Kbytes long. This is seem-less to the foreground process.
For the outgoing Usart data, use a 'separate buffer pointer set', on the same ADC Buffer,
then your Usart can send when the buffer is not empty.
2017-12-04 07:15 AM
Hi Marsh,
Can you please give me an example code w.r.t UART buffer pointer set?
Right now, I am using the printf using
int __io_putchar(int ch)
{
/* write a character to the USART */
USART_SendData(USART2, (uint8_t)ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{}
return ch;
}�?�?�?�?�?�?�?�?�?
And,
'you code should be setting a timer to direct the ADC to sample periodically.
that code can fill a circular buffer say 20Kbytes long. This is seem-less to the foreground process.'
can be implemented as follows?
volatile uint16_t ADC_Aggregated[ARRAYSIZE];
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_InitStructure.DMA_Channel =DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)&ADC_Aggregated[0];
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ARRAYSIZE; // increase the buffer size for multi-channels
DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord; //16 bits DR register
DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord; // 16 bits user defined variable
DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority =DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode =DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold =DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst =DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst =DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Thanks in advance.