Хочу попробовать силы в освоении STM32,в наличии голые контроллеры STM32F030F4P6 и STM32F103C8T6,есть ст-линк,из дисплеев выбрал ILI9225 если дойдет до них дело
Со старого форума прочитал,поставил аддон,все успешно,с чего начать изучение?
С языка программирования, на котором будешь писать код.
Библиотеку можешь тут взять
ЗЫ специально форк сделал и поправил ошибки
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 если заглянет в тему и будет в хорошем настроении (он катушкой не натирается, поэтому настроение бывает разное, как и у меня) - возможно поможет.
Это не весь листинг. Нет объявления переменных.
учиться на 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 . Можно просто читать, можно читать и делать как автор. В любом случае после прочтения это цикла вопросов будет куда меньше.
Тут надо сразу определиться, что вы хотите, 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);
}
но это уже не важно-в кокосе я не разберусь никогда потому решил перейти на ардуино
И правильно. Намного проще так. Главное на первых порах не ставить себе сверхтрудных задач а разбираться постепенно наращивая их сложность.
ну да, только зачем тащить в эту ардуину SPL?
писал бы как все setup{}; loop{};
а то начинают свои delay_ms писать.
берите готовую плату “блю пилл” как её называют, с этим процессором. Для начала самое то - подключаете проводками и тренируетесь.

