Я хочу использовать микроконтроллер и аналого-цифровой преобразователь для высокочастотной (~ 100 кГц) долговременной (минимум пятисекундный буфер, цикл до срабатывания) регистрации данных. Похоже, хороший способ сделать это с помощью SD-карты. Я знаю, что есть разные способы доступа к SD-карте, в том числе напрямую через SPI. Я также считаю, что можно писать в файловую систему или напрямую на карту без файловой системы. Я также обеспокоен тем, что записи должны охватывать целые сектора, а не побайтно, или записи, мешающие продолжению операций АЦП, но это может быть неправомерным.
В настоящее время я использую чипы dsPIC 33, что дает мне скорость команд ~ 60 MIPS; Я готов перейти на другое семейство контроллеров, если это необходимо.
Возможно, вы не сможете сделать это с PIC33, и почти наверняка не с любым PIC33. Некоторые флэш-карты «уходят» на длительные периоды времени (десятки миллисекунд и более), несмотря на высокую пропускную способность, эта задержка может убить вас с маленьким микроконтроллером, потому что у вас закончится буферная оперативная память.
Если вы разрешите буферизацию в течение 200 мс (что должно быть безопасным), вам потребуется 20 КБ слов памяти, которых может не быть у PIC33 (самые большие члены семейства имеют 48 КБ x 8, поэтому, если ваш АЦП занимает два байта, это 40 КБ, а предположительно вашей программе требуется немного оперативной памяти.
При 100 000 выборок в секунду вы также не сможете много обрабатывать данные, просто возьмите их. Я бы предложил использовать оперативную память. И у вас была бы избыточная вычислительная мощность, если бы вы использовали ARM с внешней SDRAM или даже последовательной RAM.
Я делал это раньше, но не помню всех подробностей. Я использовал файловую систему Fat и там был какой-то другой подход, я использовал для передачи блока данных 512 байт. Но то, что вам нужно, я вам точно скажу: круговой буфер, у меня был 16к байт. Когда вы выполняете выборку в ISR, вы записываете в буфер, затем увеличиваете указатель записи, когда разница между указателем wr и rd превышает 512 байтов, вы записываете эти байты на SD и увеличиваете указатель rd. Во всяком случае, это старо, без использования передачи DMA, просто пример. При создании криволинейного буфера используйте размер буфера степени 2, ищите математику, используемую с указателями rd и wr, это упрощается благодаря свойству бинарных чисел rollover, при любом расчете нужно применять маску: & ( size-1), который равен 2 ^ N-1, в моем случае N = 14 -> размер буфера circ = 2 ^ 14 = 16384.
void AddBuffer (char data)
{
CircBuffer[WR_Pointer]=data;
WR_Pointer++;
WR_Pointer= WR_Pointer & 16383;
if (WR_Pointer==RD_Pointer)
{
printf("\r\nBuffer overrun\r\n",0);
stat0_off();
stat1_on();
VICIntEnClr = 0xFFFFFFFF; //clear all interrupts
fat_flush();
while(1);
}
}
char GetBuffer()
{
char res;
if (WR_Pointer==RD_Pointer)
{
res=0; // no data available
printf("\r\nError calling GetBuffer()\r\n",0);
stat0_off();
stat1_on();
VICIntEnClr = 0xFFFFFFFF; //clear all interrupts
fat_flush();
while(1);
}
else
{
res=CircBuffer[RD_Pointer];
RD_Pointer++;
RD_Pointer=RD_Pointer & 16383;
}
return(res);
}
void SD_Card_Log(void)
{
int j;
BufferLength = WR_Pointer-RD_Pointer;
BufferLength = BufferLength & 16383;
if (BufferLength>=512)
{
for (j = 0; j < 512; j++) {
RX_array1[j] = GetBuffer();
}
stat0_off();
stat1_off();
if (fat_write(handle,RX_array1, 512) < 0)
{
while(1) // card failure
{
}
}
трубка
Евгений Ш.
Асмыльдоф
семай
Стивен Коллингс