Mikrokontroler STM8, biblitoteka SPL i kompilator SDCC - Na partyzanta

Pozostałe układy mikrokontrolerów, układy peryferyjne i inne, nie mieszczące się w powyższych kategoriach.
Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Mikrokontroler STM8, biblitoteka SPL i kompilator SDCC - Na partyzanta

Postautor: ZbeeGin » piątek 03 maja 2019, 22:13

Do napisania tego "małego" poradnika skłoniły mnie moje uwieńczone nieco połowicznym sukcesem próby pogodzenia trzech elementów:

1. Mikrokontrolerów STM8 - Jest to rodzina 8-bitowych µC produkowanych przez STMicroelectronics. Jak wielokrotnie ST chwaliło się na swoich prezentacjach, rodzina ta powstała jako jakoby z różnych innych rodzin mikrokontrolerów 8-bitowych, z których została wyssana sama najlepsza esencja i skompilowana na pokładzie STM8. Czy jest to prawdą musicie już określić sami...
2. Bibliotek Standard Peripherial Library for STM8 (w skrócie SPL) - Jest to jakby odpowiednik bibliotek SPL starszych braci STM32. Napisany mniej więcej w tym samym stylu. Ich wadą jest to, że są one dostosowane tylko dla wspieranych przez ST kompilatorów: IAR, Raisonance oraz COSMIC. Ten ostatni można otrzymać za darmo z licencją na 12 miesięcy - szczegóły w witrynie firmy COSMIC Software.
3. Darmowego kompilatora SDCC (Small Device C Compiler) - Jest to otwartoźródłowy projekt kompilatora dla sporej grupy mikrokontrolerów i mikroprocesorów 8-bitowych, m.in. MCS-51, HC08, Z80, częściowo również PIC. No i ostatnio również dla naszego bohatera STM8.

Opis będzie dotyczył systemu MS Windows, gdzie nie mamy takich narzędzi jak w systemach Linux. Można oczywiście dodać je stosując pewne ogólnie znane protezy: Cygwin, MinGW, UnixUtils. My jednak nie chcąc robić sobie większego bajzlu w systemie skorzystamy z tego co jest dostępne tuż po wyjęciu z pudełka.

Najpierw powinniśmy pobrać kompilator SDCC. W tym celu możemy udać się na stronę http://sdcc.sourceforge.net/ i kliknąć z lewej strony Download. Linki poprowadzą nas i zasobów SourceForge: https://sourceforge.net/projects/sdcc/files/sdcc-win32/ Pobieramy instalator w najnowszej dostępnej - stabilnej - kompilacji. W tej chwili było to SDCC 3.9.0. Instalujemy w zwykły sposób przechodząc kolejne kroki kreatora. Jeśli ktoś nie chce mieć wsparcia dla innych rodzin µC oprócz STM8 to na liście może odznaczyć niepotrzebne. W ostatnim kroku instalator będzie chciał dodać ścieżkę do zmiennej PATH. Pozwólmy mu na to.

INFO: W przypadku problemów z kompilacją w systemach Windows 10 x64 po zainstalowaniu sdcc-win64, polecam jego pełne odinstalowanie oraz instalację sdcc-win32 nawet w systemie 64-bitowym. Problem może objawiać się błędem zwracanym przez program sdar, który ustąpił po instalacji wersji 32-bitowej.

Po instalacji można uruchomić konsolę - na przykład naciskając kombinację Start+R, wpisując cmd.exe i wciskając Enter - a tam wydać polecenie sdcc --version. Powinna się pokazać następująca informacja:

Kod: Zaznacz cały

Microsoft Windows [Version 10.0.17763.437]
(c) 2018 Microsoft Corporation. Wszelkie prawa zastrzeżone.

C:\Users\Zbyszek>sdcc --version
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ez80_z80/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk14/pdk15 3.9.0 #11195 (MINGW64)
published under GNU General Public License (GPL)

Dzięki temu wiemy, że da się kompilator bezproblemowo wywołać.

Teraz musimy pobrać pakiet bibliotek SPL ze strony ST. Znajdują się one pod adresem https://www.st.com/en/embedded-software ... m8069.html Trzeba je pobrać i rozpakować. Ale aby były strawne dla kompilatora SDCC trzeba dokonać w nich pewnych "poprawek".
Odszukujemy folder Libraries a tam STM8S_StdPeriph_Driver, kopiujemy go do STM8S_StdPeriph_Driver_SDCC w tym samym miejscu. Dzięki temu będziemy mieć wersję oryginalną i poprawioną obok siebie w razie potrzeby. Teraz warto przejść jeszcze do folderu Project, a tam do STM8S_StdPeriph_Template. Stamtąd skopiujemy jeszcze plik stm8s_conf.h, i też umieśćmy go w STM8S_StdPeriph_Driver_SDCC.

Główne poprawki wyglądają następująco:
1. Plik stm8s_conf.h linia 93:

Code: Select all

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT (1) */

Umieszczamy w komentarzu definicję USE_FULL_ASSERT by zablokować wszystkie asercje.

2. Plik inc\stm8s.h linia 78:

Code: Select all

/******************************************************************************/
/* Library configuration section */
/******************************************************************************/
/* Check the used compiler */
#if defined(__CSMC__)
#define _COSMIC_
#elif defined(__RCST7__)
#define _RAISONANCE_
#elif defined(__ICCSTM8__)
#define _IAR_
#elif defined(__SDCC)
#define _SDCC_
#else
#error "Unsupported Compiler!" /* Compiler defines not found */
#endif

Dodajemy wykrywanie kompilatora SDCC, co pozwoli nam na automatyczne zdefiniowanie symbolu _SDCC_, który przyda się w kilku innych miejscach.

Dalej, linia 143:

Code: Select all

#elif defined (_SDCC_)
#define FAR /* SDCC gets confused by __far */
#define NEAR /* SDCC gets confused by __near */
#define TINY /* SDCC gets confused by __tiny */
#define EEPROM /* SDCC gets confused by __eeprom */
#define CONST const
#else /*_IAR_*/
#define FAR __far
#define NEAR __near
#define TINY __tiny
#define EEPROM __eeprom
#define CONST const
#endif /* __CSMC__ */

Blokujemy atrybuty FAR/NEAR/TINY/EEPROM, które byłby źle zrozumiane przez SDCC w przypadku STM8.
Sprawę odwoływania się do adresów z powiększonej przestrzeni adresowej trzeba załatwić na etapie parametryzacji kompilacji stosując opcję --model-large. Domyślnie SDCC kompiluje z domyślną opcją --model-medium z adresacją 16-bitową.

Dalej, linia 218:

Code: Select all

#if defined(_SDCC_)
#include <stdint.h>
#else
/*!< Signed integer types */
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;

/*!< Unsigned integer types */
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
#endif

Tu musimy dodać warunek by w przypadku SDCC wykorzystać gotowe typy z pliku nagłówkowego <stdint.h>.

Dalej, linia 2736:

Code: Select all

#elif defined(_COSMIC_)
#define enableInterrupts() {_asm("rim\n");} /* enable interrupts */
#define disableInterrupts() {_asm("sim\n");} /* disable interrupts */
#define rim() {_asm("rim\n");} /* enable interrupts */
#define sim() {_asm("sim\n");} /* disable interrupts */
#define nop() {_asm("nop\n");} /* No Operation */
#define trap() {_asm("trap\n");} /* Trap (soft IT) */
#define wfi() {_asm("wfi\n");} /* Wait For Interrupt */
#define halt() {_asm("halt\n");} /* Halt */
#elif defined(_SDCC_)
#define enableInterrupts() {__asm__("rim\n");} /* enable interrupts */
#define disableInterrupts() {__asm__("sim\n");} /* disable interrupts */
#define rim() {__asm__("rim\n");} /* enable interrupts */
#define sim() {__asm__("sim\n");} /* disable interrupts */
#define nop() {__asm__("nop\n");} /* No Operation */
#define trap() {__asm__("trap\n");} /* Trap (soft IT) */
#define wfi() {__asm__("wfi\n");} /* Wait For Interrupt */
#define halt() {__asm__("halt\n");} /* Halt */
#else /*_IAR_*/

Musimy w przypadku SDCC zmienić format wplatania poleceń maszynowych na rozpoznawany przez niego (wersje 3.2.0 i wyższe).

3. Plik src\stm8s_itc.c linia 62:

Code: Select all

uint8_t ITC_GetCPUCC(void)
{
#ifdef _COSMIC_
_asm("push cc");
_asm("pop a");
return; /* Ignore compiler warning, the returned value is in A register */
#elif defined _RAISONANCE_ /* _RAISONANCE_ */
return _getCC_();
#elif defined _IAR_
asm("push cc");
asm("pop a"); /* Ignore compiler warning, the returned value is in A register */
#else
__asm__("push cc");
__asm__("pop a"); /* Ignore compiler warning, the returned value is in A register */
#endif /* _COSMIC_*/
}

Poprawiamy funkcję ITC_GetCPUCC() by w przypadku kompilacji przez SDCC korzystała z właściwego formatu wplatania poleceń kodu maszynowego.

Przy okazji. Jak głosi komentarz, kompilator da nam ostrzeżenie, że funkcja nie zwraca wartości, ale jest to w tym przypadku normalne. Zatem ostrożnie z używaniem parametru --Werror dla tego pliku.

4. Plik src\stm8s_tim2.c linia 1103:

Code: Select all

void TIM2_ClearFlag(TIM2_FLAG_TypeDef TIM2_FLAG)
{
/* Check the parameters */
assert_param(IS_TIM2_CLEAR_FLAG_OK(TIM2_FLAG));

/* Clear the flags (rc_w0) clear this bit by writing 0. Writing �1� has no effect*/
TIM2->SR1 = (uint8_t)(~((uint8_t)(TIM2_FLAG)));
TIM2->SR2 = (uint8_t)(~((uint8_t)((uint16_t)TIM2_FLAG >> 8)));
}

To akurat moja autorska poprawka nie związana z kompatybilnością. Ktoś pisząc ten fragment nieco się rozpędził i zamiast rzutowania TIM2_FLAG na uint16_t zrobił rzutowanie na uint8_t, co oczywiście nie spodoba się kompilatorowi SDCC z uwagi na późniejsze przesunięcia bitowe.

5. Plik inc\stm8s_clk.h linia 159:

Code: Select all

CLK_FLAG_CCOBSY = (uint16_t)0x0540, /*!< Configurable clock output busy */
CLK_FLAG_CCORDY = (uint16_t)0x0520 /*!< Configurable clock output ready */
}CLK_Flag_TypeDef;

Kolejna moja poprawka wynikła z błędu twórców SPL. Musimy poprawić dwie zdefiniowane wartości by flagi z rejestru CCOR były odczytywane z właściwych bitów.

To już wszystkie poprawki w źródłach.

Teraz możemy przygotować sobie krótki plik wsadowy, który skompiluje nam jakiś przykładowy kod. Wiem, że to nieeleganckie - Miało być na partyzanta, to jest na partyzanta... :) - ale wrzućmy teraz do jakiegoś folderu wszystkie pliki nagłówkowe oraz źródłowe bibliotek SPL oraz te pobrane z domyślnego projektu do jakiegoś folderu. Umieśćmy tam również plik main.c gdzie znajdować się będzie jakiś prosty kod (Pożyczony od kolegi z forum):

Code: Select all

/* Copyright by StaryAnoda_NEW */
#include "stm8s_conf.h"

void clock_setup(void);
void gpio_setup(void);

int main(void)
{
clock_setup();
gpio_setup();
for(;;) {
if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_7) != RESET)
GPIO_WriteHigh(GPIOB, GPIO_PIN_5);
else
GPIO_WriteLow (GPIOB, GPIO_PIN_5);
}
return (0);
}

void clock_setup(void)
{
CLK_DeInit();
CLK_HSECmd(DISABLE);
CLK_LSICmd(DISABLE);
CLK_HSICmd(ENABLE);

while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE) {};

CLK_ClockSwitchCmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
CLK_SYSCLKConfig (CLK_PRESCALER_CPUDIV4);
CLK_ClockSwitchConfig (CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}

void gpio_setup(void)
{
GPIO_DeInit(GPIOC);
GPIO_Init (GPIOC, GPIO_PIN_7, GPIO_MODE_IN_FL_NO_IT);
GPIO_DeInit(GPIOB);
GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
}


Kod jest dla procesora STM8S103F3P6, którego można spotkać na najmniejszych płytkach prototypowych dostępnych w serwisie aukcyjnym. Jeśli będziemy pobudzać linię PC7 stanem wysokim to ma zaświecić nam dioda podłączona do PB5.

INFO: Na niektórych podobnych płytkach dioda jest podłączona do innego pinu więc należy to sprawdzić i ewentualnie zmienić w kodzie.

Mając już wszystko razem możemy napisać prosty plik wsadowy main.bat, który:
- dokona kompilacji wszystkich plików SPL dotyczących istniejących w STM8S103F3P6 peryferii,
- uzyskane pliki wyjściowe złoży w bibliotekę stm8s103.lib, którą potem wykorzystamy przy finalnej kompilacji main.c,
- dokona kompilacji i linkowania pliku main.c,
- spakuje wynikowy plik main.ihx do pliku main.hex nadającego się do zaprogramowania procesora przez ST-Linka.

Code: Select all

@echo off
set CC_FLAGS=-lstm8 -mstm8 --std-c11 --opt-code-size --vc -DSTM8S103

echo Compiling library sources...
sdcc -c %CC_FLAGS% stm8s_adc1.c
sdcc -c %CC_FLAGS% stm8s_awu.c
sdcc -c %CC_FLAGS% stm8s_beep.c
sdcc -c %CC_FLAGS% stm8s_clk.c
sdcc -c %CC_FLAGS% stm8s_exti.c
sdcc -c %CC_FLAGS% stm8s_flash.c
sdcc -c %CC_FLAGS% stm8s_gpio.c
sdcc -c %CC_FLAGS% stm8s_i2c.c
sdcc -c %CC_FLAGS% stm8s_itc.c
sdcc -c %CC_FLAGS% stm8s_iwdg.c
sdcc -c %CC_FLAGS% stm8s_rst.c
sdcc -c %CC_FLAGS% stm8s_spi.c
sdcc -c %CC_FLAGS% stm8s_tim1.c
sdcc -c %CC_FLAGS% stm8s_tim2.c
sdcc -c %CC_FLAGS% stm8s_tim4.c
sdcc -c %CC_FLAGS% stm8s_uart1.c
sdcc -c %CC_FLAGS% stm8s_wwdg.c

echo Create library for STM8S103...
del stm8s103.lib
sdar -rc stm8s103.lib stm8s_adc1.rel stm8s_awu.rel stm8s_beep.rel stm8s_clk.rel stm8s_exti.rel stm8s_flash.rel stm8s_gpio.rel stm8s_i2c.rel stm8s_itc.rel stm8s_iwdg.rel stm8s_rst.rel stm8s_spi.rel stm8s_tim1.rel stm8s_tim2.rel stm8s_tim4.rel stm8s_uart1.rel stm8s_wwdg.rel

echo Deleting compiler artifacts...
del *.asm
del *.lst
del *.rel
del *.rst
del *.sym

echo Compiling main file...
sdcc %CC_FLAGS% --out-fmt-ihx stm8s103.lib main.c

echo Create Intel HEX output...
packihx main.ihx >main.hex
del *.ihx

echo All done!
timeout /T 5


PRO TIP: Wygenerowaną bibliotekę możecie potem wykorzystać w innych projektach dla tego procesora i część dotyczącą jej tworzenia usunąć z pliku wsadowego. Nic też nie stoi na przeszkodzie by utworzyć sobie jeszcze inne biblioteki dla pozostałych rodzin w podobny sposób.

Kto chce może od razu dopisać do pliku jeszcze polecenie programowania:

Code: Select all

echo Flashing...
"C:\Program Files (x86)\STMicroelectronics\st_toolset\stvp\STVP_CmdLine.exe" -BoardName=ST-LINK -Port=USB -ProgMode=SWIM -Device=STM8S103x3 -verbose -verif -FileProg=main.hex


W parametrze -Device= należy podać nazwę zgodną z wybranym procesorem i tą która jest na liście dostępnych układów ST Visual Programmer.

To wszystko w tym, krótkim i jak widać "partyzanckim" poradniku. Wiem, że można to zrobić lepiej, nie robiąc takiego bałaganu. Są opcje kompilatora, których tu nie wykorzystałem.
Ba! Ktoś pewnie zarzuci zaraz "Przecież od tego jest makefile!". Tak. Macie w 100% rację, ale wymaga to doinstalowania pewnych linuxowych narzędzi, a tu miało się bez nich obejść. Jeśli ktoś chce podjąć temat jak to zrobić "po Bożemu" to zapraszam do kontynuacji tego wątku...

Sprawa przerwań

Procedury obsługi przerwań są dość specyficznie traktowane przez kompilatory i SDCC nie jest tu wyjątkiem. Możemy napisać swoje procedury obsługi odpowiednio tworząc ich nagłówki lub skorzystać z gotowych plików stm8_it.h oraz stm8_it.c dostępnych w przykładach dostarczonych przez ST w bibliotece SPL.


W przypadku gdybyśmy chcieli napisać swoje własne funkcje mające się później znaleźć pod odpowiednim adresem tablicy wektorów przerwania należy je konstruować w następujący sposób:

Code: Select all

/*- Interrupt Handlers ----------------------------------*/
/**
* @brief TIM2 Overflow Interrupt handler
* @param None
* @retval None
*/
void TIM2_Overflow_Handler() __interrupt(13)
{
uiPeriodCounter++;

TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
}

Najważniejsze by:
- Funkcje były bezparametrowe i zwracały void.
- W nagłówku funkcji występował atrybut __interrupt() z podanym w nawiasie numerem w tablicy wektorów przerwań. Numery przerwań i powiązane z nimi źródła można poznać w dokumentacji danego mikrokontrolera pod hasłem "Interrupt vector mapping".

Przy korzystania ze specjalnego przerwania programowego TRAP występującego w STM8 jako drugi wektor w tablicy nie posiadający nadanego numeru, należy zamiast atrybutu __interrupt() podać atrybut __trap bez parametru liczbowego.


Jeśli wybierzemy sposób z wykorzystaniem plików przygotowanych przez ST to musimy jeszcze raz wrócić do pliku inc\stm8s.h i dopisać dwa makra:

6. Plik inc\stm8s.h linia 2776:

Code: Select all

#endif /* _RAISONANCE_ */

#ifdef _SDCC_
#define INTERRUPT_HANDLER(a,b) void a(void) __interrupt(b)
#define INTERRUPT_HANDLER_TRAP(a) void a(void) __trap
#endif /* _SDCC_ */

#ifdef _IAR_
#define STRINGVECTOR(x) #x


Dodatkowo należy jeszcze mocno zmodyfikować plik nagłówkowy:

7. Plik stm8s_it.h linia 43:

Code: Select all

#endif /* _COSMIC_ */

#ifdef _SDCC_
INTERRUPT_HANDLER_TRAP(TRAP_IRQHandler); /* TRAP */
INTERRUPT_HANDLER(TLI_IRQHandler, 0); /* TLI */
INTERRUPT_HANDLER(AWU_IRQHandler, 1); /* AWU */
INTERRUPT_HANDLER(CLK_IRQHandler, 2); /* CLOCK */
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3); /* EXTI PORTA */
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4); /* EXTI PORTB */
INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5); /* EXTI PORTC */
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6); /* EXTI PORTD */
INTERRUPT_HANDLER(EXTI_PORTE_IRQHandler, 7); /* EXTI PORTE */

#if defined(STM8S903) || defined(STM8AF622x)
INTERRUPT_HANDLER(EXTI_PORTF_IRQHandler, 8); /* EXTI PORTF */
#endif /* (STM8S903) || (STM8AF622x) */

#if defined (STM8S208) || defined (STM8AF52Ax)
INTERRUPT_HANDLER(CAN_RX_IRQHandler, 8); /* CAN RX */
INTERRUPT_HANDLER(CAN_TX_IRQHandler, 9); /* CAN TX/ER/SC */
#endif /* (STM8S208) || (STM8AF52Ax) */

INTERRUPT_HANDLER(SPI_IRQHandler, 10); /* SPI */
INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12); /* TIM1 CAP/COM */
INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11); /* TIM1 UPD/OVF/TRG/BRK */

#if defined(STM8S903) || defined(STM8AF622x)
INTERRUPT_HANDLER(TIM5_UPD_OVF_BRK_TRG_IRQHandler, 13); /* TIM5 UPD/OVF/BRK/TRG */
INTERRUPT_HANDLER(TIM5_CAP_COM_IRQHandler, 14); /* TIM5 CAP/COM */
#else /* (STM8S208) || (STM8S207) || (STM8S105) || (STM8S103) || (STM8AF52Ax) || (STM8AF62Ax) || (STM8A626x) */
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13); /* TIM2 UPD/OVF/BRK */
INTERRUPT_HANDLER(TIM2_CAP_COM_IRQHandler, 14); /* TIM2 CAP/COM */
#endif /* (STM8S903) || (STM8AF622x) */

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \
defined(STM8S005) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined (STM8AF626x)
INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler, 15); /* TIM3 UPD/OVF/BRK */
INTERRUPT_HANDLER(TIM3_CAP_COM_IRQHandler, 16); /* TIM3 CAP/COM */
#endif /* (STM8S208) || (STM8S207) || (STM8S105) || (STM8AF52Ax) || (STM8AF62Ax) || (STM8A626x) */

#if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S103) || \
defined (STM8S001) || defined(STM8S003) || defined (STM8AF52Ax) || defined (STM8AF62Ax) || defined (STM8S903)
INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17); /* UART1 TX */
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18); /* UART1 RX */
#endif /* (STM8S208) || (STM8S207) || (STM8S903) || (STM8S103) || (STM8S001) || (STM8AF52Ax) || (STM8AF62Ax) */

#if defined (STM8AF622x)
INTERRUPT_HANDLER(UART4_TX_IRQHandler, 17); /* UART4 TX */
INTERRUPT_HANDLER(UART4_RX_IRQHandler, 18); /* UART4 RX */
#endif /* (STM8AF622x) */

INTERRUPT_HANDLER(I2C_IRQHandler, 19); /* I2C */

#if defined(STM8S105) || defined(STM8S005) || defined (STM8AF626x)
INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21); /* UART2 RX */
INTERRUPT_HANDLER(UART2_TX_IRQHandler, 20); /* UART2 TX */
#endif /* (STM8S105) || (STM8AF626x) */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
INTERRUPT_HANDLER(UART3_RX_IRQHandler, 21); /* UART3 RX */
INTERRUPT_HANDLER(UART3_TX_IRQHandler, 20); /* UART3 TX */
#endif /* (STM8S207) || (STM8S208) || (STM8AF62Ax) || (STM8AF52Ax) */

#if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax)
INTERRUPT_HANDLER(ADC2_IRQHandler, 22); /* ADC2 */
#else /* (STM8S105) || (STM8S103) || (STM8S903) || (STM8AF622x) */
INTERRUPT_HANDLER(ADC1_IRQHandler, 22); /* ADC1 */
#endif /* (STM8S207) || (STM8S208) || (STM8AF62Ax) || (STM8AF52Ax) */

#if defined(STM8S903) || defined(STM8AF622x)
INTERRUPT_HANDLER(TIM6_UPD_OVF_TRG_IRQHandler, 23); /* TIM6 UPD/OVF/TRG */
#else /* (STM8S208) || (STM8S207) || (STM8S105) || (STM8S103) || (STM8AF62Ax) || (STM8AF52Ax) || (STM8AF626x) */
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23); /* TIM4 UPD/OVF */
#endif /* (STM8S903) || (STM8AF622x) */
INTERRUPT_HANDLER(EEPROM_EEC_IRQHandler, 24); /* EEPROM ECC CORRECTION */
#endif /* _SDCC_ */


#if !defined(_RAISONANCE_) && !defined(_SDCC_)
INTERRUPT void TRAP_IRQHandler(void); /* TRAP */

Wtedy można wykorzystać plik stm8_it.c i tam uzupełnić tylko odpowiednie zalążki funkcji obsługi przerwań w treść.

I najważniejsze przy tym podejściu: Plik stm8_it.h należy obowiązkowo włączyć w plik main.c. Inaczej linker nie poradzi sobie z ominięciem wektorów przerwań.

Modrzew.
Ostatnio zmieniony niedziela 10 maja 2020, 10:50 przez ZbeeGin, łącznie zmieniany 8 razy.

Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Re: Mikrokontroler STM8, biblitoteka SPL i kompilator SDCC - Na partyzanta

Postautor: ZbeeGin » sobota 20 lip 2019, 23:38

Jak się okazuje, są jeszcze dwa archiwa z bibliotekami StdPeriph dla kilku innych rodzin mikrokontrolerów STM8. Poprawki pokazane wyżej można zastosować też do:

  • STM8L10x_StdPeriph_Lib (en.stsw-stm8012.zip)
  • STM8L15x-16x-05x-AL31-L_StdPeriph_Lib (en.stsw-stm8016.zip)
gdyż struktura plików jest taka sama, aczkolwiek nie będą się zgadzać numery linii jakie podałem. Łatwo jednak znaleźć odpowiednie fragmenty.


Wróć do „Inne mikroklocki, również peryferyjne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 5 gości