Синхронизация вывода и обработки

nik182
Offline
Зарегистрирован: 04.05.2015

В сгенерённый кубом файл нужно добавить строки 94-106 из #92. Этого достаточно для работы. Все остальное я вставлял для отладки. 

/* USER CODE END 4 */ действительно улетел,когда я хвост файла коцал. 463 строка мне нужна была для установки точки остановки при заполнении буфера АЦП. Точку остановки я ставил на 117 строке. 

Вот ещё в копилку АЦП. При отладке я поднял 2 канала и соединил с выходами таймера. 2 мкс не хватило на оцифровку двух каналов. АЦП пропускало каждый второй такт.

a5021
Offline
Зарегистрирован: 07.07.2013

Время оцифровки одного канала равно четырнадцати тактам в самом быстром случае. 14 тактов на частоте 12мгц это 14/12=1,7мкс.

Юрий48
Offline
Зарегистрирован: 19.06.2018

Как противно когда дело не идёт. Компилируется без ошибок. При запуске отладчика выдаётся сообщение

Есть файл DU_nik182.elf.launch, а DU_nik182.elf нет. Почему он не создаётся, что там в настройках надо сделать? Плюс ко всему развёртка у осцилографа не работает. Пол вечера счищал с него пыль, накопившуюся за 10 лет и вот такой подарок. Что то мерзко на душе - не пойти ли съесть буше.

nik182
Offline
Зарегистрирован: 04.05.2015

У меня в папке debug появляется файл с расширением elf  размером 391572 байта. Потом подключаем stlink c платой и нажимаем кнопку с изображением жука на панели инструментов. Начинается отладка.

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

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

У меня в папке debug появляется файл с расширением elf  размером 391572 байта. Потом подключаем stlink c платой и нажимаем кнопку с изображением жука на панели инструментов. Начинается отладка.

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

Спасибо. Да, кирилицу не любит, весь путь сделал латиницей и при запуске debug отработал без каких либо сообщений какой то процессинг, но и ничего не поменялось. PC13 как моргал так и моргает. Файла с elf не появилось, так что пляски прдолжаются. Просто какой то заколдун. А в какой момент появляется этот elf? А можно ли и как в среде Atollic понять видит ли он плату?

nik182
Offline
Зарегистрирован: 04.05.2015

 После нажатия кнопки build с молотком внизу высыпается куча сообщений о компиляции модулей которые заканчиваются сообщением

Generate build reports...
Print size information
   text    data     bss     dec     hex filename
  16596     460   14480   31536    7b30 timers.elf
Print size information done
Generate listing file
Output sent to: timers.list
Generate listing file done
Generate build reports done
arm-atollic-eabi-objcopy.exe -O ihex timers.elf timers.hex 
 
20:44:04 Build Finished (took 3s.601ms)
 
После этого в папке debug образуются 4 файла с расширениями elf, hex, list, map
Файл hex можно прошить в плату с помощью програматора ST-LINK разными программами, а с помощью flush loader demo через переходник USB-TTL. Отладку можно запустить через програматор ST-LINK. Если его нет, то ничего не получится. Стоит 100 руб на алиэкспресс. Китайские иногда горят при подключени к компу на горячую, поэтому закупаю сразу по 3 штуки. Сначала делел их из этих же плат. Нужно 2 резистора и 2 конденсатора. В сети есть инструкции по запросу ST-LINK своими руками. Я начинал с этого  https://habr.com/post/247275/
Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

 После нажатия кнопки build с молотком внизу высыпается куча сообщений о компиляции модулей которые заканчиваются сообщением

Generate build reports...
Print size information
   text    data     bss     dec     hex filename
  16596     460   14480   31536    7b30 timers.elf
Print size information done
Generate listing file
Output sent to: timers.list
Generate listing file done
Generate build reports done
arm-atollic-eabi-objcopy.exe -O ihex timers.elf timers.hex 
 
20:44:04 Build Finished (took 3s.601ms)
 
После этого в папке debug образуются 4 файла с расширениями elf, hex, list, map
Файл hex можно прошить в плату с помощью програматора ST-LINK разными программами, а с помощью flush loader demo через переходник USB-TTL. Отладку можно запустить через програматор ST-LINK. Если его нет, то ничего не получится. Стоит 100 руб на алиэкспресс. Китайские иногда горят при подключени к компу на горячую, поэтому закупаю сразу по 3 штуки. Сначала делел их из этих же плат. Нужно 2 резистора и 2 конденсатора. В сети есть инструкции по запросу ST-LINK своими руками. Я начинал с этого  https://habr.com/post/247275/

Спасибо за поддержку, а то совсем тоскливо. Никаких таких сообщений в конце не появляется и файлов то же. Мысль попробовать прошить через flush loader была, но файлов hex или bin не нашёл, теперь понятно почему. ST-LINK рабочий потому, что через ардуино всё проходит нормально. Где косяк ума не приложу. Сейчас попробую всё переустановить. Если дело так пойдёт дальше, то dimax будет прав, говоря, что "сомневаюсь что  у вас что-то выйдет."

nik182
Offline
Зарегистрирован: 04.05.2015

Можете показать какие сообщения высыпаются в лог? Только сворачивайте при загрузке,что бы место не занимать. 

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Можете показать какие сообщения высыпаются в лог? Только сворачивайте при загрузке,что бы место не занимать. 

Если это тот лог, что на картинке, то он не создаётся, как и остальные перечисленные вами файлы в Debug. Может, что то связано с Host ом.

Юрий48
Offline
Зарегистрирован: 19.06.2018

Переустановил Atollic, версия 9.2.0. Ситуация не много изменилась. При первом запусе Debug что то начало раскручиваться, куча быстро меняющейся информации. Потом резко прекратилось без каких либо сообщений и суммарной информации. После этого все дальнейшие попытки сразу же кончалсь как и раньше уже до боли знакомым сообщением, правда с чуть чуть другим текстом. Прилагаю лог.



!ENTRY org.eclipse.cdt.dsf.gdb 4 104 2018-12-06 18:19:09.093
!MESSAGE Program file does not exist
!STACK 0
java.io.FileNotFoundException: D:\Razrabotki\Datchik urovnay\Projects\Atollic\DU_nik182\Debug\DU_nik182.elf not found
	at org.eclipse.cdt.dsf.gdb.launching.LaunchUtils.verifyProgramPath(LaunchUtils.java:126)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.checkBinaryDetails(GdbLaunchDelegate.java:293)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugSession(GdbLaunchDelegate.java:138)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugger(GdbLaunchDelegate.java:102)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launch(GdbLaunchDelegate.java:91)
	at com.atollic.hardwaredebug.launch.DSFDelegate.launch(DSFDelegate.java:59)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:885)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:739)
	at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1039)
	at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1256)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
!SUBENTRY 1 org.eclipse.cdt.dsf.gdb 4 104 2018-12-06 18:19:09.093
!MESSAGE D:\Razrabotki\Datchik urovnay\Projects\Atollic\DU_nik182\Debug\DU_nik182.elf not found
!STACK 0
java.io.FileNotFoundException: D:\Razrabotki\Datchik urovnay\Projects\Atollic\DU_nik182\Debug\DU_nik182.elf not found
	at org.eclipse.cdt.dsf.gdb.launching.LaunchUtils.verifyProgramPath(LaunchUtils.java:126)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.checkBinaryDetails(GdbLaunchDelegate.java:293)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugSession(GdbLaunchDelegate.java:138)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launchDebugger(GdbLaunchDelegate.java:102)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.launch(GdbLaunchDelegate.java:91)
	at com.atollic.hardwaredebug.launch.DSFDelegate.launch(DSFDelegate.java:59)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:885)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:739)
	at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1039)
	at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1256)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
b707
Онлайн
Зарегистрирован: 26.05.2017

Юрий48. стесняюсь спросить, а Вы "Make All" или "Rebuild All" перед Debug нажимаете?

Юрий48
Offline
Зарегистрирован: 19.06.2018

b707 пишет:

Юрий48. стесняюсь спросить, а Вы "Make All" или "Rebuild All" перед Debug нажимаете?

Очень деликатно, я даже улыбнулся, хотя состояние такое, что удерживаю руку по чему ни будь не долбануть. Нажимаю. Всё просто бесит. Вот только что проект был без предупреждений. Снова открыл и там появились 2 предупреждения Invalid project path: Include path not found (DU_nik182\#undef __ARM_FEATURE_DSP).    DU_nik182        pathentry    Path Entry Problem. Не знаю, что делать.
 

nik182
Offline
Зарегистрирован: 04.05.2015

Вы добились вида True studio как в #39 ? 

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Вы добились вида True studio как в #39 ? 

Да.

nik182
Offline
Зарегистрирован: 04.05.2015

После нажатия кнопки молоток в нижнем окне идёт лог обработки. Нужен он, а не сообщения об ошибках.

Юрий48
Offline
Зарегистрирован: 19.06.2018

Друзья, за полтора часа в Keil-е мне удалось прорваться до нормальной заливки в процессор. Так стало легко голове. Всё было очень логично. Всем спасибо, особенно nik182. Начал с вашего решения, но оно полностью не собралось, чего то там не хватало, предполагаю, что LL библиотеки. Поскольку целью была лишь распальцовка, то пока не стал разбираться с этим, а попробовал свою, которую делал раньше по варианту поста № 54. Там тоже ругнулась на АЦП и I2C. Когда их отключил всё собралось без ошибок и залилось в процессор. Правда сигнала не увидел, видимо надо чего то запустить. Сейчас буду с этим разбираться. Так что мафия Atollic меня не приняла, ну и хорошо - изначально тянуло к Keil-у.

nik182
Offline
Зарегистрирован: 04.05.2015

Для кейла куб тоже генирит проекты и дописывает все библиотеки при этом. Не собраться не может. Это что то у вас не перенеслось.

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:
После нажатия кнопки молоток в нижнем окне идёт лог обработки. Нужен он, а не сообщения об ошибках.
Если дело в принципе, то вот

 

7:43:04 **** Incremental Build of configuration Debug for project DU_nik182 ****
Info: Internal Builder is used for build
arm-atollic-eabi-gcc -c -mthumb -mcpu=cortex-m3 -std=gnu11 -DUSE_FULL_LL_DRIVER -D__weak=__attribute__((weak)) -D__packed=__attribute__((__packed__)) -DUSE_HAL_DRIVER -DSTM32F103xB -I../Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -g -fstack-usage -Wall -specs=nano.specs -o Src\main.o ..\Src\main.c 
..\Src\main.c: In function 'main':
..\Src\main.c:127:52: error: 'aADCConvertedValues' undeclared (first use in this function)
                                        (uint32_t *)aADCConvertedValues,
                                                    ^~~~~~~~~~~~~~~~~~~
..\Src\main.c:127:52: note: each undeclared identifier is reported only once for each function it appears in
..\Src\main.c:128:41: error: 'ADCCONVERTEDVALUES_BUFFER_SIZE' undeclared (first use in this function)
                                         ADCCONVERTEDVALUES_BUFFER_SIZE
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

17:43:06 Build Finished (took 1s.828ms)

Но эта ошибка какая то странная, то её нет, а то появится.

nik182
Offline
Зарегистрирован: 04.05.2015

A как же строчки 17 и 18 изкода #92?

nik182
Offline
Зарегистрирован: 04.05.2015

глюк сервера. Повтор.

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

A как же строчки 17 и 18 изкода #92?

Да, их не вставил. Сейчас исправил. Сам увидел сразу после ответа вам, но ничего не изменилось - сообщение при билденге как было так и осталось, а собирается без ошибок. В Кейле то я попробовал программу сразу из под Куба, без добавок.

nik182
Offline
Зарегистрирован: 04.05.2015

Вставить. Сохранить проект. Rebuild all. Показать лог. Без вставок, просто из куба, ничего не заработает. Куб только инициализирует оборудование. Запуск и обработку надо писать руками. Строки 94-106 из #92.

nik182
Offline
Зарегистрирован: 04.05.2015

То что у вас в логе это не сборка. После сборки пишет размер выходного файла.

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Вставить. Сохранить проект. Rebuild all. Показать лог.

Вставил, сохранил. Rebuild all такого нет, есть только Rebuild - молоток с чем то жёлтеньким. Нажимаю его, что то быстро пробегает и ничего нового не появляется - всё чисто. Ну, а debug, как всегда - с этим гадостным сообщением.

Восстановленная Ваша программа в Keil-е прошла без замечаний и я наконец то увидел сигналы, правдо потанцевал с осцилографом - сильно капризничает, в какой то момент вдруг заработал.

nik182
Offline
Зарегистрирован: 04.05.2015

Отлично.
Я уже хвалил тут nucleo 303k8. Сделана в формате arduino nano сразу с st-link через который можно во время работы ком порт пробрасывать. Кроме того у неё ацп 6МГц и таймера с возможностью фазового сдвига каналов одного таймера в PWM режиме на любой угол. Для вашей задачи просто то что надо.

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:
Отлично. Я уже хвалил тут nucleo 303k8. Сделана в формате arduino nano сразу с st-link через который можно во время работы ком порт пробрасывать. Кроме того у неё ацп 6МГц и таймера с возможностью фазового сдвига каналов одного таймера в PWM режиме на любой угол. Для вашей задачи просто то что надо.

Спасибо, nik182. Вещь хорошая, действительно то, что нужно.  Но уже не те силы, что бы бегать за двумя зайцами. Мне бы с этой разобраться. В Чип-Дипе стоит 1050 р. В противовес моей - 120 р.  Пару штук уже заказано. А, если чесно сказать, то взял бы, если цена была сравнима с моей.

Сейчас начал пробовать вариант поста № 54. Только лишь генератор. Собралось в Keil-е без ошибок, но сигнала нет. Запуск такой.

 /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim2);
  HAL_TIM_Base_Start(&htim3);     
  /* USER CODE END 2 */

При использования в этой части вашего кода, без АЦП. даёт две ошибки. Кубовский проект такой:

#MicroXplorer Configuration settings - do not modify
Dma.Request0=TIM2_CH1
Dma.RequestsNb=1
Dma.TIM2_CH1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.TIM2_CH1.0.Instance=DMA1_Channel5
Dma.TIM2_CH1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.TIM2_CH1.0.MemInc=DMA_MINC_ENABLE
Dma.TIM2_CH1.0.Mode=DMA_NORMAL
Dma.TIM2_CH1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.TIM2_CH1.0.PeriphInc=DMA_PINC_DISABLE
Dma.TIM2_CH1.0.Priority=DMA_PRIORITY_LOW
Dma.TIM2_CH1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
File.Version=6
KeepUserPlacement=false
Mcu.Family=STM32F1
Mcu.IP0=DMA
Mcu.IP1=NVIC
Mcu.IP2=RCC
Mcu.IP3=SYS
Mcu.IP4=TIM2
Mcu.IP5=TIM3
Mcu.IP6=USB
Mcu.IPNb=7
Mcu.Name=STM32F103C(8-B)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PD0-OSC_IN
Mcu.Pin1=PD1-OSC_OUT
Mcu.Pin10=VP_SYS_VS_Systick
Mcu.Pin11=VP_TIM2_VS_ClockSourceINT
Mcu.Pin12=VP_TIM3_VS_ControllerModeTrigger
Mcu.Pin13=VP_TIM3_VS_ClockSourceINT
Mcu.Pin14=VP_TIM3_VS_ClockSourceITR
Mcu.Pin2=PA0-WKUP
Mcu.Pin3=PA1
Mcu.Pin4=PA6
Mcu.Pin5=PA7
Mcu.Pin6=PA11
Mcu.Pin7=PA12
Mcu.Pin8=PA13
Mcu.Pin9=PA14
Mcu.PinsNb=15
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103C8Tx
MxCube.Version=5.0.0
MxDb.Version=DB.5.0.0
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false
PA0-WKUP.Signal=S_TIM2_CH1_ETR
PA1.Signal=S_TIM2_CH2
PA11.Mode=Device
PA11.Signal=USB_DM
PA12.Mode=Device
PA12.Signal=USB_DP
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA6.Signal=S_TIM3_CH1
PA7.Signal=S_TIM3_CH2
PCC.Checker=false
PCC.Line=STM32F103
PCC.MCU=STM32F103C(8-B)Tx
PCC.PartNumber=STM32F103C8Tx
PCC.Seq0=0
PCC.Series=STM32F1
PCC.Temperature=25
PCC.Vdd=3.3
PD0-OSC_IN.Mode=HSE-External-Oscillator
PD0-OSC_IN.Signal=RCC_OSC_IN
PD1-OSC_OUT.Mode=HSE-External-Oscillator
PD1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=3
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F103C8Tx
ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.7.0
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=TrueSTUDIO
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=DU_K.ioc
ProjectManager.ProjectName=DU_K
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=MDK-ARM V5
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_TIM2_Init-TIM2-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true,6-MX_USB_PCD_Init-USB-false-HAL-true
RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2
RCC.APB1Freq_Value=36000000
RCC.APB1TimFreq_Value=72000000
RCC.APB2Freq_Value=72000000
RCC.APB2TimFreq_Value=72000000
RCC.FCLKCortexFreq_Value=72000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=72000000
RCC.IPParameters=ADCFreqValue,ADCPresc,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,PLLSourceVirtual,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,USBPrescaler,VCOOutput2Freq_Value
RCC.MCOFreq_Value=72000000
RCC.PLLCLKFreq_Value=72000000
RCC.PLLMCOFreq_Value=36000000
RCC.PLLMUL=RCC_PLL_MUL9
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.SYSCLKFreq_VALUE=72000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.TimSysFreq_Value=72000000
RCC.USBFreq_Value=48000000
RCC.USBPrescaler=RCC_USBCLKSOURCE_PLL_DIV1_5
RCC.VCOOutput2Freq_Value=8000000
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1
SH.S_TIM2_CH2.0=TIM2_CH2,PWM Generation2 CH2
SH.S_TIM2_CH2.ConfNb=1
SH.S_TIM3_CH1.0=TIM3_CH1,Output Compare1 CH1
SH.S_TIM3_CH1.ConfNb=1
SH.S_TIM3_CH2.0=TIM3_CH2,Output Compare2 CH2
SH.S_TIM3_CH2.ConfNb=1
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM2.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM2.IPParameters=Prescaler,TIM_MasterSlaveMode,TIM_MasterOutputTrigger,Period,Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2
TIM2.Period=3
TIM2.Prescaler=35
TIM2.TIM_MasterOutputTrigger=TIM_TRGO_OC2REF
TIM2.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_ENABLE
TIM3.Channel-Output\ Compare1\ CH1=TIM_CHANNEL_1
TIM3.Channel-Output\ Compare2\ CH2=TIM_CHANNEL_2
TIM3.IPParameters=Channel-Output Compare1 CH1,Channel-Output Compare2 CH2,Prescaler,Period,Pulse-Output Compare1 CH1,Pulse-Output Compare2 CH2
TIM3.Period=2-1
TIM3.Prescaler=10-1
TIM3.Pulse-Output\ Compare1\ CH1=2-1
TIM3.Pulse-Output\ Compare2\ CH2=1-1
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
VP_TIM3_VS_ClockSourceITR.Mode=TriggerSource_ITR0
VP_TIM3_VS_ClockSourceITR.Signal=TIM3_VS_ClockSourceITR
VP_TIM3_VS_ControllerModeTrigger.Mode=Trigger Mode
VP_TIM3_VS_ControllerModeTrigger.Signal=TIM3_VS_ControllerModeTrigger
board=DU

 

nik182
Offline
Зарегистрирован: 04.05.2015

Вы стартуете таймеры, а надо стартовать канал. Типа HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); но при этом не будет 90 градусов, т.к. будет задержка старта между каналами.

Наткнулся на интересный топик. https://www.stm32duino.com/viewtopic.php?f=48&p=51373

LL драйвера куба используют в среде ардуино без каких либо правок. Только хидеры в инклюды добавляют.

Это ж какие возможности открываются! Сделал проект в кубе, переобозвал main в setup. Вписал инклюды. Добавил loop с обработкой и лей в чип из среды ардуино. Уровень входа конечно повыше чем чисто в ардуину, но для вставившего в среду поддержку stm32 вполне по силам.   

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nik182 пишет:

...переобозвал main в setup.

Вот только этого не нужно.

nik182
Offline
Зарегистрирован: 04.05.2015

Что? Страшно? А мы не ищем легких путей. Выкидываем из переобозванного main цикл while, добавляем Serial.begin(115200); и радуемся результату.

Вот проба пера. Только запуск таймеров через LL драйвера куба.

#include "stm32yyxx_ll.h"
   
void setup() {

   Serial.begin(115200);
   LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
   LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH1);
   LL_TIM_CC_EnableChannel(TIM4, LL_TIM_CHANNEL_CH4);
   LL_TIM_EnableCounter(TIM1);

}

void loop() {
 

}

Ну и результат.

Скетч использует 19004 байт (28%) памяти устройства. Всего доступно 65536 байт.
Глобальные переменные используют 1244 байт (6%) динамической памяти, оставляя 19236 байт для локальных переменных. Максимум: 20480 байт.
 
Ну и как без ложки дёгтя. Реализация кушает только LL вызовы и не поддерживает LL структуры. Прямо из куба не получается, приходится кое что переписывать. Зато после конвертора SPL2LL-Converter сразу работает.  
Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Вы стартуете таймеры, а надо стартовать канал. Типа HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); но при этом не будет 90 градусов, т.к. будет задержка старта между каналами.

nik182, спасибо. Хотел проверить свои возражения по поводу 90 градусов, но осцилограф опять не работает. А соображения такие. Возмём, скажем, таймер 3, он сейчас настроен просто на компарирование и тригерный выход. Счётчик то для обоих каналов один, поэтому сдвиг может зависить только от уровней компарирования. И, если я правильно понимаю, появление сигнала на выходе как раз и будет зависеть  от момента старта. И поскольку сам выход тригерный, то в этом случае,  при не удачном раскладе задержки включения каналов, один из выходов может просто стать инверсным - минус 90 градусов. Гадостный осцилограф. Написал и пришла такая мысль, что эти рассуждения справедливы только при условии , что автоперезапуск не зависит от момента включения каналов. Если моменты включения каналов как то влияют на старт самого счётчика, тогда да, фаза может получиться произвольной.

nik182
Offline
Зарегистрирован: 04.05.2015

Включение канала это только выдача сигнала на ногу процессора. Все запрограмированные таймеры работают с момента установки в регистре бита EN. Это можно сделать аппаратно одновременно для нескольких таймеров и тогда они будут работать синхронно. Или программно, но тогда между таймерами будет задержка на время между двумя командами ,пишущими в EN единицы. Одной командой сразу в 2 таймера записать нельзя. Чем выше абстракция, тем больше задерка. На HAL это могут быть микросекунды. На СМSIS десятки наносекунд. 

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Включение канала это только выдача сигнала на ногу процессора. Все запрограмированные таймеры работают с момента установки в регистре бита EN. Это можно сделать аппаратно одновременно для нескольких таймеров и тогда они будут работать синхронно. Или программно, но тогда между таймерами будет задержка на время между двумя командами ,пишущими в EN единицы. Одной командой сразу в 2 таймера записать нельзя. Чем выше абстракция, тем больше задерка. На HAL это могут быть микросекунды. На СМSIS десятки наносекунд. 

Все последние мои посты относятся к структуре поста № 54, где задействовано всего два таймера. Помимо этого она хороша тем, что не требует их синхронизации. Это я видел изначально и поэтому на заморачивался этим вопросом. Другое дело их надо как то запустить. Как мне представлялось, это выполняется командой  HAL_TIM_Base_Start(&htim2);

 /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
  HAL_TIM_Base_Start(&htim2);
  HAL_TIM_Base_Start(&htim3);

/* USER CODE END 2 */

Осцил задышал, но сигнала не видно.

 

 

Юрий48
Offline
Зарегистрирован: 19.06.2018

Довольно быстро решил проблему и получил сигналы с таймера 2, те, которые и ожидались, что меня очень воодушевило. Но со следующим, подчинённым таймером 3, который должен тактироваться вторым каналом таймера 2, до сих пор вожусь с единственным результатом - сигналы хоть и квадратурные, но частотой 2 мГц. Откуда она берётся ума не приложу. Что не так настроено?

Юрий48
Offline
Зарегистрирован: 19.06.2018

С сигналами генератора разобрался - всё как хотел. И даже оптимизировал структуру поста 54. В первом таймере достаточно одного канала. По завершении работы опишу всё обстоятельно. А сейчас хочу получить совет. Есть желание оперативно поиграться значениями предделителей, уровней компарирования и значениями перезапуска. Пока вижу такой путь. Для этих значений создать переменные и из дебагера их менять, а в программе отслеживать их изменение. И, если оно есть, то инициализировать соответствующую команду. Например, если меняю значение предделителя, то запускается команда htim2.Init.Prescaler = Prescaler2;. В этой связи вопросы:

1. насколько реален этот подход?

2. если реален, то достаточно такой команды или надо ещё чего то дописывать?

3. Может есть более удобный вариант?

nik182
Offline
Зарегистрирован: 04.05.2015

Если у вас стоит куб, то по  пути 

c:\Users\1\STM32Cube\Repository\STM32Cube_FW_F1_V1.7.0\Drivers\STM32F1xx_HAL_Driver\STM32F103xB_User_Manual.chm лежит мануал по всем командам всех модулей HAL и LL.

Мне проще менять параметры командами LL: LL_TIM_SetClockDivision, LL_TIM_SetCounter, LL_TIM_OC_SetCompareCH1 и прочие. Они сразу применяют параметры к счётчику и не надо вызывать дополнительных команд инициализации.

 

Юрий48
Offline
Зарегистрирован: 19.06.2018

Меня то на первом этапе интересовал сам подход для оперативного изменения интересующих параметров. Не компилировать же при каждом чихе всю программу. Тот подход, который я описал выше реален или есть более удобный? А сами команды это уже второй вопрос, с которым мне надо будет ещё разобраться.

nik182
Offline
Зарегистрирован: 04.05.2015

Подход прост. Пишется общение с модулем по любому протоколу. Мне нравится MODBUS. В программе пишется блок реакции на внешние команды. Типа если пришла команда "с4n1000" то выполнить команду "LL_TIM_SetCounter(TIM4,1000);

Выбор команд за вами. Но после выполнения этой команды в счетчик четвертого таймера будет записано число 1000 и он продолжит работу с этого значения.

Можно повесить резистор на вход АЦП и в конце каждого цикла таймера считывать значение ValADC и писать его в канал таймера LL_TIM_OC_SetCompareCH1(TIM4,ValADC); и тогда вращая резистор можно менять скважность PWM.

Можно повесить LCD дисплей с кнопочками, написать меню по изменению параметров таймера и менять все параметры нажимая кнопочки.  

Можно измыслить ещё разные способы которые позволяют на лету, не переписывая программу, менять любые параметры любых модулей. Ограничений нет. Можно почти всё что вы пожелаете, остается только найти в мануале как это сделать.

 

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Подход прост. Пишется общение с модулем по любому протоколу. Мне нравится MODBUS. В программе пишется блок реакции на внешние команды. Типа если пришла команда "с4n1000" то выполнить команду "LL_TIM_SetCounter(TIM4,1000);

Подход понятен. MODBUS знаком и даже работал с ним в плотную. Писал программы для общения ПК с ПЛК по этому протоколу, но это в других средах. Но, что бы его реализовать, надо пройти путь куда длиннее того, который я описал. Я понял, что он реален и прямо сейчас можно его реализовать, только с командами разобраться надо. Да и преобразователя нет - только только заказал. В этой связи возникает такой вопрос. Какой объём работ нужно сделать, что бы организовать обмен по USB каналу. Если это только скачать какую то библиотеку, это одно, а, если ещё кучу своего надо писать, то это совсем другое, да и вопрос с драйвереми для ПК.

mixail844
Offline
Зарегистрирован: 30.04.2012

Юрий48 пишет:

Подход понятен. MODBUS знаком и даже работал с ним в плотную. Писал программы для общения ПК с ПЛК по этому протоколу, но это в других средах. Но, что бы его реализовать, надо пройти путь куда длиннее того, который я описал. Я понял, что он реален и прямо сейчас можно его реализовать, только с командами разобраться надо. Да и преобразователя нет - только только заказал. В этой связи возникает такой вопрос. Какой объём работ нужно сделать, что бы организовать обмен по USB каналу. Если это только скачать какую то библиотеку, это одно, а, если ещё кучу своего надо писать, то это совсем другое, да и вопрос с драйвереми для ПК.

да в принципе не трудно , на STM32 настроить USB как CDC  - Communication Device Class (драйвера есть встроенные Win 7 и Win 10 , устройствое определяеться как Serial Com Port)

примерно продумать какой набор комманд хотите потдерживать,изменение какие параметров , включение и отключение какого процесса,значения каких данных хотите видеть

и потом додумываете,(для упрощения) сможете ли сделать так что бы все команды было одной длины

например в самом простом случае может быть команда 

"W,T,4,1,4000;" - что может означать ,записать в таймер 4,на первый канал значение прескалера = 4000.

все это можно слать из простых и распространенных терминалов,например мне нравиться 

https://sourceforge.net/projects/y-a-terminal/ потому что команды можно сохранить на кнопки и не писать каждый раз заново.

отправлять команды можно как в ASCII так и прямо в RAW(hex/bin) формате

на стороне контроллера парсить,в данном случае по признаку "," и ";" - конец команды и все. 

если нужно чертить графики в зависимости в зависимости от изменений переменных ,то можно использовать https://hackaday.io/project/5334-serialplot-realtime-plotting-software - принимает данные в формате CSV и по ним рисует "в живую" графики . 

Юрий48
Offline
Зарегистрирован: 19.06.2018

mixail844, спасибо. На счёт общения по COM порту тут я как рыба в воде. Своих программ типа терминальных c хорошими возможностями отображению информации понаписано достаточно. Если я увижу, что COM проключился, то со стороны ПК проблемм нет. А вот написать программу того же самого парсинга на STM32 вот тут возникает куча проблемм, поскольку язык си совсем для меня новый (пишу я в Labview, это язык не инструкций а графический). Вот, например, прямо сейчас пытаюсь обьявить массив. Как он пишется примерно помню, но для уверенности ищу ресурсы, где можно это посмотреть, а это время - интернет дохлый. Я тут уже задавал вопрос кто какими ресурсами по СИ пользуется, но ответов не было. Ну нашёл, написал как будто железно, но компилятор даёт предупреждение, начал разбираться но отвлёкся на эту писанину. Это маленький рабочий штришок, а сколько их впереди при освоении языка, да и среды программирования как таковой. А, вот, вопрос посерьёзнее, который всплыл только сейчас. Хочу создать массив из тех данных которые надо менять. Это предделитель, перезапуск и компарирование по двум каналам и двум таймерам - всего 8 элементов. В отладчике менять нужныые значения, а в программе отслеживать их изменение. И, если оно произошло, то инициализировать команду, подписывающую это значение в соответчтвующий регистр. Всё это хорошо, так ведь в начале надо прописать в массив начальные данные, а их надо прочесть из регистра. Вот как это сделать? Да и работаю я на XP, это на счёт драйверов. Подумалось, ведь я же работал по USB из Ардуино, может, этого достаточно?

nik182
Offline
Зарегистрирован: 04.05.2015

Например CCR1 LL_TIM_IC_GetCaptureCH1, LL_TIM_IC_GetPrescaler и прочие. Взято из файла STM32F103xB_User_Manual.chm ссылку на который я давал. Потратьте полчаса и посмотрите  все Exported Function раздела справки "Модули- LL драйвер - TIM" даже просто по названиям функций понятно что они делают. На этом форуме в разделе песочница есть книги по CИ. Скачайте один раз и скорость интернета не будет мешать. XP и драйвера это серьёзно. Гораздо проще поднять первый сом порт на плате и через переходник TTL-COM общаться с платой. У меня на изготовление переходника уходило пол часа при наличии MAX232. 

Юрий48
Offline
Зарегистрирован: 19.06.2018

nik182 пишет:

Например CCR1 LL_TIM_IC_GetCaptureCH1, LL_TIM_IC_GetPrescaler и прочие. Взято из файла STM32F103xB_User_Manual.chm ссылку на который я давал. Потратьте полчаса и посмотрите  все Exported Function раздела справки "Модули- LL драйвер - TIM" даже просто по названиям функций понятно что они делают. На этом форуме в разделе песочница есть книги по CИ. Скачайте один раз и скорость интернета не будет мешать. XP и драйвера это серьёзно. Гораздо проще поднять первый сом порт на плате и через переходник TTL-COM общаться с платой. У меня на изготовление переходника уходило пол часа при наличии MAX232.

nik182. Ваше недовольство я полностью разделяю, всё верно. Но вот не дошёл ещё до этого, а собираюсь. Хотел сделать заготовку по циклу, а потом уже туда вставлять команды, но видете как всё медленно идёт.

nik182 пишет:

Гораздо проще поднять первый сом порт на плате и через переходник TTL-COM общаться с платой. У меня на изготовление переходника уходило пол часа при наличии MAX232.

Это я сразу понял в самом начале. Изготовить плату не проблема, хотя зрение уже не то. Но живу то я в глуши, зимой в деревне всего то 3 человека вместе со мной и женой. Спасает только Алиэкспрес и наезд детей. То же редковато приезжают. Конвертор заказал, считай через месяц придёт.

mixail844
Offline
Зарегистрирован: 30.04.2012

Не думал что предложу такое : может вам скрестить бегемота с ежом и заодно выстрелить себе в ногу но затем все перевязать?

То есть настроить регистры таймера в среде Ардуино. Nik, Из среды Ардуино же можно обращаться ко всем регистрам stm32f103?
А после того как настроите, общения с ПК писать командами Ардуино? Порог вхождения вроде снижается но ооочень многая часть фишек среды Atollic и гибкость языка C отпадает

nik182
Offline
Зарегистрирован: 04.05.2015

Да. Я полностью перенёс в среду Ардуино файлы сгенерённые кубом. Всё заработало и все фишки Ардуино доступны. Даже ОLED дисплей без переделок на библиотеках Ардуино поднялся. Однако ком порт остался ком портом и без переходника врядли можно его использовать. Вот если есть в наличии нано или что ещё из ардуино плат их можно использовать как TTL - USB переходник простым соединением ног Тх наны и Rx STMки  и соединением через 1к Rx наны и Тх STMки. Изврат конечно, но когда долго ждать и как временное решение то вполне.  

Юрий48
Offline
Зарегистрирован: 19.06.2018

Нет, ребята, надо подумать, сколько можно шарахаться. Даже, если nik182 выложит однозначно читаемую инструкцию по приручению Куба Ардуиной, и то надо подумать. Но, вот, опять заколебался.

b707
Онлайн
Зарегистрирован: 26.05.2017

народ, а что за проблема с USB на СТМ? - встроенный в "Блюпилл" USB отлично доступен из ардуино как Serial, никакие переходники не нужны.

nik182
Offline
Зарегистрирован: 04.05.2015

Драйвера под ХР есть?

Юрий48
Offline
Зарегистрирован: 19.06.2018

Из Ардуино по USB я работал с платой. Этого достаточно? Но там или с USB или ST-Link и тогда программа для работы с USB затерается. Драйвера встали с трудом, пришлось потанцевать. А на старенький ноутбук с XP вообще не встали. Что бы программно допилить блок на объете пришлось дорабатывать железо, организовывать выход для ST-Link, что очень не хотелось.

Юрий48
Offline
Зарегистрирован: 19.06.2018

Свою идею воплотил таким образом. И ведь работает. Ура

// Чтение параметров таймеров
   for(i=0; i<8; i++)
      {       
        switch (i)
             {
       // Таймер 2
               case 0:                  
                 isl_T[i] = TIM2->PSC; // Предделитель таймера 2
                break;
               case 1:
                  isl_T[i] = TIM2->ARR; //Перезапуск таймера 2
                break;
               case 2:
                  isl_T[i] = TIM2->CCR1;
                 /*isl_T [i] = isl_T_ [i] = LL_TIM_OC_GetCompareCH1(TIM_TypeDef *TIMx)*/; // Уровень компариования для первого канала таймера 2
                break;
               case 3:
                  isl_T[i] = TIM2->CCR2; //Уровень компариования для второго канала таймера 2
                break;
       // Таймер 3
               case 4:
                isl_T[i] = TIM3->PSC; // Предделитель таймера 3
                break;
               case 5:
                  isl_T[i] = TIM3->ARR ; //Перезапуск таймера 3
                break;
               case 6:
                   isl_T[i] = TIM3->CCR1; //Уровень компариования для первого канала таймера 3
                break;
               case 7:
                   isl_T[i] = TIM3->CCR2; //Уровень компариования для второго канала таймера 3
                break;             
            } 
        isl_T_[i] = isl_T[i];     
      } 
      
      
      
  while (1)
  {
       for(i=0; i<8; i++)
      {
       if (isl_T[i] != isl_T_[i])
       {
           switch (i)
             {
        // Таймер 2 
               case 0:
                   TIM2->PSC = isl_T[i];  // Предделитель таймера 2
                break;
               case 1:
                   TIM2->ARR = isl_T[i]; //Перезапуск таймера 2                
                break;
               case 2:
                  TIM2->CCR1 = isl_T[i] ; // Уровень компариования для первого канала таймера 2
                break;
               case 3:
                   TIM2->CCR2 = isl_T[i];// Уровень компариования для второго канала таймера 2
                 break;
      // Таймер 3
               case 4:
                   TIM3->PSC = isl_T[i];// Предделитель таймера 3
                break;
               case 5:
                   TIM3->ARR = isl_T[i];//Перезапуска таймера 3
                break;
               case 6:
                   TIM3->CCR1 = isl_T[i]; //Уровень компариования для первого канала таймера 3
                break;
               case 7:
                   TIM3->CCR2;// Уровень компариования для второго канала таймера 3
                break;
            }            
        isl_T_[i] = isl_T[i];
      }
   } 

Массивы  isl_T[] и isl_T_[] беззнаковые шестнадцатиразрядные.

Юрий48
Offline
Зарегистрирован: 19.06.2018

Возник такой вопрос, связанный с прерыванием. Tаймер 3 работает в режиме компарирования с триггерным выходом. Если я правильно понял, то организовать прерывание можно только от переполнения счётчика. По отношению к выходу это получается на каждый фронт выходного сигнала. Но мне надо сделать прерывание только от положительного фронта выхода канала 1. Единственный вариант, который пришёл в голову, это с этого выхода кинуть перемычку на какой либо другой вход и уж от него организовывать прерывание. Не в открытую ли дверь я ломлюсь?