Difference between revisions of "Programmering STM32"
Line 94: | Line 94: | ||
===Ytterligare felkällor=== | ===Ytterligare felkällor=== | ||
Om det inte fungerar och du är helt säker på att du gjort rätt så kan det vara fel på processorn. Kolla därför igenom Erratan för din processor. Man hittar dom på STs hemsida på sidan om den aktuella processorn under Design Resources och scrolla ner till errata. Här är några errata för vanligt använda processorer: <br> | Om det inte fungerar och du är helt säker på att du gjort rätt så kan det vara fel på processorn. Kolla därför igenom Erratan för din processor. Man hittar dom på STs hemsida på sidan om den aktuella processorn under Design Resources och scrolla ner till errata. Här är några errata för vanligt använda processorer: <br> | ||
[http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00278726.pdf STM32F100 Errata] | [http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00278726.pdf STM32F100 Errata]<br> | ||
[http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00278726.pdf STM32L Errata] | |||
==Peripheralexempel== | ==Peripheralexempel== |
Revision as of 13:24, 4 June 2014
Denna sida är under konstruktion, men kommer att innehålla information om vad man bör tänka på när man programmerar STM32 (och delvis generellt ARM). Notera att denna sida endast handlar om att skriva kod, inte om hur man får programmet att bygga osv. Detta tas upp i artiklarna Förberedelse programmering STM32 och Byggprocess ARM
Tillvägagångssätt för programmering
Innan du kan sätta och och börja koda för STM32 behöver du sätta upp mjukvara för att kunna kompilera koden. Ifall du inte har gjort det, läs Förberedelser för programmering av STM32.
Dokumentation för STM32
Här är en länk till STs standardlib (det är svårare att hitta än man kan tro...). dessa dokument vill du ladda hem, och läsa i för att förstå hur just den funktion du vill ha fungerar. reference sheet datasheet disovery board datasheet
Tips om Eclipse
Filstruktur i projekt
i src lägger du koden du skriver, som slutar på .c
i lib finns bibliotek, främst stdlib från ST, men du kan även ta hem andra bibliotek i framtiden
i inc lägger du alla .h filer
makefile är den fil som läses av programmet make varje gång du trycker på kompilera i Eclipse. Det är ungefär som en göralista som styr vad som ska utföras av make, för att alla filer ska kompileras, allt ska länkas etc. Den skriver du antingen sjläv (baserat på en existerande såklart) eller så låter du Eclipse generera den åt dig.
Här behöver du lägga till nya filer du skriver under SRC, annars kommer inte make ta med dem i kompileringen
kompilera i eclipse
skicka över med st-link program
Testprogram för introARM
Debugging
Blinka med LEDs och UART.
Skriva C-kod
Grunderna
Är du ny? Läs lite i C-bok eller läs exempelkod! Här ska massa länkar till bra material Att lära sig C programmering finnas
skriva kod för stm32
processorer med en ARM kärna skiljer sig från microprocessorer från Atmel och PIC i grund och botten i att .... kärna från arm, periferienheter från ST
Structer
Man skriver inte i register, utan man använder ett abstraheringslager, stdlib, med funktioner och structer etc så bör man inte ändra direkt i register
Klockor
finns en uppsjö av klockor i STM32, se "karta"(?)
Exempelkod
för introARM / discovery board gpio uart timer interrupt
Programmering
Som alla vet programmerar man i C.
Felsökning
Om du setat länge med ett problem finns det några standardmisstag om man brukar göra. Kolla igenom följande checklista så kanske du hittar ditt problem:
Har du givit klocka till peripheral?
Alla peripherals måste ha klocka. Det första man bör gör när man initar någonting peripheral är att anropa funktionen RCC_APBxPeriphClockCmd(RCC_APBxPeriph_PPPPP,ENABLE) där x är den buss din peripheral sitter på och RCC_APBxPeriph_PPPPP är makrot för den peripheral du ska slå igång. Det finns även för RCC_AHB-bussen också. GPIO sitter på APB2 exempelvis. Notera att alla moduler som är inblandade ska ha klocka. Exempelvis om du ska göra PWM så måste du ge klocka både till GPIO, GPIO_AF och timern.
Är du säker på att det är rätt pinne? Har du skrivit rätt Port-namn i koden?
Har du kopplat alternate function till pinnen?
AF till pinnen kopplas med funktionen GPIO_PinAFConfig(GPIO_PORT,GPIO_PinSource,GPIO_AF). Info finns i filen GPIO.c.
Har du kört din init-funktion?
Nej, det har du inte. Kolla igen.
Har du enablat din peripheral?
Detta gör man med Periph_CMD(Enable) (t.ex. TIM_Cmd(TIMx,ENABLE), SPI_Cmd(SPIx,ENABLE) eller USART_Cmd(USARTx,ENABLE)).
Min PWM funkar inte!
Notera att för vissa timers (TIM1, TIM8, TIM15-17 på STM32F1xx och endast TIM1,8 på F4) så måste man anropa en extra funktion som sätter igång PWM. Detta görs med funktionen TIM_CtrlPWMOutputs(TIMx,ENABLE). Denna funktion kan också användas för att stänga av PWM på pinnen (vilket kan vara smidigt ibland)
Kontrollera även feldatabladet, t.ex. på TIM1, utgångskomparator kanal 1 på STM32F100 så krockar timern och UART1 vilket gör att timern inte kan användas om uarten används.
Min pinne funkar inte!
Är din pinne PB3, PB4, PA13, PA14 eller PA15? Detta är JTAG/SWD-pinnarna och dom är som standard denna funktion och INTE GPIO. Dessa måste remappas innan dom kan användas som GPIO. Detta görs med funktionen GPIO_PinRemapConfig(GPIO_Remap_SWJ_xxx,ENABLE), där xxx finns som följande options: NoJRST som låser upp PB4, JTAGDisable som låser upp PB3, PB4 och PA15 samt Disable som låser upp alla pinnar (ja, det ser skumt ut när man anropar GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE), men det är korrekt). Notera att på STM32F4xx så finns det ingen remap alls. Där sköts detta enbart via AF-controllern (men man måste fortfarande välja GPIO som AF i STM32F4xx).
Den hänger sig i interrupt!
Det finns många saker som kan bli fel på interrupt. Det vanligaste är:
- Inte korrekt initad interruptvektor. Du måste ha den funktion som svarar mot din interruptvektor (där du hamnar vid interrupt). Dessa står i startup-filen (.s-filen). Dessa har typiskt formatet void PERIPH_Handler(){ do_interrupt_stuff } där PERIPH är den peripheral du har.
- Har du kvitterat (clearat) ditt interrupt? Detta bör göras så tidigt som möjligt i interruptet (men kan göras senare vid avancerade applikationer). Det finns inbyggda funktioner för detta. För external interrupt (pinne som ger interrupt) heter den EXTI_ClearItPendingBit(EXTI_Linex), där x är vilket nummer.
- För vissa interrupt måste du också läsa av interruptkällan (typiskt interrupts som flera källor kan trigga, exempelvis EXTI_Line som kan triggas av flera pinnar)
De_init-funktionen
Många peripherals (t.ex. DMA och I2C) har en de_init-funktion. Den bör man köra innan man initierar peripheralen, annars finns det risk att den inte fungerar.
Logikanalysator
Denna är helt ovärderlig vid felsökning av kommunikationsprotokoll. Om du setat mer än 5 minuter med ditt problem med UART/SPI så hämta logikanalysatorn och koppla upp den. Det tar inte många minuter och löser oftast ditt problem. Den är mycket enkelt att få igång. Mer info finns här. Annars är oscilloskopet din vän. Samma där, det tar inte lång tid att ta fram och sätta upp det.
Min timer dummar sig och sätter sig inte till korrekt idle-värde
P.g.a att ST har gjort fel i sitt bibliotek fungerar inte TIM15 kanal2. De extrafunktioner som har med break att göra (t.ex. idle state) är inte korrekt gjorda. I funktionen TIM_OC2Init i stm32f10x_tim.c ska du lägga till TIMx==TIM15 i if-satsen för att tillåta att de avancerade funktionerna kan användas. Det ska se ut som "if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM15))"
Mitt DMA Interrupt fungerar inte
Tänk på att aktivera DMA-kanalen innan interruptet aktiveras. T.ex. <syntaxhighlight lang="c"> DMA_Cmd(DMA1_Channel4, ENABLE); DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); </syntaxhighlight>
Min I2C fungerar inte
Varför använder du I2C? Det är ju jättedåligt. Vidare är STs I2C väldigt trasig. Den fungerar bäst med DMA. Kolla mer information i Erratan.
Ytterligare felkällor
Om det inte fungerar och du är helt säker på att du gjort rätt så kan det vara fel på processorn. Kolla därför igenom Erratan för din processor. Man hittar dom på STs hemsida på sidan om den aktuella processorn under Design Resources och scrolla ner till errata. Här är några errata för vanligt använda processorer:
STM32F100 Errata
STM32L Errata
Peripheralexempel
Med i libbet kommer det massa exempel som är ganska bra och tar upp det mesta. Här följer några skräddassydda och bättre förklarade exempel.
GPIO
Med interrupt
Timer
PWM
UART
Modeller
Det finns massa olika modeller.
Länkar
Vart hittar man datablad? Vart hittar man libbet? Vart köper man dom?