|
|
  |
STM32F103, Альтернатива библиотеки производителя |
|
|
|
May 6 2009, 12:45
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(KSN @ May 6 2009, 12:58)  Создаете свои функции/макросы или где-то есть альтернатива? Речь идет о примерах ИАР или примерах библиотеки STM? Библиотека в примерах ИАР безнадежно устарела, регулярно обновляемся с сайта STM. Если нет проблемы с временем выполнения, использую стандартные функции из библиотеки. Пробовал создавать свои макросы для PIO - все работает на ура. В более сложные узлы не лазил, потому что есть мнение, что в библиотеке учтены work arround к errata, а заново копаться в этом всем желания нет.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 10 2009, 10:56
|

Участник

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

|
Цитата(KRS @ May 28 2009, 16:00)  Для кортекса обработчик - обычная С функция. Надо только указатель на нее в векторе прерывания разместиь Здравствуйте. Посмотрите пожалуйста для Таймера 1 будет работать прерывание по вектору TIM1_UP_IRQHandler. Код #pragma language=extended #pragma segment="CSTACK"
void __iar_program_start( void );
#pragma location = ".intvec" /* STM32F10x Vector Table entries */ const intvec_elem __vector_table[] = { { .__ptr = __sfe( "CSTACK" ) }, //0 __iar_program_start, //1 0,//NMIException, //2 0,//HardFaultException, //3 0,//MemManageException, //4 0,//BusFaultException, //5 0,//UsageFaultException, //6 0, 0, 0, 0, /* Reserved */ 0,//SVCHandler, //11 0,//DebugMonitor, //12 0, /* Reserved */ 0,//PendSVC, //14 0,//SysTickHandler, //15 0,//WWDG_IRQHandler, //16 0,//PVD_IRQHandler, //17 0,//TAMPER_IRQHandler, //18 0,//RTC_IRQHandler, //19 0,//FLASH_IRQHandler, //20 0,//RCC_IRQHandler, //21 0,//EXTI0_IRQHandler, //22 0,//EXTI1_IRQHandler, //23 0,//EXTI2_IRQHandler, //24 0,//EXTI3_IRQHandler, //25 0,//EXTI4_IRQHandler, //26 0,//DMAChannel1_IRQHandler, //27 0,//DMAChannel2_IRQHandler, //28 0,//DMAChannel3_IRQHandler, //29 0,//DMAChannel4_IRQHandler, //30 0,//DMAChannel5_IRQHandler, //31 0,//DMAChannel6_IRQHandler, //32 0,//DMAChannel7_IRQHandler, //33 0,//ADC_IRQHandler, //34 0,//USB_HP_CAN_TX_IRQHandler, //35 0,//USB_LP_CAN_RX0_IRQHandler, //36 0,//CAN_RX1_IRQHandler, //37 0,//CAN_SCE_IRQHandler, //38 0,//EXTI9_5_IRQHandler, //39 0,//TIM1_BRK_IRQHandler, //40 TIM1_UP_IRQHandler, //41 0,//TIM1_TRG_COM_IRQHandler, //42 0,//TIM1_CC_IRQHandler, //43 0,//TIM2_IRQHandler, //44 0,//TIM3_IRQHandler, //45 0,//TIM4_IRQHandler, //46 0,//I2C1_EV_IRQHandler, //47 0,//I2C1_ER_IRQHandler, //48 0,//I2C2_EV_IRQHandler, //49 0,//I2C2_ER_IRQHandler, //50 0,//SPI1_IRQHandler, //51 0,//SPI2_IRQHandler, //52 0,//USART1_IRQHandler, //53 0,//USART2_IRQHandler, //54 0,//USART3_IRQHandler, //55 0,//EXTI15_10_IRQHandler, //56 0,//RTCAlarm_IRQHandler, //57 0,//USBWakeUp_IRQHandler, //58 }; А Код void __iar_program_start( void ); для чего или она тут не при чем? Кто-нибудь может скинуть пример работы программы на STM32 с библиотекой от IAR. Мне нужно запустить процессор, инициализировать прерывания, таймер, АЦП и UART. С процессором вроде как разобрался, вот что получилось: Код void SetupClock(void) { // 1. включаем внутренний генератор RCC_CR_bit.HSION = 1; // включаем внутренний генератор while(RCC_CR_bit.HSIRDY == 0){} // ожидаем потверждения включения внутреннего генератора // 2. %%%%%%%%%%%% отключаем SYSCLK %%%%%%%%%%%%%%%%%%%%%%%%%% RCC_CFGR_bit.SW = 0; // системный clock не выбран while(RCC_CFGR_bit.SWS != 3){} // ожидаем потверждения выключения 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 Скачал примеры, там самописные билиотеки (не привязанные к IAR), такие замудренные, разбираться замучаешься. Может кто чем поможет? Заранее спасибо!
|
|
|
|
|
Jun 10 2009, 12:23
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(miksher @ Jun 10 2009, 13:56)  Скачал примеры, там самописные билиотеки (не привязанные к IAR), такие замудренные, разбираться замучаешься. Какие библиотеки? От STM? Я бы так не драматизировал, только одна ошибка - определение TRUE и FALSE конфликтует с ИАРовским. Зато все есть, и примеры под них написаны.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 13 2009, 07:55
|

Участник

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

|
Цитата(Dog Pawlowa @ Jun 10 2009, 19:23)  Какие библиотеки? От STM? Я бы так не драматизировал, только одна ошибка - определение TRUE и FALSE конфликтует с ИАРовским. Зато все есть, и примеры под них написаны. библиотека с программным обеспечение IAR (c:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\arm\inc\ST\iostm32f10xxE.h) Хотелось бы посмотреть примеры программ с этой библиетекой
|
|
|
|
|
Jun 19 2009, 17:27
|

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

|
Сдаётся мне, что баги есть и в родной USB библиотеке для STM32 - USB-FS-Device development kit v3.0.1. Это касается модификации регистров конечных точек USB_EPnR. Регистры выглядят так:
Мягко говоря, весьма поганый набор битов с различными режимами доступа - и обычные rw, и read_and_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.Так почему же это не выполняется? Задал этот же вопрос в ветке по АРМам, но видимо никто не в курсе... ЗЫ: по идее, эта библиотека и куски кода из неё наверняка юзаются не в одном проекте. И если никто не чешется - значит или баг очень маловероятен, или его нет... В общем, пока буду, на всякий случай, дополнительно OR-ить эти два бита перед записью в регистр сразу после чтения...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|