STM32+Arduino,с чего начать?

Хочу попробовать силы в освоении STM32,в наличии голые контроллеры STM32F030F4P6 и STM32F103C8T6,есть ст-линк,из дисплеев выбрал ILI9225 если дойдет до них дело
Со старого форума прочитал,поставил аддон,все успешно,с чего начать изучение?

С языка программирования, на котором будешь писать код.

Библиотеку можешь тут взять
ЗЫ специально форк сделал и поправил ошибки

1 лайк

Arduino,рыщу в интернете в поисках поддержки STM32F030F4P6
Хотел поставить кейл но так и не разобрался как им пользоваться-делаю как описано при создании проекта и программа зависает пока принудительно ноутбук не выключишь
Пробовал кокос,успехи были-дошел до вывода чисел на дисплей ILI9225,именно чисел например “12345”,получилось,но как вывести переменную так и не разобрался-прут ошибки,может в ардуино проще
Могу дать исходники от кокоса,но его мало кто хвалит…

int main(void)
{
	int i;
	GPIO_InitTypeDef  GPIO_InitStructure;

	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_Init(GPIOA, &GPIO_InitStructure);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	    GPIO_Init(GPIOA, &GPIO_InitStructure);

	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_10;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_Init(GPIOB, &GPIO_InitStructure);
	    SPI_I2S_DeInit(SPI1);
	        SPI_InitTypeDef SPI_InitStructure;
	        SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
	        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	        SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
	        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
	        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	        SPI_Init(SPI1,&SPI_InitStructure);
	        SPI_I2S_ClearFlag(SPI1,SPI_I2S_FLAG_TXE);
	        SPI_Cmd(SPI1, ENABLE);

	        LCD_init();
            LED_Hi;
	    while (1)
	    {

	    	ili9225_clear(0x00000000);
	    	ili9225_set_window(10, 10, 50, 32);
	    	//write (*"12",Red);
	    	ssd1306_WrirteSting("12345",2,10,10);
	    	//timedate="3";
	    	//sprintf(timedate , "%04d", 2008) ; //дата
	    	ssd1306_WriteString(1,2,50,10);
	    	for(i=0;i<0x100000;i++);
	    	

	    }
	}
char  ssd1306_WriteChar(char ch,uint8_t Font)
{
	write (ch,Font,Red);
    return ch;
}
void  ssd1306_WriteString(char* str,uint8_t Font,uint8_t x, uint8_t y)
{
	uint8_t CurrentX;
	uint8_t CurrentY;
	CurrentX=x;
	CurrentY=y;
	while (*str)
    {
		ili9225_set_window(CurrentX, CurrentY, 40, 24);
		if (ssd1306_WriteChar(*str,Font) != *str)
        {
            // Char could not be written
            return *str;
        }

        // Next char
        str++;
        CurrentY=CurrentY+24;
        //CurrentY=CurrentY+32;
        //ili9225_set_window(CurrentX, CurrentY, 50, 32);
    }

    // Everything ok
    return *str;
}

Строка 46,там пытался вывести значение переменной,пробовал itoa,никак…выходит ошибка " collect2.exe: error: ld returned 1 exit status"

@xDriver если заглянет в тему и будет в хорошем настроении (он катушкой не натирается, поэтому настроение бывает разное, как и у меня) - возможно поможет.

Для исключения тупых вопросов:

Это не весь листинг. Нет объявления переменных.

1 лайк

учиться на 030 плохая идея, по ошибке - видимо нехватка памяти, бери F103, ядро от STM сейчас версия 2.81 среда ARDUINO IDE, адрес библиотеки я дал, начни с простого

Это если программировать в парадигме ARDUINO!!!

Естественно всё в 100 раз проще, к примеру:

// Include application, user and local libraries
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#include "math.h"

#if defined (ARDUINO_ARCH_STM32F1)|| defined (ARDUINO_ARCH_STM32F4)
#define TFT_RST PA1
#define TFT_RS  PA2
#define TFT_CS  PA0 // SS
#define TFT_SDI PA7 // MOSI
#define TFT_CLK PA5 // SCK
#define TFT_LED 0 // 0 if wired to +5V directly
#elif defined(ESP8266)
#define TFT_RST 4   // D2
#define TFT_RS  5   // D1
#define TFT_CLK 14  // D5 SCK
//#define TFT_SDO 12  // D6 MISO
#define TFT_SDI 13  // D7 MOSI
#define TFT_CS  15  // D8 SS
#define TFT_LED 2   // D4     set 0 if wired to +5V directly -> D3=0 is not possible !!
#elif defined(ESP32)
#define TFT_RST 26  // IO 26
#define TFT_RS  25  // IO 25
#define TFT_CLK 14  // HSPI-SCK
//#define TFT_SDO 12  // HSPI-MISO
#define TFT_SDI 13  // HSPI-MOSI
#define TFT_CS  15  // HSPI-SS0
#define TFT_LED 0 // 0 if wired to +5V directly
#else
#define TFT_RST 8
#define TFT_RS  9
#define TFT_CS  10  // SS
#define TFT_SDI 11  // MOSI
#define TFT_CLK 13  // SCK
#define TFT_LED 3   // 0 if wired to +5V directly
#endif

#define TFT_BRIGHTNESS 200 // Initial brightness of TFT backlight (optional)

#define ROTATE_ANGLE 10 // Angle in degrees to rotate the triangle

struct _point
{
    int16_t x;
    int16_t y;
};

// Use hardware SPI (faster - on Uno: 13-SCK, 12-MISO, 11-MOSI)
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_LED, TFT_BRIGHTNESS);

// Variables and constants
_point c1, c2, c3, cc;

// Setup
void setup() {
  tft.begin();

  // Define triangle start coordinates
  c1.x = 30;  c1.y = 30;
  c2.x = 120; c2.y = 80;
  c3.x = 80;  c3.y = 130;

  // Determine the rotation point, i.e. the center of the triangle
  cc = getCoordCentroid(c1, c2, c3);
  
  tft.clear();

}

// Loop
void loop() {
  // Calculate the number of steps to rotate the triangle a full rotation
  int16_t steps = (int16_t)(360 / ROTATE_ANGLE);

  // Draw solid triangle
  tft.fillTriangle(30, 190, 80, 150, 130, 210, COLOR_BLUE);

  for (int8_t i = 0; i < steps; i++) {
    // Draw triangle
    tft.drawTriangle(c1.x, c1.y, c2.x, c2.y, c3.x, c3.y, COLOR_GREEN);
    // Rotate triangle
    rotateTriangle(c1, c2, c3, cc, ROTATE_ANGLE);
    delay(50);
  }
  delay(5000);
  tft.clear();
}

// Get centroid of triangle
_point getCoordCentroid( _point a, _point b, _point c ) {
  _point o;

  o.x = (int16_t)((a.x + b.x + c.x) / 3);
  o.y = (int16_t)((a.y + b.y + c.y) / 3);

  return o;
}

// Rotate triangle around point r
void rotateTriangle( _point &a, _point &b, _point &c, _point r, int16_t deg ) {

  // Convert degrees to radians
  float angle = (float)deg * 1000 / 57296;

  // Rotate each individual point
  a = rotatePoint( r, angle, a);
  b = rotatePoint( r, angle, b);
  c = rotatePoint( r, angle, c);
}

// Rotate each point p around c
_point rotatePoint( _point c, float angle, _point p ) {
  _point r;
  
  // 1. translate point back to origin
  // 2. rotate point
  // 3. translate point back

  r.x = cos(angle) * (p.x - c.x) - sin(angle) * (p.y - c.y) + c.x;
  r.y = sin(angle) * (p.x - c.x) + cos(angle) * (p.y - c.y) + c.y;

  return r;
}

Если действительно хочешь разобраться с stm32 рекомендую прочитать цикл Программирование МК STM32 . Можно просто читать, можно читать и делать как автор. В любом случае после прочтения это цикла вопросов будет куда меньше.

3 лайка

Тут надо сразу определиться, что вы хотите, STM32 или оверхев Ардуино на ней с большей памятью и ее мГц-ами?

Выкладывайте код полностью. Где описана функция write?

В целом, судя по коду, у вас проблемы не с СТМ32 , а с языком программирования С/С++. Так что я бы на вашем месте СТМ пока отложил.

У меня нет такого окошка которое вы обвели

Спасибо,понял,начну с STM32F103

Спасибо за ссылку!

Программирование STM32 в среде arduino

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_conf.h"
//#include "stdio.h"
//#include "Font32x50.h"
//#include "Font16x24.h"
#include "disp.h"
#include <stdlib.h>
//#include <stdint.h>
//extern FontDef Font32x50;
//extern FontDef Font_16x24;

//#include "misc.h"
//#define HSE_VALUE    ((uint32_t)4000000)
#define EXTI9_5_IRQChannel  ((u8)0x17)  // External Line[9:5] Interrupts
/*
#define LCD_led GPIO_Pin_1;
#define LCD_RST GPIO_Pin_10;//PORTB
#define LCD_RS  GPIO_Pin_1;//PORTB
#define LCD_SDA GPIO_Pin_7;//PORTA
#define LCD_CLK GPIO_Pin_5;//PORTA
#define LCD_CS GPIO_Pin_4;//PORTA
*/

char timedate[5];
uint8_t  cur_col = 0;
//void RCC_Configuration(void);
//ErrorStatus HSEStartUpStatus;
int main(void)
{
	int i;
	GPIO_InitTypeDef  GPIO_InitStructure;

	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_Init(GPIOA, &GPIO_InitStructure);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	    GPIO_Init(GPIOA, &GPIO_InitStructure);

	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_10;
	    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	    GPIO_Init(GPIOB, &GPIO_InitStructure);
	    SPI_I2S_DeInit(SPI1);
	        SPI_InitTypeDef SPI_InitStructure;
	        SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
	        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	        SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
	        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
	        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	        SPI_Init(SPI1,&SPI_InitStructure);
	        SPI_I2S_ClearFlag(SPI1,SPI_I2S_FLAG_TXE);
	        SPI_Cmd(SPI1, ENABLE);

	        LCD_init();
            LED_Hi;
	    while (1)
	    {

	    	ili9225_clear(0x00000000);
	    	ili9225_set_window(10, 10, 50, 32);
	    	//write (*"12",Red);
	    	ssd1306_WrirteSting("12345",2,10,10);
	    	//timedate="3";
	    	sprintf(timedate , "%04d", 2008) ; //дата
	    	ssd1306_WriteString(1,2,50,10);
	    	for(i=0;i<0x100000;i++);


	    }
	}
char  ssd1306_WriteChar(char ch,uint8_t Font)
{
	write (ch,Font,Red);
    return ch;
}
void  ssd1306_WriteString(char* str,uint8_t Font,uint8_t x, uint8_t y)
{
	uint8_t CurrentX;
	uint8_t CurrentY;
	CurrentX=x;
	CurrentY=y;
	while (*str)
    {
		ili9225_set_window(CurrentX, CurrentY, 40, 24);
		if (ssd1306_WriteChar(*str,Font) != *str)
        {
            // Char could not be written
            return *str;
        }

        // Next char
        str++;
        CurrentY=CurrentY+24;
        //CurrentY=CurrentY+32;
        //ili9225_set_window(CurrentX, CurrentY, 50, 32);
    }

    // Everything ok
    return *str;
}

void delay_ms(uint32_t ms) {
   volatile uint32_t nCount;
   RCC_ClocksTypeDef RCC_Clocks;
   RCC_GetClocksFreq (&RCC_Clocks);
    nCount = (RCC_Clocks.HCLK_Frequency/10000)*ms;
    for (; nCount != 0; nCount--);
}


// *************************************************************************

библиотека ILI9225

#include "stdio.h"
#include "disp.h"
#include "Font32x50.h"
#include "Font24x40.h"
//#include "RusFont12.h"
void write(char c,uint8_t Font, uint16_t color) {
   if (c>=0x30) {
			c=c-0x30;//32,50,48,11
			short t1,t2;int i;
			if (Font==1) {t1=Font32x50[0];t2=Font32x50[1];}
			if (Font==2) {t1=Font24x40[0];t2=Font24x40[1];}



    RS_Low; __NOP(); CS_Low;
	SPI_Send(0x0022);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	CS_Hi;RS_Hi;__NOP();CS_Low;

	for (int j=0; j<t1*t2/8; j++) {
	   if (Font==1) {i=Font32x50[(c*t1*t2/8)+4+j];}
	   if (Font==2) {i=Font24x40[(c*t1*t2/8)+4+j];}
	   for (short k=0; k<8; k++) {
	   if (i&(1u<<(7-k))) {
	          SPI_Send(color);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	   } else {
		SPI_Send(0x0000);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	   }
     }}
	CS_Hi;}}
void ili9225_clear( uint16_t color){
	int i;
	//ili9225_write_register(0x0020, 0x0000);  /* column */
	//ili9225_write_register(0x0021, 0x0000);  /* row */
	ili9225_set_window(0, 0, 176, 220);
	RS_Low;__NOP();CS_Low;
	SPI_Send(0x0022);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	RS_Hi;__NOP();
	    for(i=0;i<0x219*175;i++){
	    		//SPI_Send(0x80808080);
	    	     SPI_Send(color);};
	CS_Hi;
}

void ili9225_set_window(uint16_t ul_x, uint16_t ul_y, uint8_t ul_width, uint8_t ul_height)
{    uint16_t CurrentX=ul_x;
     uint16_t CurrentY=ul_y;
	 ili9225_write_register(0x0036, ul_x + ul_width - 1);
     ili9225_write_register(0x0037, ul_x);
     ili9225_write_register(0x0038, ul_y + ul_height - 1);
     ili9225_write_register(0x0039, ul_y);
     ili9225_write_register(0x0020, ul_x);  /* column */
     ili9225_write_register(0x0021, ul_y);  /* row */
}


void SPI_Send (uint16_t SPI_Data) {
// while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1,SPI_Data);

__NOP(); __NOP();__NOP(); __NOP();
while(SPI1->SR & SPI_SR_BSY); // Wait for SPI Tx Buffer Empty
}

void LCD_CMD(uint16_t data) {
  CS_Low;
  RS_Low;//Низкий
  SPI_Send(data);
  CS_Hi;
}

void LCD_DATA(uint16_t data) {
  CS_Low;
  RS_Hi;
  SPI_Send(data);
  CS_Hi;
}

void ili9225_write_register(uint16_t uc_reg, uint16_t us_data)
{
	RS_Low;
	__NOP();
	CS_Low;
	uint8_t tmp=0x00;  //index
	SPI_Send(uc_reg);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	CS_Hi;RS_Hi;__NOP();CS_Low;
    SPI_Send(us_data);//HAL_SPI_Transmit(&hspi1, &tmp, 1, 1000);
	CS_Hi;
}

void ili9225_sw_reset(void)
{
	RESET_Hi;
	ili9225_write_register(0x0028, 0x00CE);
}









void LCD_init(void) {
	ili9225_sw_reset();
	delay_ms(50);
	   ili9225_write_register(0x0011 , 0x0018);
	   ili9225_write_register(0x0012 , 0x6121);
	   ili9225_write_register(0x0013 , 0x006F);                                        //65
	   ili9225_write_register(0x0014 , 0x495F);                                        //5058
	   ili9225_write_register(0x0010 , 0x0800);
	   delay_ms(50);
	   //Lcd_mode = 1    справа налево
	   /*    ili9225_write_register(0x0001 , 0x011C);
	   	   ili9225_write_register(0x0002 , 0x0100);
	   	   ili9225_write_register(0x0003 , 0x1030);*/
	   //Lcd_mode = 2
	   /*	   ili9225_write_register(0x0001 , 0x021C);
	   	   ili9225_write_register(0x0002 , 0x0100);
	   	   ili9225_write_register(0x0003 , 0x1030);*/
	   //Lcd_mode = 3    то что надо-сверху вниз слева направо
	   	   ili9225_write_register(0x0001 , 0x031C);
	   	   ili9225_write_register(0x0002 , 0x0100);
	   	   ili9225_write_register(0x0003 , 0x1038);
	   	//Lcd_mode = 4
	   	/*	ili9225_write_register(0x0001 , 0x001C);
	   		ili9225_write_register(0x0002 , 0x0100);
	   		ili9225_write_register(0x0003 , 0x1038);*/



	   ili9225_write_register(0x0011 , 0x1038);
	   ili9225_write_register(0x0007 , 0x0000);
	   ili9225_write_register(0x0008 , 0x0808);
	   ili9225_write_register(0x000b , 0x1100);
	   ili9225_write_register(0x000c , 0x0000);
	   ili9225_write_register(0x000f , 0x0D01);                                        //e01
	   ili9225_write_register(0x0020 , 0x0000);
	   ili9225_write_register(0x0021 , 0x0000);
	   ili9225_write_register(0x0030 , 0x0000);
	   ili9225_write_register(0x0031 , 0x00DB);
	   ili9225_write_register(0x0032 , 0x0000);
	   ili9225_write_register(0x0033 , 0x0000);
	   ili9225_write_register(0x0034 , 0x00DB);
	   ili9225_write_register(0x0035 , 0x0000);
	   ili9225_write_register(0x0036 , 0x00AF);
	   ili9225_write_register(0x0037 , 0x0000);
	   ili9225_write_register(0x0038 , 0x00DB);
	   ili9225_write_register(0x0039 , 0x0000);
	   ili9225_write_register(0x0050 , 0x0000);
	   ili9225_write_register(0x0051 , 0x0808);
	   ili9225_write_register(0x0052 , 0x080A);
	   ili9225_write_register(0x0053 , 0x000A);
	   ili9225_write_register(0x0054 , 0x0A08);
	   ili9225_write_register(0x0055 , 0x0808);
	   ili9225_write_register(0x0056 , 0x0000);
	   ili9225_write_register(0x0057 , 0x0A00);
	   ili9225_write_register(0x0058 , 0x0710);
	   ili9225_write_register(0x0059 , 0x0710);
	   delay_ms(50);
	   ili9225_write_register(0x0007 , 0x0012);
	   delay_ms(50);
	   ili9225_write_register(0x0007 , 0x1017);
	   delay_ms(50);
     delay_ms(50);

}

но это уже не важно-в кокосе я не разберусь никогда потому решил перейти на ардуино

И правильно. Намного проще так. Главное на первых порах не ставить себе сверхтрудных задач а разбираться постепенно наращивая их сложность.

2 лайка

ну да, только зачем тащить в эту ардуину SPL?
писал бы как все setup{}; loop{};
а то начинают свои delay_ms писать.

1 лайк

берите готовую плату “блю пилл” как её называют, с этим процессором. Для начала самое то - подключаете проводками и тренируетесь.