W tym poście chciałbym opisać sposób przygotowania projektu w języku C++ dla układu STM32.
Przy takiej implementacji __io_putchar na terminalu można zaobserwować poprawne działanie obu funkcji.
[Źródło: http://www.st.com/en/evaluation-tools/stm32f4discovery.html]
Na samym początku należy standardowo wygenerować projekt za pomocą CubeMx.
Po wygenerowaniu i załadowaniu np. do STM32CubeIde, projekt należy przekonwertować do C++, przez kliknięcie na niego prawym przyciskiem myszy.
Po konwersji należy dołożyć plik main.cpp lub zmienić nazwę już umieszczonego pliku main.c.
W tak przygotowanym projekcie można sprawdzić działanie operacji przesyłania danych na terminal:
- #include <iostream>
- int __io_putchar (int ch)
- {
- HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 1000);
- return ch;
- }
- //W funkcji main oba sposoby przesłania danych zadziałają poprawnie
- std::cout << "wartosc " << "\r\n";
- printf("test2\r\n");
Poniżej przykład użycia:
- uint8_t value = 12;
- int value2 = 56;
- std::cout << unsigned(value) << "\r\n";
- std::cout << value2 << "\r\n";
- printf("test2 %u\r\n", value);
Teraz przygotuję prostą klasę obsługującą cztery diody zamontowane na płytce discovery.
Klasę można dodać przez kliknięcie prawym przyciskiem na projekt Add->Class. Otworzy to okno z możliwością dodania nowych plików.
- #ifndef INC_DIODECONTROLCLASS_H_
- #define INC_DIODECONTROLCLASS_H_
- #include "main.h"
- class DiodeControlClass {
- private:
- uint8_t diodeNumber;
- void InitPins(void);
- public:
- DiodeControlClass();
- virtual ~DiodeControlClass();
- void TurnOnDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- void TurnOffDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- void ToggleDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- void LoopThroughDiodes(void);
- };
- #endif /* SRC_DIODECONTROLCLASS_H_ */
- #include "DiodeControlClass.h"
- DiodeControlClass::DiodeControlClass() {
- // TODO Auto-generated constructor stub
- InitPins();
- }
- DiodeControlClass::~DiodeControlClass() {
- // TODO Auto-generated destructor stub
- }
- void DiodeControlClass::InitPins(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __HAL_RCC_GPIOD_CLK_ENABLE();
- HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
- GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
- }
- void DiodeControlClass::TurnOnDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
- HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
- }
- void DiodeControlClass::TurnOffDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
- HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
- }
- void DiodeControlClass::ToggleDiode(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
- HAL_GPIO_TogglePin(GPIOx, GPIO_Pin);
- }
- void DiodeControlClass::LoopThroughDiodes(void)
- {
- if(diodeNumber >= 4)
- {
- diodeNumber = 0;
- }
- if(diodeNumber == 0) {
- ToggleDiode(GPIOD, GPIO_PIN_12);
- diodeNumber++;
- }
- else if(diodeNumber == 1) {
- ToggleDiode(GPIOD, GPIO_PIN_13);
- diodeNumber++;
- }
- else if(diodeNumber == 2) {
- ToggleDiode(GPIOD, GPIO_PIN_14);
- diodeNumber++;
- }
- else if(diodeNumber == 3) {
- ToggleDiode(GPIOD, GPIO_PIN_15);
- diodeNumber++;
- }
- }
Jej wywołanie wywołanie wygląda następująco:
- /* USER CODE BEGIN 2 */
- DiodeControlClass DiodeControl;
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- DiodeControl.LoopThroughDiodes();
- HAL_Delay(400);
- }
- /* USER CODE END 3 */