Перейти к содержанию

Sd Через Spi Stm32F415Rgt6


Hedhehog

Рекомендуемые сообщения

Доброго всем времени суток! Ковыряя свое устройство наткнулся на некоторую интересную особенность контроллера, связанную то ли с моей реализацией, то ли с контроллером. Есть задача: сделать устройство, принимающее данные с АЦП и передающее его на карту с помощью SPI (почему не SDIO не спрашивайте-не моя прихоть) с достаточно большой частотой.

Есть реализация: сделано АЦП, циклический буфер для АЦП объемом 8192 элемента, сделано взаимодействие с картой.

Есть проблема: буфер сделан по прерыванию таймера (около микросекунды-несколько меньше). Частота контроллера-максимальная. Так вот, стоит начинать уменьшать делитель таймера-программа беспомощно зависает в прерывании (тупо не выходит из него). Делитель АЦП равен 2. Если оставлять все как есть-запись со скоростью всего лишь 140 -150 секторов в секунду (маловато будет-хорошо бы 300 и более). Привожу код:

Инициализация АЦП

void init_ADC()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitTypeDef gpio;
gpio.GPIO_Mode=GPIO_Mode_AN;
gpio.GPIO_OType=GPIO_OType_PP;
gpio.GPIO_Pin=GPIO_Pin_0;
gpio.GPIO_PuPd=GPIO_PuPd_NOPULL;
gpio.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpio);

ADC_InitTypeDef adc;
adc.ADC_Resolution = ADC_Resolution_12b;
adc.ADC_ScanConvMode = DISABLE;
adc.ADC_ContinuousConvMode = ENABLE;
adc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
adc.ADC_DataAlign = ADC_DataAlign_Right;
adc.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &adc);

ADC_CommonInitTypeDef adc_common;
adc_common.ADC_Mode = ADC_Mode_Independent;
adc_common.ADC_Prescaler = ADC_Prescaler_Div2;
adc_common.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
adc_common.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&adc_common);

ADC_RegularChannelConfig(ADC1, ADC_Channel_Vbat, 1, ADC_SampleTime_3Cycles);

ADC_Cmd(ADC1, ENABLE);
ADC_VBATCmd(ENABLE);	
ADC_SoftwareStartConv(ADC1);	
}

Инициализация таймера:

[/size][/font][/color]
[color=#000000][font=Lucida Grande', ', ', 'Trebuchet MS', ', Helvetica, Arial, sans-serif][size=3]void init_Timer()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseInitTypeDef tim;

tim.TIM_Prescaler=6;//26 и более работает, 14-уже нет, 15 нестабильно.
tim.TIM_CounterMode=TIM_CounterMode_Up;
tim.TIM_Period = 1;
tim.TIM_ClockDivision = 0;
tim.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &tim);

TIM_UpdateRequestConfig (TIM1, TIM_UpdateSource_Global);
TIM_UpdateDisableConfig (TIM1,DISABLE);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM1, DISABLE);

NVIC_InitTypeDef NVIC_InitStructure
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

Кольцевой буфер:

void TIM1_UP_TIM10_IRQHandler(void)
{
if(ADC_Free_Index + 1 == ADC_Busy_Index)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);		
return;	
}
GPIO_SetBits(GPIOB,GPIO_Pin_14);
ADC_Buffer[ADC_Free_Index++] = ADC_GetConversionValue(ADC1);
if(ADC_Free_Index==8192)
 if(ADC_Busy_Index!=0)
 ADC_Free_Index=0;
else
 ADC_Free_Index--;	
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);	
}[/size][/font][/color]
[color=#000000][font=Lucida Grande', 'Trebuchet MS', Helvetica, Arial, sans-serif][size=3]int16_t Get_Byte()// функция забора байт, есть еще функция упаковки, однако в случае зависания туда программа не добирается.
{
if(ADC_Busy_Index==ADC_Free_Index)
 return -1;[/size][/font][/color]
uint16_t saveInd = ADC_Busy_Index;
if(++ADC_Busy_Index == 8192)
 ADC_Busy_Index=0;
return (int16_t)ADC_Buffer[saveInd];
}

Main

[/size][/font][/color]
[color=#000000][font=Lucida Grande', 'Trebuchet MS', Helvetica, Arial, sans-serif][size=3]void main()
{
for(uint16_t i = 0; i < 8192; i++)
ADC_Buffer[i] = 0;
__enable_irq();
maxADR.MaxAdr=0;
adr.Nseg=0x0;
init_LED();
init_USART();
init_SPI();
init_ADC();
Init_Card();
Send_CSD();
Fast_SPI();
init_Timer();
TIM_Cmd(TIM1, ENABLE);
while(1)
{			
 Pack_Block();		
 Write_Block();	
}
}

Что еще хотелось бы узнать-так это нормальную скорость передачи на данном интерфейсе.

Заранее благодарен за любую помощь.

З.Ы. Не понял как код убрать в спойлер и как убрать сообщения о размере шрифтов-они появляются вновь-поэтому получилось кривовастенько))

Изменено пользователем Hedhehog
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • правильно мыслишь... скорее всего надо увеличить сопротивление R1 до 2-3 кОм.. (или R3)..
    • @r9o-11 Я про перемотку трансформатора. Не, возможно если магнитопроводов под рукой запас, провода запас, станочек есть, рука набита - тогда да, это будет быстрее и проще. Но мне кажется что в современных реалиях добыть два импульсных БП подходящей мощности всё-же легче. А человеку далёкому от электроники - гораздо легче. 
    • Нужен электронный реостат для нагрузки блоков питания. Т.е. я собираю не электронную нагрузку, а электронный реостат. Здесь нет стабилизации ни тока, ни напряжения. Слева - подается питающее напряжение, справа - подключается исследуемый блок питания. Когда движок потенциометра внизу транзистор закрыт и ток через него практически не идет. Сдвигая движок, транзистор приоткрывается и начинает пропускать ток. Тем самым создаем нагрузку для исследуемого блока питания. Но возник вопрос. Одновременно оба напряжения - питающее и исследуемое подаваться не будут. И получается, что в какой то момент времени транзистор будет работать с оборванной базой или с оборванным коллектором. Допустимо ли это? Не повредится ли он?
    • Вот это плохие новости. Я был готов к такому повороту, но у меня всегда был уверенный запуск с ППГ сердечниками, термообработанными без наложения поля (с индексом N). ППГ подходят лучше всего, особенно для мощных ключей – обеспечивают наименьшие динамические потери, с ними можно увеличивать номинал балластного резистора в цепи ПОС. Еще лучше с отжигом в продольном поле, но от однополярного динисторного пускача, такие точно будут запускаться с вероятностью ровно 50%. При желании  выкрутиться можно и с очень высокой прямоугольностью, если запускающие импульсы будут поочередно-разнополярными, в этом случае обеспечен 100% запуск независимо от того, в каком квадранте находилась остаточная индукция перед запуском.
×
×
  • Создать...