Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : two programming environments for the STM32F4V
Author | Message | ||||
poida Guru Joined: 02/02/2017 Location: AustraliaPosts: 1388 |
I've spent a little time playing with a STM32F4VET6 based cheapie from Aliexpress The Arduino IDE does work with this board, but you need to use the ST-LINK programmer. The alternative IDE used was Atollic truestudio for STM32. This is also a free download. The F4 offers hardware floating point support. Until now, I have used the ATMega 328p (Arduino Uno, etc), the Atmel SAM3 (Arduino Due), the ESP32 Wroom and the STM32F1 "Blue pill". All lack floating point hardware. I wanted to see how fast it can go. The task is the Lorenz Atractor, see Paul Bourke's page with code examples The code continuously loops, calculating new values that are then fed back into the loop. If you monitor the variables x0, y0 and z0 you will see lovely chaotic behaviour. feed x0 and y0 into a DAC and then take these to an oscilloscope and you will see the same sort of thing as seen in the web page. You could output these via a serial port and plot them, just as good and easy to do with the Arduino IDE. Measured times for an iteration through the continuous loop: Arduino Due (SAM3, 84MHz): 20 usec F4, 168Mhz, Arduino : 6 usec F4, 168Mhz, Atollic : 0.288 usec The F4 is fast. The Arduino IDE is not able to compile code using the floating point hardware, due to included libraries that are precompiled using soft floats. The Atollic IDE can compile code using the floating point hardware, and it can employ optimisation too, and it's good quality. Timing was done using a DSO monitoring a GPIO pin. Anyway, I thought some here might want to get an idea of how good the STMF4 is for the price and the compute power. I paid $9.70 US for it. It's probably the pick of the litter for running MMBASIC on. Here are the codes used. I freely use direct hardware manipulation for digital i/o and DAC access. Arduino DUE char buf[100]; inline void digitalWriteDirect(int pin, boolean val){ if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin; else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin; } void setup() { Serial.begin(115200); pinMode(5, OUTPUT); analogWrite(DAC0,0); analogWrite(DAC1,0); REG_DACC_ACR = 0x00000000; REG_DACC_MR |= 0x100010; } void da(unsigned int x, unsigned int y) { // fastest 2 channel DAC, 420 nS, needs some preparation, see below REG_DACC_CDR = x + (y << 16) + 0x10000000; // needs REG_DACC_MR |= 0x100010; for tag and word update mode while ((REG_DACC_ISR & 2) == 0) ; // wait for tx to complete. Better than checking tx empty prior to transfer } void loop() { int x,y; float x0,y0,z0,x1,y1,z1; float h = 0.001, a = 10.0,b = 28.0, c = 8.0 / 3.0; float tx,ty,s=30.0; int i=0; x0 = 0.1; y0 = 0.0; z0 = 0.0; while(1) { digitalWriteDirect(5,HIGH); if (i++ > 1000) { i=0; c = (8.0/3.0) -2.0 + 10.0*analogRead(1)/1024.0; } x1 = x0 + h * a * (y0 - x0); y1 = y0 + h * (x0 * (b - z0) - y0); z1 = z0 + h * (x0 * y0 - c * z0); x0 = x1; y0 = y1; z0 = z1; tx = y0*s; if(tx > 1500.0) tx = 1500.0;if(tx < -1500.0) tx = -1500.0; ty = z0*s; if(ty > 1500.0) ty = 1500.0;if(ty < -1500.0) ty = -1500.0; x = 1800 + (int)(tx); y = 1800 + (int)(ty); da(x,y); digitalWriteDirect(5,LOW); } } STM32F4 for the Arduino IDE volatile uint32_t *dacdual = (uint32_t *)(0x40007420); volatile uint32_t *dacctl = (uint32_t *)(0x40007400); volatile uint32_t *gpiod_odr = (uint32_t *)(0x40020c14); void setup() { RCC->APB1ENR |= (1 << 29); // enable DAC peripheral clock *dacctl = (1 << 16) + 1 ; // enable dac1 and dac2 *dacdual takes 2 values pinMode(PD14,OUTPUT); } void loop() { int x,y; float x0,y0,z0,x1,y1,z1; float h = 0.01, a = 10.0,b = 28.0, c = 8.0 / 3.0; float tx,ty,s=60.0; int i=0; x0 = 0.1; y0 = 0.0; z0 = 0.0; while(1) { *gpiod_odr = 0x4000; x1 = x0 + h * a * (y0 - x0); y1 = y0 + h * (x0 * (b - z0) - y0); z1 = z0 + h * (x0 * y0 - c * z0); x0 = x1; y0 = y1; z0 = z1; tx = x0*s; if(tx > 1500.0) tx = 1500.0;if(tx < -1500.0) tx = -1500.0; ty = y0*s; if(ty > 1500.0) ty = 1500.0;if(ty < -1500.0) ty = -1500.0; x = 1800 + (int)(tx); y = 1800 + (int)(ty); *dacdual = x + (y << 16); *gpiod_odr = 0; } } and finally the F4 code used in Atollic IDE #include "stm32f4xx.h" #include "math.h" #include "stdio.h" int gx,gy; volatile uint32_t *dacdual = (uint32_t *) (0x40007420); volatile uint32_t *dacctl = (uint32_t *) (0x40007400); volatile uint32_t *gpiod = (uint32_t *)(0x40020c14); void setup_DAC() { RCC->APB1ENR |= (1 << 29); // enable DAC perif clock *dacctl = (1 << 16) + 1; // enable dac1 and dac2 *dacdual takes 2 values } void config_pins(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStructure); //GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); } int main(void) { float x0, y0, z0, x1, y1, z1, h = 0.01, a = 10.0, b = 28.0, c = 8.0 / 3.0; float tx, ty; int ix,iy,oix=0,oiy=0; float s; char buf[100]; int i; setup_DAC(); config_pins(); s = 70.0; i=0; x0 = 0.1; y0 = 0.0; z0 = 0.0; while (1) { *gpiod = 0x1000; x1 = x0 + h * a * (y0 - x0); y1 = y0 + h * (x0 * (b - z0) - y0); z1 = z0 + h * (x0 * y0 - c * z0); x0 = x1; y0 = y1; z0 = z1; tx = (2000.0 + x0*s); ix = (int)tx; if(ix > 4000) ix = 4000;if(ix < 300) ix = 300; ty = (2000.0 + y0*s); iy = (int)ty; if(iy > 4000) iy = 4000;if(iy < 300) iy = 300; *dacdual = ix + (iy << 16); //sprintf(buf," %x \n",dacval); send_uart(buf); *gpiod = 0; } } Edited 2019-10-11 15:01 by poida wronger than a phone book full of wrong phone numbers |
||||
ceptimus Senior Member Joined: 05/07/2019 Location: United KingdomPosts: 130 |
I guess you know already that Peter Mather ported the Micromite to that board. See this thread It defaults to using the ILI9341 16-bit touch display. You can get them in various sizes up to 3.2-inch. You can get one on AliExpress that fits direct to the TFT connector on the board, but it's awkward to support it properly. I wanted more of a 'backpack' design for mine so I chose to use the cheaper display from Ebay - the 34-pin one - it has a different pin-out but I designed a 'shim' PCB to make the connections and also designed and 3D-printed a mount that fastens the display to the back of the board and allows it to be panel mounted or free standing on a desk. I solder the shim PCB direct to the STM32F4VE 'TFT' pins, and then have a socket (double row of female headers) soldered to the other side for the display module to plug into. This spaces the display far enough away from the back of the STM board so that the mount is thick enough to allow self-tapping screws to fasten down the display module. The display has a full-size SD card holder on the back, which you can connect up if you want to - but I don't bother, I use the STM32F4's on-board micro SD. . Edited 2019-10-13 05:38 by ceptimus |
||||
Print this page |