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

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 пользователей онлайн

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