stm32 и подключение sdd1306 по SPI

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
aaleksander
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 07, 2015 21:00:35

stm32 и подключение sdd1306 по SPI

Сообщение aaleksander »

Добрый день всем.

Есть у меня пару экранчиков с данным чипом.
По i2c подключился без проблем.
А вот с spi вышла засада. Вчера до полуночи пытался вдохнуть жизнь в экранчик (рабочий, на AVR работает без проблемм).
Совсем отчаялся, вытащил stlink из usb и пошел водички перед сном попить.
Пока ходил, пришла еще одна мысль, дай как еще попробую. Втыкаю программатор в юсб, а оно заработало! :shock: Криво, косо, но экран ожил.
Т.е. проблема номер раз - при перепрошивке, экран не поднимается, только при полном отключении питания.
Ну еще час потерянного сна и постоянное тыкание туда-сюда программатора.
Картинку выводит, но только в первый раз. Если в цикле, то картинка за пару секунд приходит в непотребный вид.
Дальше, все на картинках.
Вот так выглядит экран, если выводить один раз, а потом просто пустой цикл без обновления экрана. Ну и программатор передернуть, естественно.
СпойлерДа-да. Спер без зазрения совести :twisted:
Изображение
А вот так, если обновлять одну и ту же картинку в цикле.
СпойлерИзображение
Все статьи, что нашел, прочитал, все попробовал. Но где-то у меня принципиальный косяк в понимании.
Не могу понять:
1. Почему не работает сразу после прошивки и надо передергивать питание?
2. Почему в цикле портится картинка.
Код прилагаю.
Спойлер

Код: Выделить всё

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"

#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2

#define SSD1306_DEACTIVATE_SCROLL 0x2E

#define BLACK 0
#define WHITE 1
#define INVERSE 2
#define NONE 3

#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF

#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA

#define SSD1306_SETVCOMDETECT 0xDB

#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9

#define SSD1306_SETMULTIPLEX 0xA8

#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10

#define SSD1306_SETSTARTLINE 0x40

#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR   0x22

#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8

#define SSD1306_SEGREMAP 0xA0

#define SSD1306_CHARGEPUMP 0x8D

#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
static uint8_t buffer[64 * 128 / 8] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
	0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
	0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
	0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
	0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
	0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
	0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
	0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
	0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
	0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
	0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
	0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
	0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
	0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
	0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
	0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
	0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
	0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
	0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
	0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
	0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
	0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
	0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
	0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
	0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
	0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
	0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//1....GND: Power ground
//2....VCC: 3.3V or 5V power supply
//3....D0: CLK Clock
//4....D1: MOSI data
//5....RST: Reset
//6....DC: data / command
//7....CS: Chip select signal

#define LED_OFF GPIO_ResetBits(GPIOC, GPIO_Pin_13);
#define LED_ON GPIO_SetBits(GPIOC, GPIO_Pin_13);

void init_gpio()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

	//светодиод (reset)
	GPIO_InitTypeDef init;
	init.GPIO_Mode = GPIO_Mode_Out_PP;
	init.GPIO_Pin = GPIO_Pin_13;
	init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &init);

	//ноги SPI
	init.GPIO_Mode = GPIO_Mode_AF_PP;
	init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOA, &init);

	//нога для D/C (данные/команда)
	init.GPIO_Mode = GPIO_Mode_Out_PP;
	init.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA, &init);
}

void init_spi()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	SPI_InitTypeDef spi;
	SPI_StructInit(&spi);
	spi.SPI_Direction = SPI_Direction_1Line_Tx; //только на передачу, по одной линии
	spi.SPI_DataSize = SPI_DataSize_8b;
	spi.SPI_CPOL = SPI_CPOL_Low; //полярность
	spi.SPI_CPHA = SPI_CPHA_1Edge; //и фаза тактового сигнала
	spi.SPI_NSS = SPI_NSS_Soft; //NSS управлять программно
	spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //предделитель SCK
	spi.SPI_FirstBit = SPI_FirstBit_MSB; //первым идет старший бит
	spi.SPI_Mode = SPI_Mode_Master; //режим

	SPI_I2S_DeInit(SPI1);
	SPI_Init(SPI1, &spi);
	SPI_Cmd(SPI1, ENABLE);

	SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);
}


// передача команды на дисплей
void spi1_CmdMode()
{
  GPIO_ResetBits(GPIOA, GPIO_Pin_0);   // DC=0;
}

// передача данных на дисплей
void spi1_DataMode()
{
  GPIO_SetBits(GPIOA, GPIO_Pin_0);   // DC=1;
}

//послать байт
void spi1_SendByte(uint8_t sendData)
{
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI1, sendData);
}

void delay(uint32_t c)
{
	for(int i=0; i<c; i++);
}

int main(void)
{
	init_gpio();
	init_spi();
	int i;

	//ресет экрана
	LED_ON
	delay(1000);
	LED_OFF
	delay(10000);
	LED_ON

	spi1_CmdMode();
	spi1_SendByte(0xAE); //display off
	spi1_SendByte(0x20); //Set Memory Addressing Mode
	spi1_SendByte(0x00); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	spi1_SendByte(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
	spi1_SendByte(0xC8); //Set COM Output Scan Direction
	spi1_SendByte(0x00); //---set low column address
	spi1_SendByte(0x10); //---set high column address
	spi1_SendByte(0x40); //--set start line address
	spi1_SendByte(0x81); //--set contrast control register
	spi1_SendByte(0xFF);
	spi1_SendByte(0xA1); //--set segment re-map 0 to 127
	spi1_SendByte(0xA6); //--set normal display
	spi1_SendByte(0xA8); //--set multiplex ratio(1 to 64)
	spi1_SendByte(0x3F); //
	spi1_SendByte(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	spi1_SendByte(0xD3); //-set display offset
	spi1_SendByte(0x00); //-not offset
	spi1_SendByte(0xD5); //--set display clock divide ratio/oscillator frequency
	spi1_SendByte(0xF0); //--set divide ratio
	spi1_SendByte(0xD9); //--set pre-charge period
	spi1_SendByte(0x22); //
	spi1_SendByte(0xDA); //--set com pins hardware configuration
	spi1_SendByte(0x12);
	spi1_SendByte(0xDB); //--set vcomh
	spi1_SendByte(0x20); //0x20,0.77xVcc
	spi1_SendByte(0x8D); //--set DC-DC enable
	spi1_SendByte(0x14); //
	spi1_SendByte(0xAF); //--turn on SSD1306 panel
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)!=RESET); // ждем пока данные передадутся до конца

	spi1_SendByte(0x21);
	spi1_SendByte(0);
	spi1_SendByte(127);

	spi1_SendByte(0x22);
	spi1_SendByte(0);
	spi1_SendByte(7);
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)!=RESET); // ждем пока данные передадутся до конца

	spi1_DataMode();
	for(i=0; i<128*64/8; i++)
		spi1_SendByte(buffer[i]);
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)!=RESET); // ждем пока данные передадутся до конца

    while(1)
    {
    	spi1_CmdMode();
    	spi1_SendByte(0x21);
    	spi1_SendByte(0);
    	spi1_SendByte(127);

    	spi1_SendByte(0x22);
    	spi1_SendByte(0);
    	spi1_SendByte(7);
    	while (SPI_I2S_GetFlagStatus(SPI1, (1 << 7))!=RESET); // ждем пока данные передадутся до конца

    	//копируем буфер на экран
    	spi1_DataMode();
    	for(i=0; i<128*64/8; i++)
    		spi1_SendByte(buffer[i]);

    	while (SPI_I2S_GetFlagStatus(SPI1, (1 << 7))!=RESET); // ждем пока данные передадутся до конца
    	//for(i=0; i<100000; i++);
    }
}
Если кто-то настолько крут, что мельком пробежавшись по коду, найдет ошибку, не сочтите за труд ткнуть носом.
Спасибо.
Реклама
Аватара пользователя
Zhuk72
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку
Контактная информация:

Re: stm32 и подключение sdd1306 по SPI

Сообщение Zhuk72 »

Код не смотрел, но на подобное наткнулся на прошлой неделе со 103С8 и дисплеем 5110.
Мучился, ну никак не выводит инфо, и это при том, что на ПИКе я его инициализацию вылизал по полной.
Утром включаю комп, втыкаю st-link, от которого питается плата с ЖКИ и с удивлением вижу свой текст, который накануне упорно пытался вывести.

Причина в том, что после подачи питания на дисплей нужно провести его правильную инициализацию сразу. А в том случае, когда вы пару раз в процессе наладки обновляете прошивку, питание с дисплея не снимается, процедура инита проходит запоздало (от момента запитывания), вот он и молчит. Так что ставьте ключ на питание дисплея и включайте его из программы перед инициализацией. Либо, как я временно сделал (каюсь, неправильно это), подключил вывод питания на ногу МК. Т.е. он питается "единицей" с порта :) Но, судя по всему, это и есть причина глюков у меня: в первый раз ЖКИ что-то выводит и подвисает. Просто никак не спаяю ключ на питание.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Реклама
Аватара пользователя
aaleksander
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 07, 2015 21:00:35

Re: stm32 и подключение sdd1306 по SPI

Сообщение aaleksander »

Zhuk72, ну это решение в лоб, оно же - костыль. Хотя право на жизнь имеет. Останавливает то, что этот же экран от аврки запускается на ура. Ну и второй вопрос остается: почему портится картинка при обновлении. На лицо косяк в логике.
Аватара пользователя
Zhuk72
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку
Контактная информация:

Re: stm32 и подключение sdd1306 по SPI

Сообщение Zhuk72 »

Я только на первый вопрос отвечал. А АВР же не питается от программатора, верно? Тут проблема в том, что схема запитывается от st-link и во время прошивки питание остается на дисплее, а время начала инициализации уже превысило какое-то паспортное.
Костыль, я же не спорю. Но я был вдали от дома и лепить ключ на питание было не из чего. А сейчас некогда.

На второй не отвечу, т.к. покупка такого ОЛЕДа только в планах.

Добавлено after 3 minutes 23 seconds:
Только сейчас обратил внимание на картинки.
Нет времени смотреть код, но проверьте как обстоят дела с адресацией в этих дисплеях. Адрес автоматически инкрементируется, а в цикле у вас, вероятно, начальный адрес не задается. Вернее задается один раз где-то до начала цикла, потому и происходит смещение.
Это просто предположение.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Реклама
Эиком - электронные компоненты и радиодетали
Зурбаган
Открыл глаза
Сообщения: 76
Зарегистрирован: Вс июн 18, 2017 08:12:41

Re: stm32 и подключение sdd1306 по SPI

Сообщение Зурбаган »

Код: Выделить всё

init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_5 |
не вижу NSS, он же CS на стороне дисплея. Как он подключен? Его настоятельно рекомендуется подключать не к GND, а именно к управляемому с микроконтроллера выводу. Иначе, пока не инициализован SPI, на дисплей могут проникать шумовые данные от шины и портить весь старт дисплея.

Скопировав весь ваш код и устранив указанное замечание - добавив программное переключение CS = 0 перед началом команд, либо поставив аппаратное управление SPI1->CR2 = SPI_CR2_SSOE и назначив PA4 на выход AF, теперь всё работает без сбоев:
(у меня сине-желтый дисплей с двумя областями, поэтому видна ступенька)

Изображение

Сбои у вас были от наводок на CS дисплея из-за висящего в воздухе вывода. Попробуйте без исправления кода пальцем ткнуть в CS - у вас все полетит к чертям.

ЗЫ. RESET дисплея у меня подключен к общему сбросу отладочной платы и отдельная команда сброса дисплея не используется

ЗЫ-2. Каждый раз задавать начальные и конечные координаты окна вывода в этом конкретном случае - НЕ нужно. Дисплей работает по кругу, после последнего столбца последней страницы он автоматом переходит на первый.

ЗЫ-3. После подачи питания дисплей может сколь угодно долго находиться в стендбае без инициализации, а инициализация и его включение может быть проведена в любое время, и после этого дисплей будет работать нормально.

ЗЫ-4. Рекомендовано выдерживать некоторые задержки, в частности, после включения DC/DC-конвертера. В документации об этом сказано. 100 мс написано. Но на деле работает и с гораздо меньшей.
After VCC become stable, send command AFh for display ON. SEG/COM will be ON after 100ms
(tAF).


ЗЫ-5. Чисто формально, буфер должен определяться не как [64 * 128 / 8], а как [128 * 64 / 8]. Хотя это чистая формальность, но смысл диаметрально противоположный - страниц в дисплее 64/8, а не 128/8. Впоследствии, это может запутать.
Ёшкин кот обормот
Реклама
Аватара пользователя
aaleksander
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 07, 2015 21:00:35

Re: stm32 и подключение sdd1306 по SPI

Сообщение aaleksander »

[uquote="Зурбаган",url="/forum/viewtopic.php?p=3140631#p3140631"]

Код: Выделить всё

init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_5 |
не вижу NSS, он же CS на стороне дисплея. Как он подключен? Его настоятельно рекомендуется подключать не к GND, а именно к управляемому с микроконтроллера выводу. Иначе, пока не инициализован SPI, на дисплей могут проникать шумовые данные от шины и портить весь старт дисплея.
Скопировав весь ваш код и устранив указанное замечание - добавив программное переключение CS = 0 перед началом команд, либо поставив аппаратное управление SPI1->CR2 = SPI_CR2_SSOE и назначив PA4 на выход AF, теперь всё работает без сбоев:
Сбои у вас были от наводок на CS дисплея из-за висящего в воздухе вывода. Попробуйте без исправления кода пальцем ткнуть в CS - у вас все полетит к чертям.[/uquote]

Блин, вот это опечатка :oops:
Спасибо, все заработало. Но почему-то CS не хочет работать при Mode = GPIO_Mode_AF_PP: когда подношу палец к проводу, начинаются пляски. Поэтому настроил его отдельно на выход и сразу выставил в ноль.
Теперь все работает стабильно. Огромное спасибо за помощь.

Полностью рабочий код, если кому надо:
Спойлер

Код: Выделить всё

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"

//подключение:
//DO -> A5
//D1 -> A7
//res -> C13
//DC -> A0
//CS -> A4


#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2

#define SSD1306_DEACTIVATE_SCROLL 0x2E

#define BLACK 0
#define WHITE 1
#define INVERSE 2
#define NONE 3

#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF

#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA

#define SSD1306_SETVCOMDETECT 0xDB

#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9

#define SSD1306_SETMULTIPLEX 0xA8

#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10

#define SSD1306_SETSTARTLINE 0x40

#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR   0x22

#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8

#define SSD1306_SEGREMAP 0xA0

#define SSD1306_CHARGEPUMP 0x8D

#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
static uint8_t buffer[128*64/8] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
	0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
	0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
	0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
	0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
	0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
	0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
	0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
	0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
	0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
	0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
	0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
	0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
	0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
	0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
	0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
	0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
	0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
	0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
	0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
	0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
	0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
	0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
	0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
	0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
	0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
	0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
	0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//1....GND: Power ground
//2....VCC: 3.3V or 5V power supply
//3....D0: CLK Clock
//4....D1: MOSI data
//5....RST: Reset
//6....DC: data / command
//7....CS: Chip select signal


void init_gpio()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

	//светодиод (reset)
	GPIO_InitTypeDef init;
	init.GPIO_Mode = GPIO_Mode_Out_PP;
	init.GPIO_Pin = GPIO_Pin_13;
	init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &init);

	//ноги SPI (MISO(A6) не используем)
	init.GPIO_Mode = GPIO_Mode_AF_PP;
	init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
	GPIO_Init(GPIOA, &init);

	//нога для D/C (данные/команда) и для выбора чипа (NSS, CS)
	init.GPIO_Mode = GPIO_Mode_Out_PP;
	init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_4;
	GPIO_Init(GPIOA, &init);
}

void init_spi()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	SPI_InitTypeDef spi;
	SPI_StructInit(&spi);
	spi.SPI_Direction = SPI_Direction_1Line_Tx;
	spi.SPI_DataSize = SPI_DataSize_8b;
	spi.SPI_CPOL = SPI_CPOL_Low; //полярность
	spi.SPI_CPHA = SPI_CPHA_1Edge; //и фаза тактового сигнала
	spi.SPI_NSS = SPI_NSS_Soft; //NSS управлять программно
	spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //предделитель SCK
	spi.SPI_FirstBit = SPI_FirstBit_MSB; //первым идет старший бит
	spi.SPI_Mode = SPI_Mode_Master; //режим

	SPI_I2S_DeInit(SPI1);
	SPI_Init(SPI1, &spi);
	SPI_Cmd(SPI1, ENABLE);
}

#define LED_OFF GPIO_ResetBits(GPIOC, GPIO_Pin_13);
#define LED_ON GPIO_SetBits(GPIOC, GPIO_Pin_13);

void spi1_SendByte(uint8_t sendData)
{
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //ждем пока закончится передача
  SPI_I2S_SendData(SPI1, sendData);
}

void delay(uint32_t c)
{
	for(int i=0; i<c; i++);
}

void sdd_1306_init()
{
	//ресет
	LED_ON
	delay(1000);
	LED_OFF
	delay(10000);
	LED_ON

	//spi1_SetCmdMode();
	//режим командр
	GPIO_ResetBits(GPIOA, GPIO_Pin_0);   // DC=0;
	spi1_SendByte(0xAE); //display off
	spi1_SendByte(0x20); //Set Memory Addressing Mode
	spi1_SendByte(0x00); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	spi1_SendByte(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
	spi1_SendByte(0xC8); //Set COM Output Scan Direction
	spi1_SendByte(0x00); //---set low column address
	spi1_SendByte(0x10); //---set high column address
	spi1_SendByte(0x40); //--set start line address
	spi1_SendByte(0x81); //--set contrast control register
	spi1_SendByte(0xFF);
	spi1_SendByte(0xA1); //--set segment re-map 0 to 127
	spi1_SendByte(0xA6); //--set normal display
	spi1_SendByte(0xA8); //--set multiplex ratio(1 to 64)
	spi1_SendByte(0x3F); //
	spi1_SendByte(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	spi1_SendByte(0xD3); //-set display offset
	spi1_SendByte(0x00); //-not offset
	spi1_SendByte(0xD5); //--set display clock divide ratio/oscillator frequency
	spi1_SendByte(0xF0); //--set divide ratio
	spi1_SendByte(0xD9); //--set pre-charge period
	spi1_SendByte(0x22); //
	spi1_SendByte(0xDA); //--set com pins hardware configuration
	spi1_SendByte(0x12);
	spi1_SendByte(0xDB); //--set vcomh
	spi1_SendByte(0x20); //0x20,0.77xVcc
	spi1_SendByte(0x8D); //--set DC-DC enable
	spi1_SendByte(0x14); //
	spi1_SendByte(0xAF); //--turn on SSD1306 panel

	//адресация
	spi1_SendByte(0x21);
	spi1_SendByte(0);
	spi1_SendByte(127);

	spi1_SendByte(0x22);
	spi1_SendByte(0);
	spi1_SendByte(7);
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)!=RESET); // ждем пока данные передадутся до конца

	//переключаемся на данные, больше команд не будет
	GPIO_SetBits(GPIOA, GPIO_Pin_0);   // DC=1;
	//spi1_SetDataMode();
}

void display()
{
	for(int i=0; i<128*64/8; i++)
		spi1_SendByte(buffer[i]);
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)!=RESET); // ждем пока данные передадутся до конца
}

int main(void)
{
	init_gpio();
	init_spi();
	sdd_1306_init();

	display();
    while(1)
    {

    }
}
Реклама
Ответить

Вернуться в «ARM»