|
|
  |
STM32F103x, делимся впечатлениями |
|
|
|
Jun 4 2009, 19:57
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(sonycman @ Jun 5 2009, 00:44)  А как сменить приоритет для прераваний без порядкового номера? К примеру, для SysTick - системного таймера? В таблице указано, что можно менять, но регистры Interrupt Priority Registers начинаются с номера 0, а это Window watchdog interrupt и ниже... Что-то непонятно как-то  core_cm3.h: Код static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, int32_t priority) { if(IRQn < 0) { SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */ else { NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ } stm32f10x.h: Код typedef enum IRQn { ... SysTick_IRQn = -1,
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 10 2009, 18:12
|
Участник

Группа: Участник
Сообщений: 72
Регистрация: 23-11-06
Из: Odessa
Пользователь №: 22 646

|
Обнаружил странную вещь. При использовании кейловской ОС RL-RTX, если настроить прерывание от ADC1, то запуск первой же ОС функции os_sys_init() приводит к вылету в прерывание HardFaultException() и, соответственно, зависанию процессора.
|
|
|
|
|
Jun 11 2009, 14:10
|
Участник

Группа: Участник
Сообщений: 72
Регистрация: 23-11-06
Из: Odessa
Пользователь №: 22 646

|
Разобрался. Не учел, что файлы STM32F10x.s (от Keil) и stm32f10x_vector.s (от ST) содержат в себе разные названия функций для обработки прерываний.
|
|
|
|
|
Jun 13 2009, 08:16
|

Участник

Группа: Свой
Сообщений: 64
Регистрация: 27-02-08
Из: Россия, Алтайский край, г.Баранул, Павловский тракт 283
Пользователь №: 35 418

|
Здравствуйте Посмотрите пожалуйста пример программки миганием светодиода (не получается помигать) В чем ошибка? Код //******************************************************************************** ***************** //******************* Настойка тактирования процессора ******************************************** //******************************************************************************** ***************** void SetupClock(void) { // 1. включаем внутренний генератор RCC_CR_bit.HSION = 1; // включаем внутренний генератор while(RCC_CR_bit.HSIRDY != 1){} // ожидаем потверждения включения внутреннего генератора // 2. %%%%%%%%%%%% отключаем SYSCLK %%%%%%%%%%%%%%%%%%%%%%%%%% RCC_CFGR_bit.SW = 0; // системный clock не выбран while(RCC_CFGR_bit.SWS != 0){} // ожидаем потверждения выключения SYSCLK // 3. отключаем внешний генератор RCC_CR_bit.HSEON = 0; // отключаем внешний генератор RCC_CR_bit.HSEBYP = 0; // не замыкаем внешний генратор с SYSCLK while(RCC_CR_bit.HSERDY != 0){} // ожидаем потверждения выключения внешнего генератора // 4. ******ВЫКЛЮЧАЕМ PLL******** RCC_CR_bit.PLLON = 0; // выключаем PLL while(RCC_CR_bit.PLLRDY != 0 ){} // ожидаем потверждения выключения PLL // 5. настаеваем SYSCLK RCC_CFGR_bit.PLLSRC = 0; // HSI (внутренний генератор) выбирается как вход PLL, при этом делится на 2 RCC_CFGR_bit.PLLXTPRE = 0; // HSE (внешний генератор) не делится на 2 во вход в PLL RCC_CFGR_bit.PLLMUL = 0xA; // установка умнажителя на 12 (8 МГц -> /2 -> 4 МГц -> *12 -> 48 МГц) // 6. ********ВКЛЮЧАЕМ PLL******* RCC_CR_bit.PLLON = 1; // включаем PLL while(RCC_CR_bit.PLLRDY == 0){} // ожидаем потверждения включения PLL // 7. настраемаем AHB предделитель RCC_CFGR_bit.HPRE = 0x0; // преддилитель AHB = 1 // 8. настраемаем APB1 предделитель RCC_CFGR_bit.PPRE1 = 0x4; // преддилитель APB1 = 2 // 9. настраемаем APB2 предделитель RCC_CFGR_bit.PPRE2 = 0x0; // преддилитель APB2 = 1 RCC_CR_bit.CSSON = 0; // отключаем внешний детектор clock // 12. %%%%%%%%%%%%%%%%%%% включаем SYSCLK %%%%%%%%%%%%%%%%%%%%% RCC_CFGR_bit.SW = 2; // PLL как системный clock while(RCC_CFGR_bit.SWS != 2){} // ожидаем потверждения включения SYSCLK } //******************************************************************************** *****************
//******************************************************************************** ***************** //******************* Инициализация порта D ******************************************************* //******************************************************************************** ***************** void PortDInit(void) { RCC_APB2ENR_bit.IOPDEN = 1; // включаем clock к GPIOA RCC_APB2RSTR_bit.IOPDRST = 1; // сброс GPIOA GPIOD_BRR_bit.BR2 = 1; // сброс PD2 GPIOD_CRL_bit.MODE2 = 3; // Output mode, max speed 50 MHz. GPIOD_CRL_bit.CNF2 = 0; // output Push-pull GPIOD_ODR_bit.ODR2 = 0; // output Push-pull } затем в main() Код while(1) { GPIOD_BRR_bit.BR2 = 1; myDelay(3000000); GPIOD_BSRR_bit.BS2 = 1; myDelay(3000000); } Может кто-нибудь поможет с примером программы мигания светодиода Мой микроконтроллер: STM32F103xxE, LQFP64, светодиод на 54 ноге (порт D, 2-ой пин) Внешнего генератора нет использую внутренний Пример программы в прикрепленном архиве
Прикрепленные файлы
stm.rar ( 33.22 килобайт )
Кол-во скачиваний: 35
|
|
|
|
|
Jun 17 2009, 08:18
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Мужики, подскажите, кто работал с USB данных чипов. Начал с ним разбираться - в первый раз. Мой девайс будет питаться от своего источника. Что произойдёт, если устройство не запитано, но производится его подключение кабелем к PC? Не будет ли напряжение с порта пытаться запитать контроллер через защитные диоды портов? (так как обычно сигнал с порта USB +5v подаётся на порт контроллера для детектирования подключенного кабеля...) Какова правильная схемотехника для данного случая?
|
|
|
|
|
Jun 18 2009, 13:52
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Кажися, я нашёл потенциальный глюк в фирменной ST-шной библиотеке USB-FS-Device development kit v3.0.1. Это касается модификации регистров конечных точек USB_EPnR. Регистры выглядят так:
Мягко говоря, весьма поганый набор битов с различными режимами доступа - и обычные rw, и read_only_cleared_by _writing_zero (rc_w0), и даже toggle биты, меняющие своё состояние только при записи единички... Так вот, процедуры модификации полей TYPE и STAT работают очень просто - читают регистр, затем маскируют (AND) биты, требующие модификации и toggle биты (оставляя без изменения остальные rw и rc_w0 биты). Затем записывают по OR нужное значение и всё это дело пишется обратно в регистр. Вот код: Код #define _GetENDPOINT(bEpNum) ((uint16_t)(*(EP0REG + bEpNum)))
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \ (uint16_t)wRegValue)
#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
#define EPTX_DTOGMASK ( 0x0030 | EPREG_MASK)
#define _SetEPTxStatus(bEpNum,wState) {\ register uint16_t _wRegVal; \ _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ /* toggle first bit ? */ \ if((EPTX_DTOG1 & wState)!= 0) \ _wRegVal ^= EPTX_DTOG1; \ /* toggle second bit ? */ \ if((EPTX_DTOG2 & wState)!= 0) \ _wRegVal ^= EPTX_DTOG2; \ _SetENDPOINT(bEpNum, _wRegVal); \ } /* _SetEPTxStatus */
void SetEPTxStatus(uint8_t bEpNum, uint16_t wState) { _SetEPTxStatus(bEpNum, wState); } Но! Ведь таким "макаром" можно стереть rc_w0 бит, в случае, если он был установлен железом в момент между чтением и записью регистра! То есть читаем такоой бит как "0", затем записываем его, естественно, тоже как "0", тем самым перезаписывая новое его значение! По идее, если я правильно понял, после маскирования биты rc_w0 надо ещё и принудительно устанавливать в "1", чтобы при записи гарантированно не потерять момент изменения состояния... Странно, почему у фирмачей не так?  Вот даже мануал говорит, что: Цитата Read-modify-write cycles on these registers should be avoided because between the read and the write operations some bits could be set by the hardware and the next write would modify them before the CPU has the time to detect the change. For this purpose, all bits affected by this problem have an ‘invariant’ value that must be used whenever their modification is not required. It is recommended to modify these registers with a load instruction where all the bits, which can be modified only by the hardware, are written with their ‘invariant’ value. Так почему же это не выполняется?
|
|
|
|
|
Jun 23 2009, 20:05
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Ммм, ковыряюсь в ST-шном примере USB Mass Storage. В коде не увидел обработки битов синхронизации (DTOG_TX и DTOG_RX) для нулевого канала. Ну я могу ещё допустить, что они сбрасываются автоматически при приёме SETUP и сами переключаются на последующих пакетах данных. Но как же быть с последним, подтверждающим пакетом, где эти биты всегда должны быть в единичке? Не думаю, что и эта ситуация может быть автоматически обработана контроллером, так как он не сможет предсказать, какой именно пакет будет последним... Эх, кажется, намучаюсь я ещё с этим примерчиком...
|
|
|
|
|
Jun 24 2009, 03:46
|

embedder
  
Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911

|
Цитата(sonycman @ Jun 17 2009, 12:18)  Мужики, подскажите, кто работал с USB данных чипов. Начал с ним разбираться - в первый раз. Мой девайс будет питаться от своего источника. Что произойдёт, если устройство не запитано, но производится его подключение кабелем к PC? Не будет ли напряжение с порта пытаться запитать контроллер через защитные диоды портов? (так как обычно сигнал с порта USB +5v подаётся на порт контроллера для детектирования подключенного кабеля...) Какова правильная схемотехника для данного случая? если Ваш девайс имеет собственное питание, то в этом случае ИМХО просто пренебречь линией +5В от USB, использовать ее как факт подключения к USB.
--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
|
|
|
|
|
Jun 24 2009, 04:15
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(zksystem @ Jun 24 2009, 06:46)  ... просто пренебречь линией +5В от USB, использовать ее как факт подключения к USB. Именно в этом случае и может возникнуть нежелаемый эффект. Если Вы не хотите питать Ваш девайс от USB, имеет смысл контролировать +5V через буфер, напр. полевик.
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|