Fórum témák
- • Érdekességek
- • Csere-bere
- • Számítógép hiba, de mi a probléma?
- • Erősítő mindig és mindig
- • Autóelektronika
- • Jókívánság
- • Parkside akkuk javìtása
- • Sütő javítás
- • NYÁK terv ellenőrzése
- • Felajánlás, azaz ingyen elvihető
- • NYÁK készítés CNC-vel
- • Crystal radio - detektoros rádió
- • Hawksford Error Correction
- • Hűtőgép probléma
- • LED-es világítás
- • Vicces - mókás történetek
- • PLC kérdések
- • Transzformátor készítés, méretezés
- • Villanyszerelés
- • Elfogadnám, ha ingyen elvihető
- • Jó lesz ez még valamire (újrahasznosítás)
- • Tápegységgel kapcsolatos kérdések
- • Mosogatógép hiba
- • Mosógépmotor bekötése
- • Li-Po - Li-ion akkumulátor és töltője
- • Tárcsázós telefon
- • 2 nagy LCD modul hasznosítása
- • Oszcilloszkóp vétel, mit gondoltok?
- • LED kijelzős digitális óra
- • 3D-s megjelenítés, a panelok virtuális képének létrehozási lehetőségei
- • Hiraga erősitő
- • Forrasztópákák - melyik miért jó
- • Villanypásztor
- • Arduino
- • V-FET és SIT erősítő kapcsolások
- • Villanymotor bekötése
- • Zigbee-s működés jelző led fény érzékelő
- • LCD kijelző vezérlése, életre keltése
- • Whirlpool mosógép
- • AVR-es alkatrész (tranzisztor) teszter
- • Léptetőmotorok (vezérlése)
- • Kávéfőzőgép hiba
- • MSP430 mikrovezérlők
- • Labortápegység készítése
- • Elektronikus szulfátoldó (Akku aktivátor)
- • Szilárdtest relé
- • Rádió építés a kezdetektől a világvevőig
- • Mikrohullámú sütő javítás, magnetron csere, stb.
- • CRT monitor javítás
- • Kamerás megfigyelőrendszer
- • Kombikazán működési hiba
- • Áramváltó trafóval áram mérés, hogy?
- • Mosógép vezérlők és általános problémáik
- • Szünetmentes táp javítása, élesztése
- • Kondenzátor
» Több friss téma
|
Fórum » ARM - Miértek hogyanok
Kihagynám: egyrészt nem ad rendes tápot (sem 3.3V, sem 5V, másrészt meg 15 euro. Ennyiért már zenéljen is).
Lehet, hogy a Black Magic Probe-bal felülvágom a firmware-t, megnézem hogyan megy.
A SWIM-et (PB11) elvileg UART RX-ként is lehet használni. Kis módosítással lehet, hogy menne.
Bár annyira nem érdekel a dolog.
Lehet, hogy egyszerűbb valódi USB-n átküldeni az adatokat.
Ez egy J-Link. Speciel sokkal gyorsabb mint az ST-Link. Dolgozz majd kicsit a nagyobb uC-kel, ahol már sokkal nagyobb a program, ég és föld a kettő.
"Nem tudom végül mi oldotta meg de letöröltem újratettem állítgattam össze vissza végül valahogy újból elkezdett működni."
Egész napi szerencsétlenkedés után úgy néz ki, hogy egy
ST-LINK_CLI.exe -c -ID=0 SWD UR
parancs kiadása után (kiadáskor a Reset gombot nyomva kell tartani, majd elengedni) egy darabig újra használható lesz az ST-link és az ST-Link Utility.
A BAITE gyártmányú klónnal sajnos tényleg nem sikerült az SWO kimenetet fogadni (bár homályos emlékeim szerint pont emiatt vettem meg ezt a kütyüt, mert a JTAG opció aligha izgatott, SDW programozóm pedig már volt kettő is).
Sajnos, már nem emlékszem rá, hogy tavasszal milyen eszközökkel és pontosan hogyan (kínai J-link klón? Blue pill + ST-Link firmware? ST-Link klón?) sikerült az SWO kimenetet használni. Itt írtam róla.
Közben rájöttem, hogy Itt írta csabeszq kolléga, hogy a "Best Quality ST-Link" rendelkezik SWO bemenettel, ezen felbuzdulva rendeltem én is egyet. De a fenti kísérletben még azt nyilván nem használhattam. A hozzászólás módosítva: Nov 17, 2017
A legegyszerűbb megoldás SWO-ra a "Best Quality ST-Link" átalakítása. A kínaiak félig voltak trehányok, mert a JTDO/SWO pineket nem kötötték össze, viszont a PA10-re csináltak jól forrasztható tappancsot.
Nem csináltam mást, mint egy zsugorcsőbe belepakoltam egy 220 ohmos ellenállást és összekötöttem a PA10-et a JTDO-val lásd fotókat.
Innentől simán ment az SWO nekem Keil alatt.
Idézet: „Nem valószínű. Ráadásul nem sokban különbözik az eredetitől. Akár te magad is készíthetsz. Legegyszerűbben egy bluepill, két ellenállás, két led, plusz a firmware.”
Blue pillre sikerült esetleg V2.1-es firmware-t raknod? Abban már van VCP (virtuális comm port), magyarul ha magam készítenék stlink-et, akkor az UART RX/TX fantasztikus lenne. Tök jó az SWO, de az UART azért mégiscsak jobb. Megérni saját programozót csinálni UART-tal.
Ha van esetleg tört 2.1-es firmware-ed, amit fel lehetne pakolni, az jó lenne.
Ami probléma, hogy 128k-s chip kellene neki. Az meg is van, csak 64k-s nak hazudja magát.
A V2-es bootloadert simán felraktam a blue pillre, sőt frissíti is magát, de a 2.1 nekem nem nagyon indul el.
Idézet: „de a 2.1 nekem nem nagyon indul el”
A V2-1-re gondolsz? Honnan sikerült letöltened?
Feltöltötted, és nem működik?
Itt vannak a bootloader-ek:
https://github.com/Krakenw/Stlink-Bootloaders
Csak a bootloader-t felrakod (v2 unprotected), értelemszerűen a panel nem fog csinálni semmi.
Viszont firmware update-nél a blue pill-t elfogadja. Magyarul felrakom a bootloader-t, firmware update és a legfrissebb V2-es firmware felmegy.
Ezután minthogy az unprotected bootloadert raktad fel, ki is olvashatod a memória tartalmát.
Az unprotected változat az option bitekben a firmware tiltást NOP-okkal helyettesíti.
Csináltam egyébként hex fájlt is a firmware-ből, hogy egy lépésben lehessen telepíteni, szórakozás nélkül.
Csatoltam egy ST-Link V2/1-es hex fájlt blue pillre.
Nem tudom, hogy jól működik-e, 3 eszköz jelenik meg miután bedugom:
- az ST-LINK programozó
- a modem (soros port)
- és egy NUCLEO nevű meghajtó (mass storage device)
Majd letesztelem, látszólag elindul, nem játszottam vele sokat.
A firmware update biztosan nem fog vele menni, mert 64k-s chipre hivatalosan nem lehet 128k-t felpaszírozni. A kód viszont nagyobb 64k-nál, túlírjuk a chipet.
Részletek:
- letöltöttem a bootloader-t
- a bootloadert megfoltoztam, hogy 128k-s a chip mérete, ne olvassa ki 0x1FFFF7E0 címről
- letöltöttem a legfrissebb st-link utility-t, van egy AllPlatform része, java-ban írva
- Az STLinkUpgrade.jar egy zip fájl, tartalmazza a firmware-eket, az f2_4.bin a firmware neve
- az st-decrypt program segítségével dekódoltam a firmware-t (feltörtem)
- a firmware akkor érvényes, ha az utolsó 4 byte a 0x0801FFFC címen 0xD3 0x27 0x00 0xA5
írtam egy szkriptet, ami
- törli a chipet
- 0x08000000 címtől kiírja a megfoltozott bootloadert
- 0x08004000 címtől feltölti a feltört firmware-t
- 0x0801FFFC-n meg beállítja az utolsó 4 byte-ot érvényesnek
Ezután a kód elindul, hogy működik-e, még kérdéses. Mindenesetre jó szórakozás volt egy kicsit warezolni.
A fentebb csatolt firmware-t sikerült végigtesztelni.
- ment a feltöltés, lekérés
- ment a debug
- szépen RESET-elt, jól adta az NRST-t
- jól ment az SWO
- ment az USART RX/TX
- szépen kapcsolgatta a LED-eket
- ment a drag & drop feltöltés a csatolt meghajtón keresztül
Az ST-LINK V2/1 firmware érdekessége, hogy nincs benne SWIMM ( STM8) támogatás, a Nucleo panel része. Nagyon frankó, hogy van benne kétirányú USART átalakító is, emellett ha egy .bin kiterjesztésű bináris fájlt dobok a meghajtóba, akkor feltölti azt. Úgy megy, hogy mondjuk a progim.bin-t felmásolom, bár hex fájlokra nálam nem ment.
A JTAG-et nem próbáltam ki, az USB reenumerationt sem. Lehet, hogy valamikor érdemes lesz egy próba panelt legyártani, ami az ST-LINK V2/1-es kivezetéseket tartalmazza blue pill-en.
Egy próbát szerintem mindenkinél megér, mert nem a tipikus ST-LINK-es cucc.
Kapcsolási rajz itt. A hozzászólás módosítva: Nov 19, 2017
És olyan hekkelt st-link firmware-röl nem tudsz amivel fel lehet programozni a magát 64kB-osnak valló, de valójában 128kB-os f103C8T6-t teljes memóriaterületét?
Én linuxot használok, ott az st-flash-től az openocd-n keresztül minden szét van peccselve.
Windows alatt megnyitottam az ST-Link Utility-t:
- File -> Open file... -> 128k-s hex fájl neve
- Target -> Program & Verify -> Start
Akadékoskodás nélkül fölment a cucc. Kiírta, hogy a chip 64k, viszont tovább már nem érdekli. Az ST-Link Utility simán írja olvassa a 128k-t.
Köszi, az ST-Link Utility alatt már működik, most ráálltam az openocd hekkelésére, hogy debuggolni is tudjam a "System Workbench for STM32 (alias eclipse)" alól.
Sikerült az openocd-t is meghekkelni. A " stm32f1x.cfg"-ben kell a következő sor lecserélni:
flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME
erre:
flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME
Nem értem, amit csináltál. Én magát az openocd kódját patcheltem meg.
Megnézi az IC típusát és 128k-ra állítja a memóriát.
index d4467076..3d33599a 100644
@@ - 962, 6 + 962, 8 @@ static int stm32x_probe (struct flash_bank *bank )
/* get flash size from target. */
retval = stm32x_get_flash_size (bank, &flash_size_in_kb );
+ if( device_id == 0x20036410 )
+ flash_size_in_kb = max_flash_size_in_kb;
/* failed reading flash size or flash size invalid (early silicon),
* default to max target family */
Az ST-Link V2.1-hez egy javított hex fájlt küldenék.
A régivel az volt a baj, hogy az ST-Link Utility-vel nem ment, a többi programmal igen.
A most csatolt hex fájlt már rendesen kezeli az ST-Link utility.
A firmware frissítés továbbra sem fog menni, de nem érdekel egyelőre. Akinek nem tetszik vegyen STM32F103RBT6-os chipet, ne blue pillen futtassa.
Ez az áramkör 2.1-es bootloadert használ, amihez a fentebb linkelt kapcsolási rajzon szükséges az USB re-enumerationt megcsinálni. Megy anélkül is, csak kevésbé. Én az USB DP-t (PA12) blue pill-lel összekötöttem a PA15-tel egy 1.5 kohm-os ellenálláson keresztül. Működik, de normális panelre ilyet lehetőleg ne.
A lényeg: amikor PA15 alacsony, az USB D+-t alacsonyra húzza, mikor visszakerül magasba, akkor elindul az enumeration (ilyenkor nem piszkálja a D+-t). A hozzászólás módosítva: Nov 20, 2017
Ja, hogy te az openocd forráskódjába nyúltál bele és újrafordítottad? Elég csak az openocd konfigurációs fájlokba belenyúlni, az egyszerűbb: pl. így .
Köszönöm!
CP2102-vel közvetlenül a uC lábairól megy!
Olyat vettem észre, hogy kiküldöm az adatokat PC-ről, és mintha a board nem venné, nem történik semmi (20-ből kb. kettőt figyelmen kívül hagy; 1 db csomagméret 3 byte)
IRQ-ban van a soros. (USB-> CP2102->uC)
Ha a végtelen hurokba (ahol meghívom a soros adatainak feldolgozását) beteszek egy delay-t (~100 ms) akkor sokkal kevesebbszer "veszti" el a bejövő adatokat, mint ha nem lenne delay.
Nem értem.
Találkoztatok már ilyennel?
Több problémát is látok a kódoddal (feltéve, ha még mindig nagyjából az, amit múltkor feltettél).
1, Az olyan változókat, amiket megszakításokban kezelsz volatile-nak kell deklarálni.
2, Minek deklarálsz változókat globálisnak, ha lokálisan használod csak? (pl. rxchar)
3, Folyamatosan nullázod a hol változót a Sorostask elején, miközben ez adja meg a csomag aktuális byte-jának pozicióját a pufferben (ennek így semmi értelme, hmm, talán a Soros-terv része? ). Tedd az első sorba a readRX változó ellenőrzését és ugorj ki a függvényből ha igaz.
4, Felejtsd el a régi reflexeidet és használd a DMA-t az adatküldésre és fogadásra, sima pufferrel az adatküldésre és körkörös puffer-el a fogadásra. Jól megválasztott puffer esetén nem lesz többet csomagvesztés.
igen, még az a kód.
Köszönöm. Az első 3 pontot azonnal átnézem.
A 4-ről semmi infóm. DMA nem fix számú adat mozgatására van? Itt meg lesz 4 byte hosszú
parancs is. ( nem csak 3) Van erre vmi kód példád?
A körkörös puffer esetén addig tölti, amíg be nem telik, majd kezdi az elejétől. Feldolgozásához használhatod a puffer tele, illetve félig tele megszakításokat, ha ennél gyakrabban akarod kezelni, akkor pedig a DMA számlálójából kiolvashatod, az aktuális pozíciót és ebből, illetve a legutóbbi feldolgozás pozíciójából megkapható az újonnan érkezett szakasz.
Mintát nem tudok adni, mert te még a régi már nem támogatott SPL-t használod az én jelenlegi kódjaim pedig már a LowLayer-en alapszanak RTOS beágyazással.
Van viszont régről némi körkörös ADC kódom, illetve nem blokkoló (bizonyos határok között) debug üzengetőm:
Definíciók:
#define CHARGE_GPIO GPIOC
#define CHARGE_GPIO_CLK RCC_APB2Periph_GPIOC
#define CHARGE_Enable_Pin GPIO_Pin_14
#define CHARGE_ADC_GPIO GPIOB
#define CHARGE_ADC_GPIO_CLK RCC_APB2Periph_GPIOB
#define CHARGE_ADC_Voltage_Pin GPIO_Pin_0
#define CHARGE_ADC_Current_Pin GPIO_Pin_1
#define CHARGE_ADC_MASTER ADC1 // Dual ADC mode
#define CHARGE_ADC_MASTER_CLK RCC_APB2Periph_ADC1
#define CHARGE_ADC_SLAVE ADC2 // Dual ADC mode
#define CHARGE_ADC_SLAVE_CLK RCC_APB2Periph_ADC2
#define CHARGE_ADC_SampleTime ADC_SampleTime_41Cycles5
#define CHARGE_ADC_DMA DMA1
#define CHARGE_ADC_DMA_CLK RCC_AHBPeriph_DMA1
#define CHARGE_ADC_DMA_Channel DMA1_Channel1
#define CHARGE_ADC_DMA_IRQn DMA1_Channel1_IRQn
#define CHARGE_ADC_DMA_IRQHandler DMA1_Channel1_IRQHandler
#define CHARGE_ADC_DMA_FLAG DMA1_FLAG_TC1
#define CHARGE_ADC_DR_Base 0x4001244C // &ADC1->DR
#define CHARGE_ADC_Channel_Vrefint ADC_Channel_17
#define CHARGE_ADC_Channel_Tempref ADC_Channel_16
#define CHARGE_ADC_Channel_Voltage ADC_Channel_8
#define CHARGE_ADC_Channel_Current ADC_Channel_9
#define CHARGE_PWM_Frequency 12000
#define CHARGE_PWM TIM1
#define CHARGE_PWM_CLK RCC_APB2Periph_TIM1
#define CHARGE_PWM_GPIO GPIOA
#define CHARGE_PWM_GPIO_CLK (RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO)
#define CHARGE_PWM_VoltageCtrl_Pin GPIO_Pin_11
#define CHARGE_PWM_DutyCycle TIM1->CCR4
Konfiguráció némi hulladékkal:
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
uint16_t prescalerValue, period;
// Enable PWM timer clock
RCC_APB2PeriphClockCmd(CHARGE_PWM_CLK, ENABLE);
// Enable PWM GPIO clock
RCC_APB2PeriphClockCmd(CHARGE_PWM_GPIO_CLK, ENABLE);
// PWM voltage control
GPIO_InitStructure.GPIO_Pin = CHARGE_PWM_VoltageCtrl_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CHARGE_PWM_GPIO, &GPIO_InitStructure);
// Compute the prescaler value
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
// Compute the period
period = (uint16_t)(24000000 / CHARGE_PWM_Frequency) - 1;
Charge_SetVoltageCtrlPWMPeriod(period);
// Time base configuration
TIM_TimeBaseStructure.TIM_Period = period;
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(CHARGE_PWM, &TIM_TimeBaseStructure);
// PWM Mode configuration
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = period;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(CHARGE_PWM, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(CHARGE_PWM, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(CHARGE_PWM, ENABLE);
// Automatic Output enable, Break, dead time and lock configuration
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 0x05;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(CHARGE_PWM, &TIM_BDTRInitStructure);
// Enable counter
TIM_Cmd(CHARGE_PWM, ENABLE);
CHARGE_PWM_DutyCycle = period;
TIM_CtrlPWMOutputs(CHARGE_PWM, ENABLE);
/*
Analog input and ADC configuration
*/
// Analog inputs
GPIO_InitStructure.GPIO_Pin = CHARGE_ADC_Voltage_Pin | CHARGE_ADC_Current_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(CHARGE_ADC_GPIO, &GPIO_InitStructure);
// Enable ADC DMA clock
RCC_AHBPeriphClockCmd(CHARGE_ADC_DMA_CLK, ENABLE);
// Enable master and slave ADCs and GPIO clock
RCC_APB2PeriphClockCmd(CHARGE_ADC_MASTER_CLK | CHARGE_ADC_SLAVE_CLK |
CHARGE_ADC_GPIO_CLK, ENABLE);
// ADC DMA configuration
DMA_DeInit(CHARGE_ADC_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&CHARGE_ADC_MASTER->DR;//CHARGE_ADC_DR_Base
DMA_InitStructure.DMA_MemoryBaseAddr = bufferAddr;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ADC_BUFFSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(CHARGE_ADC_DMA_Channel, &DMA_InitStructure);
// ADC DMA interrupt configuration
//DMA_ITConfig(CHARGE_ADC_DMA_Channel, DMA_IT_TC, ENABLE);
//CHARGE_ADC_DMA_NVIC_Configuration();
// Enable ADC DMA Channel
DMA_Cmd(CHARGE_ADC_DMA_Channel, ENABLE);
// Master ADC configuration
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(CHARGE_ADC_MASTER, &ADC_InitStructure);
// Regular channels configuration
ADC_RegularChannelConfig(CHARGE_ADC_MASTER, CHARGE_ADC_Channel_Vrefint, 1, CHARGE_ADC_SampleTime);
ADC_RegularChannelConfig(CHARGE_ADC_MASTER, CHARGE_ADC_Channel_Tempref, 2, CHARGE_ADC_SampleTime);
// Enable master ADC DMA
ADC_DMACmd(CHARGE_ADC_MASTER, ENABLE);
// Slave ADC configuration
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(CHARGE_ADC_SLAVE, &ADC_InitStructure);
// Regular channels configuration
ADC_RegularChannelConfig(CHARGE_ADC_SLAVE, CHARGE_ADC_Channel_Voltage, 1, CHARGE_ADC_SampleTime);
ADC_RegularChannelConfig(CHARGE_ADC_SLAVE, CHARGE_ADC_Channel_Current, 2, CHARGE_ADC_SampleTime);
// Enable slave ADC external trigger conversion
ADC_ExternalTrigConvCmd(CHARGE_ADC_SLAVE, ENABLE);
// Enable master ADC
ADC_Cmd(CHARGE_ADC_MASTER, ENABLE);
// Enable Vrefint and temperature
ADC_TempSensorVrefintCmd(ENABLE);
// Reset master ADC calibration
ADC_ResetCalibration(CHARGE_ADC_MASTER);
// Wait until reset done
while(ADC_GetResetCalibrationStatus(CHARGE_ADC_MASTER));
// Start master ADC calibration
ADC_StartCalibration(CHARGE_ADC_MASTER);
// Check the end of master ADC calibration
while(ADC_GetCalibrationStatus(CHARGE_ADC_MASTER));
// Enable slave ADC
ADC_Cmd(CHARGE_ADC_SLAVE, ENABLE);
// Reset slave ADC calibration
ADC_ResetCalibration(CHARGE_ADC_SLAVE);
// Wait until reset done
while(ADC_GetResetCalibrationStatus(CHARGE_ADC_SLAVE));
// Start slave ADC calibration
ADC_StartCalibration(CHARGE_ADC_SLAVE);
// Check the end of slave ADC calibration
while(ADC_GetCalibrationStatus(CHARGE_ADC_SLAVE));
// Start master ADC Software Conversion
ADC_SoftwareStartConvCmd(CHARGE_ADC_MASTER, ENABLE);
/*
DC/DC Converter enable and voltage control
*/
RCC_APB2PeriphClockCmd(CHARGE_GPIO_CLK, ENABLE);
// DC/DC converter enable
GPIO_InitStructure.GPIO_Pin = CHARGE_Enable_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CHARGE_GPIO, &GPIO_InitStructure);
Ez itt a feldolgozó rész egy darabkája, hagyd figyelmen kívül a nem használt változókat (lusta vagyok). A kód feldolgozza a DMA által az ADC-től érkezett adatokat (szummázza csatornánként majd osztja a mintavételek számával ezzel egy szimpla szűrést végezve), majd eltolja a feldolgozottságot jelző pointert.
uint16_t V, I, i;
static uint16_t sp = VOUT_SP;
static uint16_t adcPos = 0;
uint16_t dmaCount = ((ADC_BUFFSIZE - (uint16_t)(CHARGE_ADC_DMA_Channel->CNDTR)) / 2);
uint32_t cVal1 = 0, cVal2 = 0, cVal3 = 0, cVal4 = 0;
__IO uint32_t *adcBuff;
uint16_t cnt = 0;
static uint32_t srcnt = 0;
static uint32_t currentSum = 0, voltageSum = 0, powerSum = 0;
static uint16_t displayCnt = 0;
Watchdog_LoopMonitoringReset();
adcBuff = _adcRAW + (adcPos * 2);
if (dmaCount < adcPos) {
for (i = adcPos; i < ADC_BUFFSIZE / 2; i++)
{
cVal1+= *adcBuff >> 16;
cVal2+= *adcBuff++ & 0xFFFF;
cVal3+= *adcBuff >> 16;
cVal4+= *adcBuff++ & 0xFFFF;
cnt++;
}
adcPos = 0;
adcBuff = _adcRAW;
}
for (i = adcPos; i < dmaCount; i++)
{
cVal1+= *adcBuff >> 16;
cVal2+= *adcBuff++ & 0xFFFF;
cVal3+= *adcBuff >> 16;
cVal4+= *adcBuff++ & 0xFFFF;
cnt++;
}
_filteredVoltageRAW = (uint16_t)(cVal1 / cnt);
_filteredVrefRAW = (uint16_t)(cVal2 / cnt);
_filteredCurrentRAW = (uint16_t)(cVal3 / cnt);
if (_filteredCurrentRAW > ZEROCURRENTOFFSET) _filteredCurrentRAW-= ZEROCURRENTOFFSET;
else _filteredCurrentRAW = 0;
_filteredTempRAW = (uint16_t)(cVal4 / cnt);
adcPos = dmaCount;
USART példa:
#define USART_DEBUG USART1
#define USART_DEBUG_GPIO GPIOA
#define USART_DEBUG_CLK RCC_APB2Periph_USART1
#define USART_DEBUG_GPIO_CLK RCC_APB2Periph_GPIOA
#define USART_DEBUG_RxPin GPIO_Pin_10
#define USART_DEBUG_TxPin GPIO_Pin_9
#define USART_DEBUG_IRQn USART1_IRQn
#define USART_DEBUG_IRQHandler USART1_IRQHandler
#define USART_DEBUG_DMA_CLK RCC_AHBPeriph_DMA1
#define USART_DEBUG_DMA_Channel DMA1_Channel4 // Depends on USART! See DMA request mapping
#define USART_DEBUG_DMA_IRQn DMA1_Channel4_IRQn
#define USART_DEBUG_DMA_IRQHandler DMA1_Channel4_IRQHandler
#define USART_DEBUG_DMA_FLAG DMA1_FLAG_TC4
void USART_DEBUG_DMA_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART_DEBUG_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// USART - DEBUG interrupt
void USART_DEBUG_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART_DEBUG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_DEBUG_Config(uint32_t bufferAddr)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(USART_DEBUG_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(USART_DEBUG_CLK, ENABLE);
//USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
// PA.09(Tx)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = USART_DEBUG_TxPin;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USART_DEBUG_GPIO, &GPIO_InitStruct);
// PA.10(Rx)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = USART_DEBUG_RxPin;
GPIO_Init(USART_DEBUG_GPIO, &GPIO_InitStruct);
// Enable the DMA Clock
RCC_AHBPeriphClockCmd(USART_DEBUG_DMA_CLK, ENABLE);
DMA_DeInit(USART_DEBUG_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART_DEBUG->DR;//USART_DEBUG_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = bufferAddr;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(USART_DEBUG_DMA_Channel, &DMA_InitStructure);
DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, ENABLE);
USART_DEBUG_DMA_NVIC_Configuration();
USART_InitStruct.USART_BaudRate = USART_DEBUG_BAUDRATE;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART_DEBUG, &USART_InitStruct);
USART_DMACmd(USART_DEBUG, USART_DMAReq_Tx, ENABLE);
USART_ITConfig(USART_DEBUG,USART_IT_RXNE,ENABLE);
USART_DEBUG_NVIC_Configuration();
USART_Cmd(USART_DEBUG, ENABLE);
}
uint8_t _silent;
static __IO uint16_t _usartBufferPos;
static __IO uint16_t _usartSending;
static __IO uint8_t _usartBuffer;
static char __IO _debugBuffer1[USART_DEBUG_BUFFERSIZE / 2];
static char __IO _debugBuffer2[USART_DEBUG_BUFFERSIZE / 2];
#ifdef USARTDEBUG
static void _usartSend(const char *str)
{
char *target;
DisableIRQ();
size_t l = strlen(str);
if (!l) {
EnableIRQ();
return;
}
if ((l + _usartBufferPos + 1) > (USART_DEBUG_BUFFERSIZE/2)) {
EnableIRQ();
return; // Drop messages
}
if (_usartBuffer) target = (char*)_debugBuffer2;
else target = (char*)_debugBuffer1;
target += _usartBufferPos;
strcpy(target, str);
_usartBufferPos += l;
if (_usartSending) {
EnableIRQ();
return;
}
DMA_ClearFlag(USART_DEBUG_DMA_FLAG);
DMA_Cmd(USART_DEBUG_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USART_DEBUG_DMA_Channel, l);
if (_usartBuffer) {
USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer2;
} else {
USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer1;
}
_usartSending = l;
_usartBufferPos = 0;
_usartBuffer = !_usartBuffer;
DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, ENABLE);
DMA_Cmd(USART_DEBUG_DMA_Channel, ENABLE);
EnableIRQ();
}
void DBG_BlockPrint(const char *str)
{
DisableIRQ();
size_t l = strlen(str);
int i;
for (i = 0; i < l; i++) {
USART_SendData(USART1,*(char *)(str + i));
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
EnableIRQ();
}
ISR(USART_DEBUG_DMA_IRQHandler)
{
DisableIRQ();
DMA_ClearFlag(USART_DEBUG_DMA_FLAG);
DMA_Cmd(USART_DEBUG_DMA_Channel, DISABLE);
if (!_usartBufferPos) {
_usartSending = 0;
DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, DISABLE);
EnableIRQ();
__DSB();
return;
}
DMA_SetCurrDataCounter(USART_DEBUG_DMA_Channel, _usartBufferPos);
if (_usartBuffer) {
USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer2;
} else {
USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer1;
}
_usartSending = _usartBufferPos;
_usartBufferPos = 0;
_usartBuffer = !_usartBuffer;
DMA_Cmd(USART_DEBUG_DMA_Channel, ENABLE);
EnableIRQ();
__DSB();
}
void DBG_Init(void)
{
USART_DEBUG_Config((uint32_t)_debugBuffer1);
_usartSend(TXT("*** LOG STARTED ***\r\n"));
}
void DBG_PrintC(const char *str, uint16_t color)
{
char escstr[8] = "\x1B[36;1m";
switch (color) {
case LCD_BLACK:
escstr[3] = '0';
break;
case LCD_RED:
escstr[3] = '1';
break;
case LCD_GREEN:
escstr[3] = '2';
break;
case LCD_YELLOW:
escstr[3] = '3';
break;
case LCD_BLUE:
escstr[3] = '4';
break;
case LCD_CYAN:
escstr[3] = '6';
break;
case LCD_WHITE:
escstr[3] = '7';
break;
default:
escstr[3] = '5';
break;
}
_usartSend(escstr);
_usartSend(str);
_usartSend(TXT("\x1B[0m"));
}
void DBG_Print(const char *str)
{
_usartSend(str);
}
void DBG_PrintLn(const char *str)
{
_usartSend(str);
_usartSend(TXT("\r\n"));
}
void DBG_PrintLnC(const char *str, uint16_t color)
{
DBG_PrintC(str, color);
_usartSend(TXT("\r\n"));
}
void DBG_TimeRef(void)
{
char str[20];
ltoa(str, SysTick_GetReference(), 10);
DBG_Print(TXT("["));
DBG_PrintC(str, LCD_YELLOW);
DBG_Print(TXT("]:"));
#ifdef SCHEDULER_NAMEDTASKS
DBG_PrintC(Scheduler_GetActiveTaskName(), LCD_WHITE);
DBG_Print(TXT(":"));
#endif
}
void DBG_PrintChar(char c)
{
char s[2];
s[0] = c;
s[1] = 0;
_usartSend(s);
}
void DBG_Ok(void)
{
_usartSend(TXT("\x1B[32;1mOk!\x1B[0m\r\n"));
}
void DBG_Fail(void)
{
_usartSend(TXT("\x1B[31;1mFailed!\x1B[0m\r\n"));
}
#endif
A hozzászólás módosítva: Nov 22, 2017
Köszönöm.
Lesz mit értelmeznem.
Elképesztő hibát találtál a kódban. Mennyire átsiklottam fölötte.
És a 3-as (hol változó nullázása folyamatosan) hiba volt. Köszönöm.
Amikor a FLASH-t írom programban (pl. ezzel: FLASH_ProgramHalfWord, coocox) érdemes az IRQ-kat leállítani (és systick-et)?
stm32f103rbt6
Köszönöm. A hozzászólás módosítva: Nov 27, 2017
Ez attól függ. Nálam nem volt sosem probléma, amikor a memória utolsó 1k-ját felülvágtam adatokkal. Abban tároltam a perzisztens adatokat.
Ha éppen az interrupt vektor tábládat írod RAM-ból, miközben a kódodat is frissíted, akkor nem árt tiltani az interruptokat. Miközben saját magadat írod felül, nem jó az interrupt. A hozzászólás módosítva: Nov 27, 2017
Létezik STM32-es 480 mbps high speed USB-vel?
Amiket látok, oda külső ULPI PHY kell, alapjáraton csak a full speed megy.
Ha jól látom az új M7-esek között van olyan, ami tartalmazza PHY-t is.
(#) |
gtk hozzászólása |
Dec 5, 2017 |
|
/ |
|
|
Sziasztok !
Ha jol tudom a H7-et az ev masodik felere igertek. Be lehet szerezni ? Valaki foglalkozott vele ? ( mar nagyon kellene ) A hozzászólás módosítva: Dec 5, 2017
Hello! Nekem itt van az asztalomon vagy egy hónapja egy stm32h743 Nucleo-144, úgy hogy be lehet szerezni. Lelkierőm a megismeréséhez (3000 oldal a prociról + 1800 oldal a HAL-ről) még nem volt... Az atollic a procit ismeri, ezt a nucleot nem, de az alap végtelen ciklus program azért felment rá. Nem én vettem, egy ismerősömé, talán a farnellnél vette.
|
|