Ярлыки

_GetPixelIndex (1) _SetPixelIndex (1) 3-phase (1) 800x480 (1) АЦП (1) генератор (1) синхронный усилитель (2) структура (1) учебный курс (1) шаговый двигатель (1) ШИМ (2) accert (1) AD7608 (1) AD8429 (1) ADC (5) amplifer (1) arccos (1) arcsin (1) arctang (2) arctg (3) ARM (2) arm_sqrt_q15 (2) assembler (6) ASSERT (1) atan (2) bit (1) Bitband (1) boot (3) bootlloader (1) BUTTON (1) C (5) C# (1) CAN (2) CC2530 (5) CMSIS (4) command (1) Cordic (1) Core746I (1) CubeMX (4) DBGMCU (2) debug (2) debug.ini (1) delegate (1) Digital Potentiometers (1) DigitalPOT (1) Discovery (1) DMA (9) DMA2D (1) DSP (1) DSP library (1) DWT (1) EFM32 (5) EmWin (9) EXTI (1) FATFS (1) FMC (2) FreeRTOS (2) gl868-dual cmux (1) GPIO (4) GUI (2) GUIBuilder (1) GUIDRV_CompactColor_16 (1) HAL (3) HappyGecko (1) Hard Fault (2) heap (1) I2C (1) ID (1) ILI9320 (1) ILI9325 (1) Initialisation (1) InitLTDC (1) Instrumentithion (1) Interrupt (4) ITR (1) JTAG (1) Keil (5) LCDConf (2) lock-in (1) LTCD (1) LTDC (3) main (1) memory (1) MINI_STM32 Revision 01 (1) nBoot0 (1) NVIC (1) OnePulse (2) OSAL (4) pack (1) phase (1) printf (3) Pulse (1) PWM (12) RCC (2) RCR (1) Register (1) RESET (2) RS232 (3) RSS (1) RTC (3) RTOS-RTX (1) RTT (1) RTX-RTOS (1) SDCard (1) SDRAM (6) Segger (2) SPI (3) sqrt (3) SSD1298 (1) SSD1963 (1) Standart Peripherial Library (3) STANDBAY (1) startup (1) STemWin (8) stepper motor (1) STlink (2) STM32 (17) STM32429ZI (1) STM32Cube (1) STM32DBG.IN (1) STM32F (28) STM32F0 (4) STM32F1 (13) STM32F4 (10) STM32F4 Discovery (1) STM32F407ZG (1) STM32F429 (2) STM32F746 (1) STOP (1) string (1) struct (1) SWD (1) SWD JTAG (1) Synhronization (1) system_stm32f4xx.c (1) SystemInit (1) SysTick (1) task (4) telit (1) TIM (27) typedef (1) UART (1) USART (9) viewer (2) WM_PAINT (1) Z-stack (5) ZigBee (5)

воскресенье, 6 сентября 2015 г.

Software RESET fot Cortex & STM32

In the library source file stm32f10x_nvic.c :

#define AIRCR_VECTKEY_MASK    ((u32)0x05FA0000)
/*******************************************************************************
* Function Name  : NVIC_GenerateSystemReset
* Description    : Generates a system reset.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_GenerateSystemReset(void)
{
  SCB->AIRCR = AIRCR_VECTKEY_MASK | (u32)0x04;
}

or

    ldr     r0,=0xE000ED0C ; SCB AIRCR
    ldr     r1,=0x05FA0004
    str     r1, [r0, #0]

Other variant :

SystemReset     PROC
                EXPORT  SystemReset
                ldr     r1, =0xE000ED0C ; NVIC Application Interrupt and Controller
                ldr     r0, =0x05FA0004 ; Magic
                str     r0, [r1, #0]    ; Reset
self            b       self
                bx      lr
                ENDP

Saw a function in core_cm3.h. Didn't use it though.

/*    This function initiate a system reset request to reset the MCU. */
static __INLINE void NVIC_SystemReset(void)
{
  __DSB();                                                     /* Ensure all outstanding memory accesses included
                                                                  buffered write are completed before reset */
  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
  __DSB();                                                     /* Ensure completion of memory access */
  while(1);                                                    /* wait until reset */
}

суббота, 5 сентября 2015 г.

Hard Fault Handler for Cortex M4 & M3

In the Vector table you’ll see something like this

  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler
  .word  UsageFault_Handler

We need to add the C code

void hard_fault_handler_c (unsigned int * hardfault_args)
{
  unsigned int stacked_r0;
  unsigned int stacked_r1;
  unsigned int stacked_r2;
  unsigned int stacked_r3;
  unsigned int stacked_r12;
  unsigned int stacked_lr;
  unsigned int stacked_pc;
  unsigned int stacked_psr;
 
  stacked_r0 = ((unsigned long) hardfault_args[0]);
  stacked_r1 = ((unsigned long) hardfault_args[1]);
  stacked_r2 = ((unsigned long) hardfault_args[2]);
  stacked_r3 = ((unsigned long) hardfault_args[3]);
 
  stacked_r12 = ((unsigned long) hardfault_args[4]);
  stacked_lr = ((unsigned long) hardfault_args[5]);
  stacked_pc = ((unsigned long) hardfault_args[6]);
  stacked_psr = ((unsigned long) hardfault_args[7]);
 
  printf ("\n\n[Hard fault handler - all numbers in hex]\n");
  printf ("R0 = %x\n", stacked_r0);
  printf ("R1 = %x\n", stacked_r1);
  printf ("R2 = %x\n", stacked_r2);
  printf ("R3 = %x\n", stacked_r3);
  printf ("R12 = %x\n", stacked_r12);
  printf ("LR [R14] = %x  subroutine call return address\n", stacked_lr);
  printf ("PC [R15] = %x  program counter\n", stacked_pc);
  printf ("PSR = %x\n", stacked_psr);
  printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
  printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
  printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
  printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
  printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
  printf ("SCB_SHCSR = %x\n", SCB->SHCSR);
 
  while (1);
}

вторник, 1 сентября 2015 г.

SPL

Практически вся (если не вообще вся) периферия настраивается примерно одинаково, различия имеются только в специфических для каждого устройства параметрах и командах. Приведу пример: 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init( GPIOC , &GPIO_InitStructure);

Это пример настройки порта ввода-вывода (GPIO). Рассмотрим его поподробнее.

1. Включение тактирования периферийного устройства


Первым делом на порт подаётся тактирование: 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

Периферийные устройства тактируется либо от шины APB2, либо от APB1. От какой именно, можно узнать по названию константы. В нашем случае это RCC_APB2Periph_GPIOC, стало быть шина — APB2. Константа расположена в файлеstm32f10x_rcc.h, давайте найдем ее. В Eclipse для этого достаточно щелкнуть мышкой по константе, зажав Ctrl. 

Вот что мы находим в stm32f10x_rcc.h: 

#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
......
#define RCC_APB1Periph_TIM13             ((uint32_t)0x00000080)
#define RCC_APB1Periph_TIM14             ((uint32_t)0x00000100)
#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)
#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)
#define RCC_APB1Periph_SPI3              ((uint32_t)0x00008000)
#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
...

Поблизости можно найти все необходимые нам константы для запуска тактирования любого периферийного устройства. К примеру, если мы хотим воспользоваться USART2, мы воспользуемся константой RCC_APB1Periph_USART2, а поскольку из её названия видно, что USART2 тактируется от шины APB1, включение тактирования мы произведем следующим образом:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

Не забывайте, что одним вызовом функции можно включить тактирование сразу несколько устройств, задав в параметре функции несколько констант через операторпобитовое ИЛИ:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC 
  | RCC_APB2Periph_ADC1, ENABLE);

Побитовое ИЛИ «соберёт» все единички из перечисленных констант, а сами константы, как вы уже догадались, являются маской, как раз предназначенной для такого использования.

Обратите внимание, что в некоторых случаях может потребоваться дополнительная настройка, например, для АЦП необходимо выставить предделитель частоты:

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

Максимальная тактовая частота для АЦП составляет 12 МГц, это необходимо учесть при выборе предделителя. 

Идём дальше. 


воскресенье, 30 августа 2015 г.

STM32 Standard Peripheral Library

Стартовый код (C-Startup) для микроконтроллеров STM32 может быть написан на С или Assembler.
Хотя библиотеку STM32F10x Standard Peripheral Library (далее по тексту используется сокращение STM32F10x SPL) часто критикуют за наличие ошибок, все же для начала программирования под STM32 использование этой библиотеки предоставляет самый простой способ быстро приступить к работе.
Но всегда хочется, чтобы была какая-то альтернатива. На самом деле их множество, например, программировать на языке ассемблера :) .
Это самый тяжелый и бессмысленный путь. Второй способ — использовать библиотеку CMSIS, которая предоставляет синтаксис обращения к структурам языка С для доступа к различной периферии микроконтроллера. Самым простым и логичным способом (на мой взгляд) является использование библиотек.
Если вы категорически настроены против STM32F10x SPL, то специально для вас имеется еще одна альтернатива — библиотека libopencm3. В ней основное количество примеров сосредоточено вокруг основной серии микроконтроллеров STM32F10x , но появление примеров для других серий ( STM32F2xx/4xx) является только вопросом времени. Вы всегда можете присоединиться к проекту libopencm3 и ускорить этот процесс.
Стандарт CMSIS также является не обязательным для применения в ваших программах.
Можно обойтись и без него, потратив некоторые усилия и время для реализации HAL ( Hardware Abstraction Layer ) уровня на языке программирования С.
Такой способ может оказаться в некоторых случаях единственным доступным способом. Например, ваша организация использует заказные микросхемы на основе разработанных компанией ARM вычислительных ядер и специфической для отрасли периферией.
Или вам необходимо реализовать программное обеспечение на языке С для микроконтроллеров с ядром ARM9, для которого производители ориентируются на использование готовых операционных систем (Linux, QNX, Windows CE), поэтому библиотек для программирования на языке С в чистом виде или в сочетании с более легковесной RTOS производители могут не предоставлять.
К счастью производители микроконтроллеров на основе ядра Cortex-M3 предоставляют в распоряжение разработчиков большое количество библиотек кода. Это касается и микроконтроллеров STM32.
Продолжим рассмотрение библиотеки STM32F10x SPL. Рассматривать ее будем на примере stm32f10xQuickstart.
Вы можете открыть этот пример или же создать свой проект «с нуля», чтобы лучше осознать весь процесс происходящего.
Для второго случая я перечислю список необходимых шагов :
  • Создать в Eclipse новый пустой проект
  • Скопировать в проект скрипт компоновки и стартовый файл
  • Создать новый или скопировать шаблонный Makefile
  • При использовании в качестве шаблона Makefile из моего примера необходимо создать внутри проекта каталоги src, inc, bin, obj , внутри каталогов bin и obj создать подкаталоги Debug и Release.
  • Скопировать необходимые исходные и заголовочные файлы из библиотек CMSIS и STM32F10x SPL.
  • Внести необходимые изменения в секции настроек пользователя шаблонного Makefile, если он используется.
  • Создать в окне Eclipse “make target ” новые цели “Debug”, “cleanDebug”, “Release”, “cleanRelease”, “Program”.
  • Запустить на выполнение цель «Debug» и проследить за ее выполнением в окне «Console».
Для лучшего понимания материала я разбил статью на несколько независимых параграфов, в каждом из которых описывается только какой-то один аспект работы с библиотекой STM32F10x SPL.


среда, 27 мая 2015 г.

2-x фазный ШИМ (PWM) генератор на STM32F030F4

   Для питания ряда устройств (например электродвигателей переменного тока) иногда необходимо наличие сдвинутых по фазе питающих напряжений. Для питания 2-х фазных синхронных индукционных двигателей необходимо наличие двух фаз синусоидального напряжения с частотой 400 Герц и сдвинутых по фазе на 90 градусов. Один из примеров таких двигателей являются двигатели серии ДИД.  Они интересны тем, что их частота вращения может составлять от 16000 до 18000 об/мин. Для питания таких двигателей и было сделано данное устройство, которое представляет собой задающий генератор 2-х фазного 400 Гц напряжений сдвинутых по фазе на 90 градусов относительно друг друга.
  В качестве микроконтроллера использован STM32F030F4. Его выбор обусловлен его "минимализмом" - наименьший из корпусов в серии STM32F0 и естественно с минимальной стоимостью. Схема подключения изображена ниже. Микроконтроллер работает на частоте 48 МГц. В качестве задающего генератора использован TIM3, так как в данном контроллере только этот таймер можно конфигурировать так, чтобы использовать выходы трех каналов. Третий канал можно в случае необходимости использовать для генерации 3-фазного напряжения. Таймер работает в режиме генерации ШИМ (PWM). Для получения синусоидального напряжения 400 Гц в канале используется высокочастотное изменение коэффициента ШИМ с частотой 40 кГц, на которую настроен системный таймер SysTick. Синусоида формируется с помощью таблицы значений синуса с шагом 360/100 градусов. 





  Ниже показаны выходные осциллограммы генератора