Миша, как всегда, точен в определениях и академичен! Респект!
Сам я в С откровенно слабоват, спасает то, что в нем одно и то же можно записать разными способами, вот я и не заморачиваюсь, пишу, как в Асме.
А запись вида RCC->CR вполне удобна, RCC указывет на конкретную периферию (в данном случае RCC - это система тактирования, синхронизации и сброса) или иную часть архитектуры проца, а CR - на конкретный регистр (СR - контрольный регистр).
Конкретные названия периферии, регистров и битов настроечных регистров содержатся в файле определений. Например, Атоллик при создании проекта сам его подключает. Я широко пользуюсь этими определениями - они помогают не хуже комментариев вспомнить, чего я там настраивал и где.
Например:
RCC->CR |= RCC_CR_HSEON; // Включение HSE
если выделить RCC_CR_HSEON и нажать клавишу F3 (в Атоллике!
), то откроется файл определений на регистре RCC->CR на значении RCC_CR_HSEON. Там же можно посмотреть, как называются другие биты этого и других регистров, когда нужно их применить.
Ну и самое главное - начинать нужно, как и в Асме - с изучения архитектуры проца и его периферии. Если этого не знаешь - не спасет никакая книжка по языку С...
А по С, лично я пользуюсь только аналогами Асмовских операторов циклов, проверок условий и пересылок данных. И прога у меня на Асмовскую похожа получается
.
PS Кажется придумал, как мне обойти учетверенную частоту прерываний! Попробую-ка я вызывать лишь одно прерывание с частотой 31.25kHz не от таймера, а по EXTI от ножки, на которую выводится сигнал WS (левый/правый). А данные на ЦАП/АЦП слать по DMA.
Если получится, то прога должна успеть все обсчитать.