Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of foc-ed_in_the_bot_compact by
main.cpp@11:1a68e17c0279, 2016-05-19 (annotated)
- Committer:
- nki
- Date:
- Thu May 19 14:32:31 2016 +0000
- Revision:
- 11:1a68e17c0279
- Parent:
- 10:6829abb438fc
reading currentA and currentB sequentially on ADC1. DMA not yet implemented.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bwang | 0:bac9c3a3a6ca | 1 | #include "mbed.h" |
bwang | 0:bac9c3a3a6ca | 2 | #include "math.h" |
bwang | 0:bac9c3a3a6ca | 3 | #include "PositionSensor.h" |
bwang | 0:bac9c3a3a6ca | 4 | #include "FastPWM.h" |
bwang | 0:bac9c3a3a6ca | 5 | #include "Transforms.h" |
bwang | 0:bac9c3a3a6ca | 6 | #include "config.h" |
nki | 11:1a68e17c0279 | 7 | #include <numeric> |
bwang | 0:bac9c3a3a6ca | 8 | |
bwang | 1:7b61790f6be9 | 9 | FastPWM *a; |
bwang | 1:7b61790f6be9 | 10 | FastPWM *b; |
bwang | 1:7b61790f6be9 | 11 | FastPWM *c; |
bwang | 0:bac9c3a3a6ca | 12 | DigitalOut en(EN); |
bwang | 1:7b61790f6be9 | 13 | DigitalOut toggle(PC_10); |
nki | 11:1a68e17c0279 | 14 | //PositionSensorEncoder pos(CPR, 0); |
bwang | 0:bac9c3a3a6ca | 15 | Serial pc(USBTX, USBRX); |
bwang | 0:bac9c3a3a6ca | 16 | |
bwang | 1:7b61790f6be9 | 17 | int state = 0; |
nki | 11:1a68e17c0279 | 18 | float adval1, adval2; |
bwang | 2:eabe8feaaabb | 19 | float ia, ib, ic, alpha, beta, d, q, vd, vq, p; |
bwang | 1:7b61790f6be9 | 20 | float ia_supp_offset = 0.0f, ib_supp_offset = 0.0f; //current sensor offset due to bias resistor inaccuracies, etc (mV) |
bwang | 2:eabe8feaaabb | 21 | float d_integral = 0.0f, q_integral = 0.0f; |
bwang | 2:eabe8feaaabb | 22 | float last_d = 0.0f, last_q = 0.0f; |
bwang | 3:9b20da3f0055 | 23 | float d_ref = -0.0f, q_ref = -50.0f; |
bwang | 2:eabe8feaaabb | 24 | |
bwang | 4:a6669248ce4d | 25 | void commutate(); |
bwang | 3:9b20da3f0055 | 26 | void zero_current(); |
bwang | 3:9b20da3f0055 | 27 | void config_globals(); |
bwang | 3:9b20da3f0055 | 28 | void startup_msg(); |
bwang | 2:eabe8feaaabb | 29 | |
nki | 11:1a68e17c0279 | 30 | ADC_HandleTypeDef g_AdcHandle; |
nki | 11:1a68e17c0279 | 31 | uint32_t currentA_ADCValue, currentB_ADCValue; |
nki | 11:1a68e17c0279 | 32 | int g_MeasurementNumber; |
nki | 11:1a68e17c0279 | 33 | |
nki | 11:1a68e17c0279 | 34 | enum{ ADC_BUFFER_LENGTH = 200 }; //originally 8192 |
nki | 11:1a68e17c0279 | 35 | uint32_t currentA_ADCBuffer[ADC_BUFFER_LENGTH]; //current_A ADC buffer |
nki | 11:1a68e17c0279 | 36 | uint32_t currentB_ADCBuffer[ADC_BUFFER_LENGTH]; //current_B ADC buffer |
nki | 11:1a68e17c0279 | 37 | |
nki | 11:1a68e17c0279 | 38 | uint32_t debug_int = 0; |
nki | 11:1a68e17c0279 | 39 | |
nki | 11:1a68e17c0279 | 40 | |
nki | 11:1a68e17c0279 | 41 | void ConfigureADC() |
nki | 11:1a68e17c0279 | 42 | { |
nki | 11:1a68e17c0279 | 43 | GPIO_InitTypeDef currentA_gpioInit, currentB_gpioInit; |
nki | 11:1a68e17c0279 | 44 | |
nki | 11:1a68e17c0279 | 45 | __GPIOA_CLK_ENABLE(); |
nki | 11:1a68e17c0279 | 46 | __GPIOB_CLK_ENABLE(); |
nki | 11:1a68e17c0279 | 47 | __ADC1_CLK_ENABLE(); |
nki | 11:1a68e17c0279 | 48 | |
nki | 11:1a68e17c0279 | 49 | //Initialize PA_4 as an analog input |
nki | 11:1a68e17c0279 | 50 | currentA_gpioInit.Pin = GPIO_PIN_4; |
nki | 11:1a68e17c0279 | 51 | currentA_gpioInit.Mode = GPIO_MODE_ANALOG; |
nki | 11:1a68e17c0279 | 52 | currentA_gpioInit.Pull = GPIO_NOPULL; |
nki | 11:1a68e17c0279 | 53 | HAL_GPIO_Init(GPIOA, ¤tA_gpioInit); |
nki | 11:1a68e17c0279 | 54 | //Initialize PB_0 as an analog input |
nki | 11:1a68e17c0279 | 55 | currentB_gpioInit.Pin = GPIO_PIN_0; |
nki | 11:1a68e17c0279 | 56 | currentB_gpioInit.Mode = GPIO_MODE_ANALOG; |
nki | 11:1a68e17c0279 | 57 | currentB_gpioInit.Pull = GPIO_NOPULL; |
nki | 11:1a68e17c0279 | 58 | HAL_GPIO_Init(GPIOB, ¤tB_gpioInit); |
nki | 11:1a68e17c0279 | 59 | |
nki | 11:1a68e17c0279 | 60 | HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); |
nki | 11:1a68e17c0279 | 61 | HAL_NVIC_EnableIRQ(ADC_IRQn); |
nki | 11:1a68e17c0279 | 62 | |
nki | 11:1a68e17c0279 | 63 | ADC_ChannelConfTypeDef adcChannel_currentA; |
nki | 11:1a68e17c0279 | 64 | ADC_ChannelConfTypeDef adcChannel_currentB; |
nki | 11:1a68e17c0279 | 65 | |
nki | 11:1a68e17c0279 | 66 | g_AdcHandle.Instance = ADC1; |
nki | 11:1a68e17c0279 | 67 | |
nki | 11:1a68e17c0279 | 68 | g_AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; |
nki | 11:1a68e17c0279 | 69 | g_AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; |
nki | 11:1a68e17c0279 | 70 | g_AdcHandle.Init.ScanConvMode = ENABLE; //Enabled to convert multiple channels. Changed from DISABLE |
nki | 11:1a68e17c0279 | 71 | g_AdcHandle.Init.ContinuousConvMode = ENABLE; |
nki | 11:1a68e17c0279 | 72 | g_AdcHandle.Init.DiscontinuousConvMode = DISABLE; |
nki | 11:1a68e17c0279 | 73 | g_AdcHandle.Init.NbrOfDiscConversion = 0; |
nki | 11:1a68e17c0279 | 74 | g_AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; |
nki | 11:1a68e17c0279 | 75 | g_AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; |
nki | 11:1a68e17c0279 | 76 | g_AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; |
nki | 11:1a68e17c0279 | 77 | g_AdcHandle.Init.NbrOfConversion = 2; |
nki | 11:1a68e17c0279 | 78 | g_AdcHandle.Init.DMAContinuousRequests = ENABLE; |
nki | 11:1a68e17c0279 | 79 | g_AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; |
nki | 11:1a68e17c0279 | 80 | HAL_ADC_Init(&g_AdcHandle); |
nki | 11:1a68e17c0279 | 81 | |
nki | 11:1a68e17c0279 | 82 | //ADC_CHANNEL_4 corresponds to PA_4 |
nki | 11:1a68e17c0279 | 83 | adcChannel_currentA.Channel = ADC_CHANNEL_4; |
nki | 11:1a68e17c0279 | 84 | adcChannel_currentA.Rank = 1; |
nki | 11:1a68e17c0279 | 85 | adcChannel_currentA.SamplingTime = ADC_SAMPLETIME_480CYCLES; //was 28 |
nki | 11:1a68e17c0279 | 86 | adcChannel_currentA.Offset = 0; |
nki | 11:1a68e17c0279 | 87 | if (HAL_ADC_ConfigChannel(&g_AdcHandle, &adcChannel_currentA) != HAL_OK) { |
nki | 11:1a68e17c0279 | 88 | asm("bkpt 255"); |
nki | 11:1a68e17c0279 | 89 | } |
nki | 11:1a68e17c0279 | 90 | //duplicated the previous 7 lines here with the ADC channel changed to 8, corresponding to PB_0 |
nki | 11:1a68e17c0279 | 91 | adcChannel_currentB.Channel = ADC_CHANNEL_8; |
nki | 11:1a68e17c0279 | 92 | adcChannel_currentB.Rank = 2; |
nki | 11:1a68e17c0279 | 93 | adcChannel_currentB.SamplingTime = ADC_SAMPLETIME_480CYCLES; |
nki | 11:1a68e17c0279 | 94 | adcChannel_currentB.Offset = 0; |
nki | 11:1a68e17c0279 | 95 | if (HAL_ADC_ConfigChannel(&g_AdcHandle, &adcChannel_currentB) != HAL_OK) { |
nki | 11:1a68e17c0279 | 96 | asm("bkpt 255"); |
nki | 11:1a68e17c0279 | 97 | } |
nki | 11:1a68e17c0279 | 98 | } |
nki | 11:1a68e17c0279 | 99 | |
nki | 11:1a68e17c0279 | 100 | DMA_HandleTypeDef currentAB_DmaHandle; |
nki | 11:1a68e17c0279 | 101 | |
nki | 11:1a68e17c0279 | 102 | void ConfigureDMA() |
nki | 11:1a68e17c0279 | 103 | { |
nki | 11:1a68e17c0279 | 104 | __DMA2_CLK_ENABLE(); |
nki | 11:1a68e17c0279 | 105 | |
nki | 11:1a68e17c0279 | 106 | currentAB_DmaHandle.Instance = DMA2_Stream4; |
nki | 11:1a68e17c0279 | 107 | currentAB_DmaHandle.Init.Channel = DMA_CHANNEL_0; |
nki | 11:1a68e17c0279 | 108 | currentAB_DmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; |
nki | 11:1a68e17c0279 | 109 | currentAB_DmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; |
nki | 11:1a68e17c0279 | 110 | currentAB_DmaHandle.Init.MemInc = DMA_MINC_ENABLE; |
nki | 11:1a68e17c0279 | 111 | currentAB_DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; |
nki | 11:1a68e17c0279 | 112 | currentAB_DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; |
nki | 11:1a68e17c0279 | 113 | currentAB_DmaHandle.Init.Mode = DMA_CIRCULAR; |
nki | 11:1a68e17c0279 | 114 | currentAB_DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; |
nki | 11:1a68e17c0279 | 115 | currentAB_DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; |
nki | 11:1a68e17c0279 | 116 | currentAB_DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; |
nki | 11:1a68e17c0279 | 117 | currentAB_DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; |
nki | 11:1a68e17c0279 | 118 | currentAB_DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; |
nki | 11:1a68e17c0279 | 119 | HAL_DMA_Init(¤tAB_DmaHandle); |
nki | 11:1a68e17c0279 | 120 | |
nki | 11:1a68e17c0279 | 121 | __HAL_LINKDMA(&g_AdcHandle, DMA_Handle, currentAB_DmaHandle); //linking ADC1 to DMA2_Stream4 |
nki | 11:1a68e17c0279 | 122 | HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 0); |
nki | 11:1a68e17c0279 | 123 | HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn); |
nki | 11:1a68e17c0279 | 124 | } |
nki | 11:1a68e17c0279 | 125 | |
nki | 11:1a68e17c0279 | 126 | static void SystemClock_Config(void) |
nki | 11:1a68e17c0279 | 127 | { |
nki | 11:1a68e17c0279 | 128 | RCC_ClkInitTypeDef RCC_ClkInitStruct; |
nki | 11:1a68e17c0279 | 129 | RCC_OscInitTypeDef RCC_OscInitStruct; |
nki | 11:1a68e17c0279 | 130 | |
nki | 11:1a68e17c0279 | 131 | __HAL_RCC_PWR_CLK_ENABLE(); |
nki | 11:1a68e17c0279 | 132 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); |
nki | 11:1a68e17c0279 | 133 | |
nki | 11:1a68e17c0279 | 134 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; |
nki | 11:1a68e17c0279 | 135 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; |
nki | 11:1a68e17c0279 | 136 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; |
nki | 11:1a68e17c0279 | 137 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; |
nki | 11:1a68e17c0279 | 138 | RCC_OscInitStruct.PLL.PLLM = 8; |
nki | 11:1a68e17c0279 | 139 | RCC_OscInitStruct.PLL.PLLN = 288; |
nki | 11:1a68e17c0279 | 140 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; |
nki | 11:1a68e17c0279 | 141 | RCC_OscInitStruct.PLL.PLLQ = 6; |
nki | 11:1a68e17c0279 | 142 | HAL_RCC_OscConfig(&RCC_OscInitStruct); |
nki | 11:1a68e17c0279 | 143 | |
nki | 11:1a68e17c0279 | 144 | RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); |
nki | 11:1a68e17c0279 | 145 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; |
nki | 11:1a68e17c0279 | 146 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; |
nki | 11:1a68e17c0279 | 147 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; |
nki | 11:1a68e17c0279 | 148 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; |
nki | 11:1a68e17c0279 | 149 | HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); |
nki | 11:1a68e17c0279 | 150 | SystemCoreClockUpdate(); |
nki | 11:1a68e17c0279 | 151 | |
nki | 11:1a68e17c0279 | 152 | if (HAL_GetREVID() == 0x1001) |
nki | 11:1a68e17c0279 | 153 | __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); |
nki | 11:1a68e17c0279 | 154 | } |
nki | 11:1a68e17c0279 | 155 | |
nki | 11:1a68e17c0279 | 156 | extern "C" void TIM1_UP_TIM10_IRQHandler(void) { //this samples current at the 000 state |
bwang | 1:7b61790f6be9 | 157 | if (TIM1->SR & TIM_SR_UIF ) { |
nki | 11:1a68e17c0279 | 158 | |
bwang | 1:7b61790f6be9 | 159 | } |
bwang | 1:7b61790f6be9 | 160 | TIM1->SR = 0x00; |
bwang | 1:7b61790f6be9 | 161 | } |
bwang | 1:7b61790f6be9 | 162 | |
bwang | 1:7b61790f6be9 | 163 | void zero_current(){ |
bwang | 1:7b61790f6be9 | 164 | } |
bwang | 0:bac9c3a3a6ca | 165 | |
nki | 11:1a68e17c0279 | 166 | void config_globals() { |
bwang | 1:7b61790f6be9 | 167 | //Enable clocks for GPIOs |
bwang | 1:7b61790f6be9 | 168 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; |
bwang | 1:7b61790f6be9 | 169 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; |
bwang | 1:7b61790f6be9 | 170 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; |
bwang | 1:7b61790f6be9 | 171 | |
bwang | 1:7b61790f6be9 | 172 | RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; //enable TIM1 clock |
bwang | 1:7b61790f6be9 | 173 | |
bwang | 1:7b61790f6be9 | 174 | a = new FastPWM(PWMA); |
bwang | 1:7b61790f6be9 | 175 | b = new FastPWM(PWMB); |
bwang | 1:7b61790f6be9 | 176 | c = new FastPWM(PWMC); |
bwang | 1:7b61790f6be9 | 177 | |
bwang | 1:7b61790f6be9 | 178 | NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); //Enable TIM1 IRQ |
bwang | 1:7b61790f6be9 | 179 | |
bwang | 1:7b61790f6be9 | 180 | TIM1->DIER |= TIM_DIER_UIE; //enable update interrupt |
bwang | 1:7b61790f6be9 | 181 | TIM1->CR1 = 0x40; //CMS = 10, interrupt only when counting up |
bwang | 1:7b61790f6be9 | 182 | TIM1->CR1 |= TIM_CR1_ARPE; //autoreload on, |
bwang | 1:7b61790f6be9 | 183 | TIM1->RCR |= 0x01; //update event once per up/down count of tim1 |
bwang | 1:7b61790f6be9 | 184 | TIM1->EGR |= TIM_EGR_UG; |
bwang | 1:7b61790f6be9 | 185 | |
bwang | 1:7b61790f6be9 | 186 | TIM1->PSC = 0x00; //no prescaler, timer counts up in sync with the peripheral clock |
bwang | 1:7b61790f6be9 | 187 | TIM1->ARR = 0x4650; //5 Khz |
bwang | 1:7b61790f6be9 | 188 | TIM1->CCER |= ~(TIM_CCER_CC1NP); //Interupt when low side is on. |
bwang | 1:7b61790f6be9 | 189 | TIM1->CR1 |= TIM_CR1_CEN; |
bwang | 1:7b61790f6be9 | 190 | |
nki | 11:1a68e17c0279 | 191 | //ADCs PA_4 and PB_0 for current sensing |
nki | 11:1a68e17c0279 | 192 | // PA_4 PA_2 PA_0 PB_0 PC_1 analog |
bwang | 1:7b61790f6be9 | 193 | |
bwang | 1:7b61790f6be9 | 194 | |
bwang | 1:7b61790f6be9 | 195 | //DAC setup |
bwang | 1:7b61790f6be9 | 196 | RCC->APB1ENR |= 0x20000000; |
bwang | 1:7b61790f6be9 | 197 | DAC->CR |= DAC_CR_EN2; |
bwang | 1:7b61790f6be9 | 198 | |
bwang | 1:7b61790f6be9 | 199 | GPIOA->MODER |= (1 << 10); |
bwang | 1:7b61790f6be9 | 200 | GPIOA->MODER |= (1 << 11); |
bwang | 1:7b61790f6be9 | 201 | |
bwang | 1:7b61790f6be9 | 202 | //Zero duty cycles |
bwang | 1:7b61790f6be9 | 203 | set_dtc(a, 0.0f); |
bwang | 1:7b61790f6be9 | 204 | set_dtc(b, 0.0f); |
bwang | 1:7b61790f6be9 | 205 | set_dtc(c, 0.0f); |
bwang | 1:7b61790f6be9 | 206 | |
bwang | 1:7b61790f6be9 | 207 | wait_ms(250); |
bwang | 1:7b61790f6be9 | 208 | zero_current(); |
bwang | 0:bac9c3a3a6ca | 209 | en = 1; |
bwang | 0:bac9c3a3a6ca | 210 | } |
bwang | 0:bac9c3a3a6ca | 211 | |
bwang | 0:bac9c3a3a6ca | 212 | void startup_msg() { |
nki | 11:1a68e17c0279 | 213 | pc.printf("%s\n\r\n\r", "FOC'ed in the Bot Rev xA."); |
bwang | 0:bac9c3a3a6ca | 214 | } |
bwang | 0:bac9c3a3a6ca | 215 | |
bwang | 4:a6669248ce4d | 216 | void commutate() { |
nki | 11:1a68e17c0279 | 217 | //p = pos.GetElecPosition() - POS_OFFSET; |
nki | 11:1a68e17c0279 | 218 | p = 0.0f; |
bwang | 0:bac9c3a3a6ca | 219 | if (p < 0) p += 2 * PI; |
bwang | 0:bac9c3a3a6ca | 220 | |
bwang | 2:eabe8feaaabb | 221 | float sin_p = sinf(p); |
bwang | 2:eabe8feaaabb | 222 | float cos_p = cosf(p); |
bwang | 2:eabe8feaaabb | 223 | |
nki | 10:6829abb438fc | 224 | float pos_dac = 0.85f * p / (2 * PI) + 0.05f; |
nki | 10:6829abb438fc | 225 | DAC->DHR12R2 = (unsigned int) (pos_dac * 4096); |
bwang | 0:bac9c3a3a6ca | 226 | |
bwang | 1:7b61790f6be9 | 227 | ia = ((float) adval1 / 4096.0f * AVDD - I_OFFSET - ia_supp_offset) / I_SCALE; |
bwang | 1:7b61790f6be9 | 228 | ib = ((float) adval2 / 4096.0f * AVDD - I_OFFSET - ib_supp_offset) / I_SCALE; |
bwang | 2:eabe8feaaabb | 229 | ic = -ia - ib; |
bwang | 0:bac9c3a3a6ca | 230 | |
nki | 10:6829abb438fc | 231 | float u = ia; |
nki | 10:6829abb438fc | 232 | float v = ib; |
bwang | 2:eabe8feaaabb | 233 | |
bwang | 2:eabe8feaaabb | 234 | alpha = u; |
bwang | 2:eabe8feaaabb | 235 | beta = 1 / sqrtf(3.0f) * u + 2 / sqrtf(3.0f) * v; |
bwang | 2:eabe8feaaabb | 236 | |
bwang | 2:eabe8feaaabb | 237 | d = alpha * cos_p - beta * sin_p; |
bwang | 2:eabe8feaaabb | 238 | q = -alpha * sin_p - beta * cos_p; |
bwang | 2:eabe8feaaabb | 239 | |
bwang | 3:9b20da3f0055 | 240 | float d_err = d_ref - d; |
bwang | 3:9b20da3f0055 | 241 | float q_err = q_ref - q; |
bwang | 2:eabe8feaaabb | 242 | |
bwang | 2:eabe8feaaabb | 243 | d_integral += d_err * KI; |
bwang | 2:eabe8feaaabb | 244 | q_integral += q_err * KI; |
bwang | 2:eabe8feaaabb | 245 | |
bwang | 2:eabe8feaaabb | 246 | if (q_integral > INTEGRAL_MAX) q_integral = INTEGRAL_MAX; |
bwang | 2:eabe8feaaabb | 247 | if (d_integral > INTEGRAL_MAX) d_integral = INTEGRAL_MAX; |
bwang | 2:eabe8feaaabb | 248 | if (q_integral < -INTEGRAL_MAX) q_integral = -INTEGRAL_MAX; |
bwang | 2:eabe8feaaabb | 249 | if (d_integral < -INTEGRAL_MAX) d_integral = -INTEGRAL_MAX; |
bwang | 2:eabe8feaaabb | 250 | |
bwang | 2:eabe8feaaabb | 251 | vd = KP * d_err + d_integral; |
bwang | 2:eabe8feaaabb | 252 | vq = KP * q_err + q_integral; |
bwang | 2:eabe8feaaabb | 253 | |
bwang | 2:eabe8feaaabb | 254 | if (vd < -1.0f) vd = -1.0f; |
bwang | 2:eabe8feaaabb | 255 | if (vd > 1.0f) vd = 1.0f; |
bwang | 2:eabe8feaaabb | 256 | if (vq < -1.0f) vq = -1.0f; |
bwang | 2:eabe8feaaabb | 257 | if (vq > 1.0f) vq = 1.0f; |
bwang | 2:eabe8feaaabb | 258 | |
nki | 10:6829abb438fc | 259 | //DAC->DHR12R2 = (unsigned int) (-q * 20 + 2048); |
bwang | 2:eabe8feaaabb | 260 | //DAC->DHR12R2 = (unsigned int) (-vd * 2000 + 2048); |
bwang | 2:eabe8feaaabb | 261 | |
bwang | 4:a6669248ce4d | 262 | //vd = 0.0f; |
bwang | 4:a6669248ce4d | 263 | //vq = -1.0f; |
bwang | 4:a6669248ce4d | 264 | |
bwang | 2:eabe8feaaabb | 265 | float valpha = vd * cos_p - vq * sin_p; |
bwang | 2:eabe8feaaabb | 266 | float vbeta = vd * sin_p + vq * cos_p; |
bwang | 2:eabe8feaaabb | 267 | |
bwang | 2:eabe8feaaabb | 268 | float va = valpha; |
bwang | 2:eabe8feaaabb | 269 | float vb = -0.5f * valpha - sqrtf(3) / 2.0f * vbeta; |
bwang | 2:eabe8feaaabb | 270 | float vc = -0.5f * valpha + sqrtf(3) / 2.0f * vbeta; |
bwang | 2:eabe8feaaabb | 271 | |
bwang | 2:eabe8feaaabb | 272 | set_dtc(a, 0.5f + 0.5f * va); |
bwang | 2:eabe8feaaabb | 273 | set_dtc(b, 0.5f + 0.5f * vb); |
bwang | 2:eabe8feaaabb | 274 | set_dtc(c, 0.5f + 0.5f * vc); |
bwang | 0:bac9c3a3a6ca | 275 | } |
bwang | 0:bac9c3a3a6ca | 276 | |
bwang | 0:bac9c3a3a6ca | 277 | int main() { |
nki | 11:1a68e17c0279 | 278 | pc.baud(115200); |
bwang | 0:bac9c3a3a6ca | 279 | config_globals(); |
bwang | 0:bac9c3a3a6ca | 280 | startup_msg(); |
bwang | 0:bac9c3a3a6ca | 281 | |
nki | 11:1a68e17c0279 | 282 | HAL_Init(); |
nki | 11:1a68e17c0279 | 283 | SystemClock_Config(); |
nki | 11:1a68e17c0279 | 284 | ConfigureADC(); |
nki | 11:1a68e17c0279 | 285 | ADC1->CR2 |= (1<<0); //A/D on |
nki | 11:1a68e17c0279 | 286 | // ADC1->CR2 |= (1<<8); //DMA mode |
nki | 11:1a68e17c0279 | 287 | //ConfigureDMA(); |
nki | 11:1a68e17c0279 | 288 | HAL_ADC_Start_IT(&g_AdcHandle); |
nki | 11:1a68e17c0279 | 289 | //HAL_ADC_Start_DMA(&g_AdcHandle, g_ADCBuffer, ADC_BUFFER_LENGTH); //this enables the overrun interrupt |
nki | 11:1a68e17c0279 | 290 | |
nki | 11:1a68e17c0279 | 291 | //HAL_DMAEx_MultiBufferStart(..) wants uint32_t that are the destination addresses of the buffers. |
nki | 11:1a68e17c0279 | 292 | uint32_t currentA_ADCBufferAddress = (uint32_t)¤tA_ADCBuffer[0]; |
nki | 11:1a68e17c0279 | 293 | uint32_t currentB_ADCBufferAddress = (uint32_t)¤tB_ADCBuffer[0]; |
nki | 11:1a68e17c0279 | 294 | |
nki | 11:1a68e17c0279 | 295 | //HAL_DMAEx_MultiBufferStart(¤tAB_DmaHandle, ADC1->DR, currentA_ADCBufferAddress, currentB_ADCBufferAddress, ADC_BUFFER_LENGTH); //DMA_Handle, SrcAddress, DstAddress, DstAddress2, DataLength |
nki | 11:1a68e17c0279 | 296 | |
bwang | 0:bac9c3a3a6ca | 297 | for (;;) { |
nki | 11:1a68e17c0279 | 298 | //ADC1->CR1 |= 0x4000000; |
nki | 11:1a68e17c0279 | 299 | //pc.printf("%d \n\r", ADC1->DR); |
nki | 11:1a68e17c0279 | 300 | //pc.printf("%d \n\r", ADC1->SR); |
nki | 11:1a68e17c0279 | 301 | pc.printf("%d %d \n\r", currentA_ADCValue, currentB_ADCValue); |
nki | 11:1a68e17c0279 | 302 | //pc.printf("%d \n\r", currentB_ADCValue); |
nki | 11:1a68e17c0279 | 303 | //pc.printf("%d \n\r", debug_int); |
nki | 11:1a68e17c0279 | 304 | //pc.printf("%s %x %s %x\n\r", "CR1:" , ADC1->CR1, "CR2:" , ADC1->CR2); |
bwang | 0:bac9c3a3a6ca | 305 | } |
bwang | 0:bac9c3a3a6ca | 306 | } |
nki | 11:1a68e17c0279 | 307 | |
nki | 11:1a68e17c0279 | 308 | extern "C" //legacy C code goes here |
nki | 11:1a68e17c0279 | 309 | { |
nki | 11:1a68e17c0279 | 310 | void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) |
nki | 11:1a68e17c0279 | 311 | { |
nki | 11:1a68e17c0279 | 312 | //currentA_ADCValue = HAL_ADC_GetValue(AdcHandle) |
nki | 11:1a68e17c0279 | 313 | toggle = state; |
nki | 11:1a68e17c0279 | 314 | state = !state; |
nki | 11:1a68e17c0279 | 315 | if(state){currentA_ADCValue = ADC1->DR;} |
nki | 11:1a68e17c0279 | 316 | else{currentB_ADCValue = ADC1->DR;} |
nki | 11:1a68e17c0279 | 317 | toggle = state; |
nki | 11:1a68e17c0279 | 318 | |
nki | 11:1a68e17c0279 | 319 | /* |
nki | 11:1a68e17c0279 | 320 | currentA_ADCValue = std::accumulate(currentA_ADCBuffer, currentA_ADCBuffer + ADC_BUFFER_LENGTH, 0) / ADC_BUFFER_LENGTH; |
nki | 11:1a68e17c0279 | 321 | currentB_ADCValue = std::accumulate(currentB_ADCBuffer, currentB_ADCBuffer + ADC_BUFFER_LENGTH, 0) / ADC_BUFFER_LENGTH; |
nki | 11:1a68e17c0279 | 322 | g_MeasurementNumber += ADC_BUFFER_LENGTH; |
nki | 11:1a68e17c0279 | 323 | */ |
nki | 11:1a68e17c0279 | 324 | } |
nki | 11:1a68e17c0279 | 325 | |
nki | 11:1a68e17c0279 | 326 | void DMA2_Stream4_IRQHandler() |
nki | 11:1a68e17c0279 | 327 | { |
nki | 11:1a68e17c0279 | 328 | HAL_DMA_IRQHandler(¤tAB_DmaHandle); |
nki | 11:1a68e17c0279 | 329 | } |
nki | 11:1a68e17c0279 | 330 | |
nki | 11:1a68e17c0279 | 331 | void ADC_IRQHandler() |
nki | 11:1a68e17c0279 | 332 | { |
nki | 11:1a68e17c0279 | 333 | HAL_ADC_IRQHandler(&g_AdcHandle); |
nki | 11:1a68e17c0279 | 334 | |
nki | 11:1a68e17c0279 | 335 | } |
nki | 11:1a68e17c0279 | 336 | } |