Чойто не работает то? Используй таймер а не SYSTICK, т.к. последний забирается самой RTOS для организации многозадачности.
Вид для печати
Чойто не работает то? Используй таймер а не SYSTICK, т.к. последний забирается самой RTOS для организации многозадачности.
это понятно, но на практике не прокатывает
file stm32f4xx_it.c
brief Interrupt Service Routines.
в этом файле у меня вся обработка по таймеру.
Делаю тоже с RTOS и прерывания не работают, как будто их лочит RTOS
Ну вот у меня в проекте есть RTOS. Я делаю так:
Да, я люблю прямое обращение к регистрам, но это не принципиально. Это инит таймера. Сам обработчик оформляю в main.c так:Код:// Настройка таймера
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
// Запуск таймера TIM3 если он стоял (зависимость модуля от таймера)
TIM3->PSC = 0x00A7; TIM3->ARR = 0xFFFF; TIM3->CCMR1 = 0x0000; TIM3->CCMR2 = 0x3131;
TIM3->CCER = 0x3300; TIM3->SMCR = 0x0000; TIM3->DIER = 0x0000; TIM3->CR1 = 0x0001;
// Включаем прерывания
NVIC_EnableIRQ(TIM3_IRQn);
TIM3->DIER = (TIM3->DIER & ~TIM_DIER_CC1IE) | TIM_DIER_CC3IE;
А в стартовом коде не забываем выставить приоритеты нужным нам прерываниям:Код:// Прерывание таймера TIM3
void TIM3_IRQHandler ( void )
{
TIM3_IRQ();
}
Резюмирую: Чудес не бывает. STM32 сложнее АТмеги и там надо все делать руками. Т.е., для активации всей цепочки прерываний надо обязательно включить [тактирование] всего оборудования, что ты используешь (без исключений). Надо выставить все необходимые флаги и маски в настройках самого устройства (источники прерываний). Надо активировать необходимые прерывания в контроллере прерываний NVIC, при использовании всяких RTOS - дополнительно распределить приоритеты. Перехватить сам вектор прерывания (по умолчанию все неиспользованные вектора стоят как .weak и для перехвата просто достаточно объявить их в main.c). Если используются ноги - то и там следует настроить AF. Как-то так...Код:static void NVIC_Configuration ( void )
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1 );
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init( &NVIC_InitStructure );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
}
Я всю конфу делаю через STM32Cube
И это печально. (с) Кубик полезен только при планировании ножек и расчета коэффициентов дерева тактирования. В остальном он бесполезен, ибо генерирует тонну говна.
Насчет лишнего я не настолько профи в STM32, мне кажется очень удобная программа.
- - - Добавлено - - -
Буду пробовать пока без RTOS.
san010101, ну есть же тэг CODE, блин...
- - - Добавлено - - -Код:void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
static unsigned char byte=0;//выдаваемый байт
static unsigned char index=0;//номер выдаваемого бита
static unsigned short addr=0;//текущий адрес
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
/************************************************** ****************************/
switch (TapeOutMode)
{
/***********************пилот для заголовка************************************/
case TAPE_OUT_LEAD_H:
{
if (tim6_countersec < 8063)//5 secund
{
if (tim6_counter == 21)//807Hz
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//обнуляем счетчик
tim6_countersec++;//счетчик секунд (5)
}
tim6_counter++;//счетчик 807Hz
//return;
break;
}
else
{
TapeOutMode=TAPE_OUT_SYNCHRO_1;//переход на синхро 1
TapeOutModeStart=TAPE_OUT_START_H;//флаг выбор старта пилота заголовка
tim6_counter = 0;//обнуляем счетчик
tim6_countersec = 0;//обнуляем счетчик
//gui_draw();
//return;
break;
}
}
break;
/***********************пилот для данных***************************************/
case TAPE_OUT_LEAD_D:
{
if (tim6_countersec < 3223)//2 secund
{
if (tim6_counter == 21)//807Hz
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//обнуляем счетчик
tim6_countersec++;//счетчик секунд (2)
}
tim6_counter++;//счетчик 807Hz
//return;
break;
}
else
{
TapeOutMode=TAPE_OUT_SYNCHRO_1;//переход на синхро 1
TapeOutModeStart=TAPE_OUT_START_D;//флаг выбор старта пилота данных
tim6_counter = 0;//обнуляем счетчик
tim6_countersec = 0;//обнуляем счетчик
//return;
break;
}
}
break;
/***********************синхро 1***********************************************/
case TAPE_OUT_SYNCHRO_1:
{
if (tim6_counter == 6)// ~ 171,4 мксек
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//обнуляем счетчик
TapeOutMode=TAPE_OUT_SYNCHRO_2;//переход на синхро 2
//return;
break;
}
tim6_counter++;//счетчик ~ 171,4 мксек
//return;
break;
}
break;
/***********************синхро 2***********************************************/
case TAPE_OUT_SYNCHRO_2:
{
if (tim6_counter == 7)// 200 мксек
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//обнуляем счетчик
//TapeOutMode=TAPE_OUT_DATA;
//TapeOutMode=TAPE_OUT_HEAD;
//index=0;
//byte=0;
//addr=0;
if (TapeOutModeStart==TAPE_OUT_START_H)//условия старта при пилоте заголовка
{
TapeOutMode=TAPE_OUT_HEAD;//режим вывода данных заголовка (0x1A байт )
index=0;//первоначальное значение бита
byte =0;//первоначальное значение байта
addr =0;//первоначальное значение первого байта в буфере
}
else if (TapeOutModeStart==TAPE_OUT_START_D)//условия старта при пилоте данных
{
TapeOutMode=TAPE_OUT_DATA;
index=0;//первоначальное значение бита
byte =0;//первоначальное значение байта
addr=0x1+0x17;//первоначальное значение байта в буфере после чтения заголовка
}
//return;
break;
}
tim6_counter++;//счетчик ~ 200 мксек
//return;
break;
}
break;
/***********************вывод данных HEAD**************************************/
case TAPE_OUT_HEAD:
{
//if (index>7)//проверка на чтение бит
// {
if (addr>=0x17)//проверка на чтение байт из буфера(для заголовка 0x17)
{
TapeOutMode=TAPE_OUT_LEAD_D;//выбран режим пилот для данных
byte_counter++;
//addr=0;
//gui_draw();
//return;
break;
}
//index=0;//обнуляем счетчик бит
byte=read_byte(addr);//читаем байт из буфера
//byte=read_byte(0x01);//читаем байт из буфера
addr++;//счетчик текущего обрабатываемого байта в буфере
byte_counter++;
// }
TapeOutMode=TAPE_OUT_BIT;//вывод битов в порт
}
break;
/***********************вывод данных DATA**************************************/
case TAPE_OUT_DATA:
{
//if (index>7)//проверка на чтение бит
// {
if (addr>=btr)//проверка на чтение байт из буфера
{
TapeOutMode=TAPE_OUT_STOP;//стоп передача, для чтения следующего буфера с SD-CARD
//byte_counter++;
//return;
break;
}
//index=0;//обнуляем счетчик бит
byte=read_byte(addr);//читаем байт из буфера
//byte=read_byte(0x01);//читаем байт из буфера
addr++;//счетчик текущего обрабатываемого байта в буфере
byte_counter++;
// }
TapeOutMode=TAPE_OUT_BIT;//вывод битов в порт
}
break;
/***********************вывод бит**********************************************/
case TAPE_OUT_BIT:
{
if (byte&128) //проверка но ноль или еденицу старшего бита
{
if (tim6_counter == 17*2)//проверка условя 1023Hz единица
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//сброс счетчика 1023Hz единица
TapeOutMode=TAPE_OUT_NEXT_BIT;//выбор режима чтения следующего бита в байте
}
tim6_counter++;//счет 1023Hz единица
//return;
break;
}
else
{
if (tim6_counter == 8*2)//проверка условия 2047Hz ноль
{
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
tim6_counter = 0;//сброс счетчика 2047Hz ноль
TapeOutMode=TAPE_OUT_NEXT_BIT;//выбор режима чтения следующего бита в байте
}
tim6_counter++;//счет 2047Hz ноль
//return;
break;
}
}
break;
/***********************выбираем следующий бит для передачи********************/
case TAPE_OUT_NEXT_BIT:
{
if (index<=7)//проверка на обработку всех бит
{
byte<<=1;//сдвиг влево на 1 бит
index++;//следующий бит
}
else
{
//TapeOutMode=TAPE_OUT_STOP;//стоп передача, для чтения следующего буфера с SD-CARD
index=0;//первоначальное значение бита
//return;
}
switch (TapeOutModeStart)//выбор режима передачи байтов
{
case TAPE_OUT_START_D://если стартови данные
{
TapeOutMode=TAPE_OUT_DATA;//режим вывода данных
//index++;//следующий бит
//return;
}
break;
case TAPE_OUT_START_H://если стартовал заголовок
{
TapeOutMode=TAPE_OUT_HEAD;//режим вывода заголовка
//index++;//следующий бит
//return;
}
break;
}
}
break;
/***********************завершаем передачу и устанавливаем стартовые параметры*/
case TAPE_OUT_STOP:
{
index=0;//первоначальное значение бита
byte =0;//первоначальное значение байта
addr =0;//первоначальное значение первого байта в буфере
}
break;
/************************************************** ****************************/
case TAPE_OUT_SELECT_D:
{
if (tap_file.LenHeader==0x13||tap_file.flagHeader==0)
{
}
if (tap_file.LenHeader!=0x13||tap_file.flagHeader==0x FF)
{
}
}
break;
/************************************************** ****************************/
}
/************************************************** ****************************/
/* USER CODE END TIM6_DAC_IRQn 1 */
}
исправил
https://youtu.be/aHQC0d9dKhA
- - - Добавлено - - -
Доработки на текущий момент.
Сделан тест модулей системы.
Читает tap по байтам с карты (для отладки программы).
Перед блоками выдает пилот.
На экране отображает имя блока и порядковый номер.
В связи отсутствия инструмента на текущий момент не могу проверить правильность генерируемых сигналов.
Работы продолжаются.
https://cdn1.savepice.ru/uploads/201...5f801-full.jpg
- - - Добавлено - - -
Все сигналы генерируются в норме.
Загрузка не удается из за отсутствия генерации последнего бита.
Разбираюсь с кодом
- - - Добавлено - - -
Код:case TAPE_OUT_DATA:
{
if (index16 >=16){
if (BytesCount>=sz)//проверка на чтение байт из буфера
{
TapeOutMode=TAPE_OUT_PAUSE;//ставим паузу по оканчанию процесса
sz=FioNextHead();//читаем размер блока
BytesCount = 0;
break;
}
byte=FioNextByte();//читаем байт из буфера
index16=0;//первоначальное значение бита
BytesCount++;//общий счетчик байт файла
}
if (byte&128) //проверка на ноль или еденицу старшего бита
{
TIM6->PSC = 10265;
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
}
else
{
TIM6->PSC = 5132;
HAL_GPIO_TogglePin (GPIOD, LD6_Pin);
}
if ((index16%2)==1) byte<<=1;
index16++;
}break;