Skocz do zawartości

SSD1327 przeróbka biblioteki tak aby działała z DMA


_LM_

Pomocna odpowiedź

Potrzebowałem na szybko biblioteki dla wyświetlacza OLED 1.5" Wziąłem pierwszą z brzegu: https://github.com/hexaguin/SSD1327 i przystosowałem ją aby działała na mikrokontroler STM32L476 z HAL:

.h

#ifndef SSD1327_SSD1327_H_
#define SSD1327_SSD1327_H_

#include "main.h"
#include "stdbool.h"
#include "spi.h"

// Scroll rate constants. See datasheet page 40.
#define SSD1327_SCROLL_2   0b111
#define SSD1327_SCROLL_3   0b100
#define SSD1327_SCROLL_4   0b101
#define SSD1327_SCROLL_5   0b110
#define SSD1327_SCROLL_6   0b000
#define SSD1327_SCROLL_32  0b001
#define SSD1327_SCROLL_64  0b010
#define SSD1327_SCROLL_256 0b011


//		void writeCmd(uint8_t reg);
		void writeData(uint8_t data);
		void setWriteZone(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
		uint16_t coordsToAddress(uint8_t x, uint8_t y);
		void setPixelChanged(uint8_t x, uint8_t y, bool changed);
		void SSD1327drawPixel(uint8_t x, uint8_t y, uint8_t color, bool display);
		void SSD1327drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color, bool display);
		void SSD1327drawHLine(int x, int y, int length, uint8_t color, bool display);
		void SSD1327drawVLine(int x, int y, int length, uint8_t color, bool display);
		void SSD1327drawLine(int x1, int y1, int x2, int y2, uint8_t color, bool display);
		void SSD1327drawByteAsRow(uint8_t x, uint8_t y, uint8_t byte, uint8_t color);
		void SSD1327drawChar(uint8_t x, uint8_t y, char thisChar, uint8_t color);
		void SSD1327drawChar16(uint8_t x, uint8_t y, char thisChar, uint8_t color);
		void SSD1327drawChar32(uint8_t x, uint8_t y, char thisChar, uint8_t color);
		void SSD1327drawCharArray(uint8_t x, uint8_t y, char text[], uint8_t color, int size);
		void SSD1327drawString(uint8_t x, uint8_t y, char * textString, uint8_t color, int size);
		void setupScrolling(uint8_t startRow, uint8_t endRow, uint8_t startCol, uint8_t endCol, uint8_t scrollSpeed, bool right);
		void startScrolling();
		void stopScrolling();
		void scrollStep(uint8_t startRow, uint8_t endRow, uint8_t startCol, uint8_t endCol, bool right);
		void fillStripes(uint8_t offset);
		void SSD1327clearBuffer();
		void SSD1327writeFullBuffer();
		void writeUpdates();
		void SSD1327setContrast(uint8_t contrast);
		void SSD1327initRegs();
		void SSD1327init(SPI_HandleTypeDef * hspi);

	extern	uint8_t frameBuffer[8192];   // Should mirror the display's own frameBuffer.
	extern 	uint8_t changedPixels[1024]; // Each bit of this array represets whether a given byte of frameBuffer (e.g. a pair of pixels) is not up to date.

#endif /* SSD1327_SSD1327_H_ */

.c

/*
 * ssd1327.c
 *
 *  Created on: Apr 22, 2022
 *      Author: dell
 */

#include "main.h"
#include "spi.h"
#include "dma.h"
#include "ssd1327.h"
#include "stdbool.h"

#include "stdlib.h"
#include "math.h"

#include "font8x8_basic.h"
#include "font16x16.h"
#include "font16x32.h"


#define CS_SET	 HAL_GPIO_WritePin(SSD_CS_GPIO_Port, SSD_CS_Pin,GPIO_PIN_SET)
#define CS_RESET HAL_GPIO_WritePin(SSD_CS_GPIO_Port, SSD_CS_Pin,GPIO_PIN_RESET)

#define DC_SET	 HAL_GPIO_WritePin(SSD_DC_GPIO_Port,SSD_DC_Pin,GPIO_PIN_SET)
#define DC_RESET HAL_GPIO_WritePin(SSD_DC_GPIO_Port,SSD_DC_Pin,GPIO_PIN_RESET)

#define RST_SET		HAL_GPIO_WritePin(SSD_RST_GPIO_Port,SSD_RST_Pin,GPIO_PIN_SET)
#define RST_RESET 	HAL_GPIO_WritePin(SSD_RST_GPIO_Port,SSD_RST_Pin,GPIO_PIN_RESET)


#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

		uint8_t frameBuffer[8192];   // Should mirror the display's own frameBuffer.
		uint8_t changedPixels[1024];



SPI_HandleTypeDef * spix;
static void bitWrite(uint8_t * x, uint8_t n, bool b);
static uint8_t bitRead(uint8_t x,uint8_t n)
{
	return(x & (1<<n));
}


// bitWrite(x, 0, 1);  // write 1 to the first bit of x

static void ssdDelay(uint32_t d);
static void	SSD1327writeCmd(uint8_t reg);

static void bitWrite(uint8_t * x, uint8_t n, bool b)
{
	b ? (*x|= (1 << n)):(*x&=~(1 << n));
}

//void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

//TODO: Find a way to handle the write commands without toggling CS and DC every time
void SSD1327writeCmd(uint8_t reg){//Writes a command byte to the driver
	  DC_RESET;
//	digitalWrite(_dc, LOW);
	  CS_RESET;
//	SPI.transfer(reg);
HAL_SPI_Transmit(spix,&reg,1,500);
CS_SET;
//	digitalWrite(_cs, HIGH);
}

void SSD1327writeData(uint8_t data){//Writes 1 byte to the display's memory

	  DC_SET;
	  CS_RESET;


HAL_SPI_Transmit(spix,&data,1,100);
	  CS_SET;
}

void SSD1327setWriteZone(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { //defines a rectangular area of memory which the driver will itterate through. This function takes memory locations, meaning a 64x128 space
	SSD1327writeCmd(0x15); //Set Column Address
	SSD1327writeCmd(x1); //Beginning. Note that you must divide the column by 2, since 1 byte in memory is 2 pixels
	SSD1327writeCmd(x2); //End

	SSD1327writeCmd(0x75); //Set Row Address
	SSD1327writeCmd(y1); //Beginning
	SSD1327writeCmd(y2); //End
}

uint16_t SSD1327coordsToAddress(uint8_t x, uint8_t y){ //Converts a pixel location to a linear memory address
	return (x/2)+(y*64);
}

void SSD1327setPixelChanged(uint8_t x, uint8_t y, bool changed){
	uint16_t targetByte = SSD1327coordsToAddress(x, y)/8;
	bitWrite(&changedPixels[targetByte], SSD1327coordsToAddress(x, y) % 8, changed);
}

void SSD1327drawPixel(uint8_t x, uint8_t y, uint8_t color, bool display){//pixel xy coordinates 0-127, color 0-15, and whether to immediately output it to the display or buffer it
	int address = SSD1327coordsToAddress(x,y);
	if((x%2) == 0){//If this is an even pixel, and therefore needs shifting to the more significant nibble
		frameBuffer[address] = (frameBuffer[address] & 0x0f) | (color<<4);
	} else {
		frameBuffer[address] = (frameBuffer[address] & 0xf0) | (color);
	}

	if(display){
		SSD1327setWriteZone(x/2,y,x/2,y);
		SSD1327writeData(frameBuffer[address]);
		SSD1327setPixelChanged(x, y, false); // We've now synced the display with this byte of the buffer, no need to write it again
	} else {
		SSD1327setPixelChanged(x, y, true); // This pixel is due for an update next refresh
	}
}

void SSD1327drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color, bool display){//Draws a rectangle from x1,y1 to x2,y2.
	uint8_t xMin = MIN(x1, x2); // TODO: double performance by writing whole bytes at a time
	uint8_t xMax = MAX(x1, x2);
	uint8_t yMin = MIN(y1, y2);
	uint8_t yMax = MAX(y1, y2);
	for (uint8_t x = xMin; x <= xMax; x++) {
		for (uint8_t y = yMin; y <= yMax; y++) {
			SSD1327drawPixel(x, y, color, display);
		}
	}
}

void SSD1327drawHLine(int x, int y, int length, uint8_t color, bool display){
	for (uint8_t i = x; i < x+length; i++) {
		SSD1327drawPixel(i, y, color, display);
	}
}

void SSD1327drawVLine(int x, int y, int length, uint8_t color, bool display){
	for (uint8_t i = y; i < y+length; i++) {
		SSD1327drawPixel(x, i, color, display);
	}
}

void SSD1327drawLine(int x0, int y0, int x1, int y1, uint8_t color, bool display){ //Bresenham's line algorithm
	int deltaX = abs(x1-x0);
	int deltaY = abs(y1-y0);
	int signX = x0<x1 ? 1 : -1;
	int signY = y0<y1 ? 1 : -1;
	int error = (deltaX>deltaY ? deltaX : -deltaY)/2, error2;

	while (true) {
		SSD1327drawPixel(x0, y0, color, display);
		if (x0==x1 && y0==y1) break;
		error2 = error;
		if (error2 >-deltaX) { error -= deltaY; x0 += signX; }
		if (error2 < deltaY) { error += deltaX; y0 += signY; }
	}
}

void SSD1327drawByteAsRow(uint8_t x, uint8_t y, uint8_t byte, uint8_t color){//Draws a byte as an 8 pixel row
	for (int i = 0; i < 8; i++) {
		if(bitRead(byte, i)){
			SSD1327drawPixel(x+i, y, color, false);
		}
	}
}

void SSD1327drawChar(uint8_t x, uint8_t y, char thisChar, uint8_t color){
	for (size_t i = 0; i < 8; i++) {
		SSD1327drawByteAsRow(x, y+i, font8x8_basic[(unsigned char)thisChar][i], color);
	}
}

void SSD1327drawCharArray(uint8_t x, uint8_t y, char text[], uint8_t color, int size){
	const char* thisChar;
	uint8_t xOffset = 0;
	if(size==16){
		for (thisChar = text; *thisChar != '\0'; thisChar++) {
			SSD1327drawChar16(x+xOffset, y, *thisChar, color);
			xOffset += 8;
		}
	} else if(size==32){
		for (thisChar = text; *thisChar != '\0'; thisChar++) {
			SSD1327drawChar32(x+xOffset, y, *thisChar, color);
			xOffset += 16;
		}
	}
	 else {
		for (thisChar = text; *thisChar != '\0'; thisChar++) {
			SSD1327drawChar(x+xOffset, y, *thisChar, color);
			xOffset += 8;
		}
	}
}

void SSD1327drawString(uint8_t x, uint8_t y, char * textString, uint8_t color, int size){
//	char text[64];
//	textString.toCharArray(text, 64);
	SSD1327drawCharArray(x,y, textString, color, size);
}

void SSD1327drawChar16(uint8_t x, uint8_t y, char thisChar, uint8_t color){
	for (size_t row = 0; row < 16; row++) {
		SSD1327drawByteAsRow(x, y+row, font16x16[(unsigned char)thisChar][row*2], color);
		SSD1327drawByteAsRow(x+8, y+row, font16x16[(unsigned char)thisChar][(row*2)+1], color);
	}
}

void SSD1327drawChar32(uint8_t x, uint8_t y, char thisChar, uint8_t color){
	for (size_t row = 0; row < 32; row++) {
		SSD1327drawByteAsRow(x, y+row, font16x32[(unsigned char)thisChar][row*2], color);
		SSD1327drawByteAsRow(x+8, y+row, font16x32[(unsigned char)thisChar][(row*2)+1], color);
	}
}

void SSD1327fillStripes(uint8_t offset){ //gradient test pattern
	for(int i = 0; i < 8192; i++){
		uint8_t color = ((i+offset) & 0xF) | (((i+offset) & 0xF)<<4);
		frameBuffer[i] = color;
	}
	for (uint16_t i = 0; i < 1024; i++) {
		changedPixels[i] = 0xFF; // Set all pixels to be updated next frame. fillStripes should not be used without a full write anyways, but just in case
	}
}

void SSD1327setupScrolling(uint8_t startRow, uint8_t endRow, uint8_t startCol, uint8_t endCol, uint8_t scrollSpeed, bool right){
	uint8_t swap;
	if (startRow > endRow) { // Ensure start row is before end
		swap = startRow;
		startRow = endRow;
		endRow = swap;
	}
	if (startCol > endCol) { // Ditto for columns
		swap = startCol;
		startCol = endCol;
		endCol = swap;
	}
	SSD1327writeCmd(0x2E);   // Deactivate scrolling before changing anything
	if (right) {
		SSD1327writeCmd(0x26); // Scroll right
	} else {
		SSD1327writeCmd(0x27); // Scroll left
	}
	SSD1327writeCmd(0); // Dummy byte
	SSD1327writeCmd(startRow);
	SSD1327writeCmd(scrollSpeed);
	SSD1327writeCmd(endRow);
	SSD1327writeCmd(startCol);
	SSD1327writeCmd(endCol);
	SSD1327writeCmd(0); // Dummy byte
};

void SSD1327startScrolling(){
	SSD1327writeCmd(0x2F);
}

void SSD1327stopScrolling(){
	SSD1327writeCmd(0x2E);
}

void SSD1327scrollStep(uint8_t startRow, uint8_t endRow, uint8_t startCol, uint8_t endCol, bool right){
	setupScrolling(startRow, endRow, startCol, endCol, SSD1327_SCROLL_2, right);
	startScrolling();
	ssdDelay(15);
	stopScrolling();
}

void SSD1327clearBuffer(){//
	for(int i = 0; i < 8192; i++){
		if (frameBuffer[i]) { // If there is a non-zero (non-black) byte here, make sure it gets updated
			frameBuffer[i] = 0;
			bitWrite(&changedPixels[i/8], i%8, 1); // Mark this pixel as needing an update
		}
	}
}

void SSD1327writeFullBuffer(){ //Outputs the full framebuffer to the display
	SSD1327setWriteZone(0,0,63,127); //Full display



	for(int i = 0; i < 8192; i++){
		SSD1327writeData(frameBuffer[i]);
	}

	for (uint16_t i = 0; i < 1024; i++) {
		changedPixels[i] = 0; // Set all pixels as up to date.
	}
}

void SSD1327writeUpdates(){ // Writes only the pixels that have changed to the display
	for (size_t y = 0; y < 128; y++) {
		bool continued = false; // If we can continue with the write zone we're using
		for (size_t x = 0; x < 128; x++) {
			uint16_t address = coordsToAddress(x, y);
			if ( bitRead(changedPixels[address/8], address % 8) ) { // If we need an update here
				if (!continued) { // Just write the byte, no new write zone needed
					continued = true;
					setWriteZone(x/2, y, 63, 127); // Set the write zone for this new byte and any subsequent ones
				}
				writeData(frameBuffer[address]);
				bitWrite(&changedPixels[address/8], address % 8, 0);
			} else {
				continued = false; // The chain of pixels is broken
			}
		}
	}
}

void SSD1327setContrast(uint8_t contrast){
	SSD1327writeCmd(0x81);  //set contrast control
	SSD1327writeCmd(contrast);  //Contrast byte
}



void SSD1327initRegs(){ //Sends all the boilerplate startup and config commands to the driver
	SSD1327writeCmd(0xae);//--turn off oled panel

	SSD1327writeCmd(0x15);  //set column addresses
	SSD1327writeCmd(0x00);  //start column  0
	SSD1327writeCmd(0x7f);  //end column  127

	SSD1327writeCmd(0x75);  //set row addresses
	SSD1327writeCmd(0x00);  //start row  0
	SSD1327writeCmd(0x7f);  //end row  127

	SSD1327writeCmd(0x81);  //set contrast control
	SSD1327writeCmd(0x80);  //50% (128/255)

	SSD1327writeCmd(0xa0);   //gment remap
	SSD1327writeCmd(0x51);  //51 (To my understanding, this is orientation

	SSD1327writeCmd(0xa1);  //start line
	SSD1327writeCmd(0x00);

	SSD1327writeCmd(0xa2);  //display offset
	SSD1327writeCmd(0x00);

	SSD1327writeCmd(0xa4);  //rmal display
	SSD1327writeCmd(0xa8);  //set multiplex ratio
	SSD1327writeCmd(0x7f);

	SSD1327writeCmd(0xb1);  //set phase leghth
	SSD1327writeCmd(0xf1);

	SSD1327writeCmd(0xb3);  //set dclk
	SSD1327writeCmd(0x00);  //80Hz:0xc1 90Hz:0xe1  100Hz:0x00  110Hz:0x30 120Hz:0x50  130Hz:0x70   01

	SSD1327writeCmd(0xab);  //Enable vReg
	SSD1327writeCmd(0x01);

	SSD1327writeCmd(0xb6);  //set phase leghth
	SSD1327writeCmd(0x0f);

	SSD1327writeCmd(0xbe); //Set vcomh voltage
	SSD1327writeCmd(0x0f);

	SSD1327writeCmd(0xbc); //set pre-charge voltage
	SSD1327writeCmd(0x08);

	SSD1327writeCmd(0xd5); //second precharge period
	SSD1327writeCmd(0x62);

	SSD1327writeCmd(0xfd); //Unlock commands
	SSD1327writeCmd(0x12);

	SSD1327writeCmd(0xAF);
ssdDelay(100);
}

void SSD1327init(SPI_HandleTypeDef * hspi){

	spix = hspi;

	RST_SET;

ssdDelay(10);
	//		digitalWrite(_rst, LOW);
	RST_RESET;

//delay(100);
ssdDelay(10);
RST_SET;
ssdDelay(10);

SSD1327initRegs();
}

static void ssdDelay(uint32_t d)
{
	HAL_Delay(d);
};

bibliotekę uruchomiłem, działa, ale widzę że jest sporo bajtów kopiowanych z ram do wyświetlacza, próbowałem to zrobić za pomocą DMA, ja używam SPI2 więc DMA pracuje na kanale 5 tryb normal. W pierszej kolejności próbowałem podmienić zawartość funkcji 

void SSD1327writeFullBuffer(){ //Outputs the full framebuffer to the display
	SSD1327setWriteZone(0,0,63,127); //Full display



	for(int i = 0; i < 8192; i++){
		SSD1327writeData(frameBuffer[i]);
	}

	for (uint16_t i = 0; i < 1024; i++) {
		changedPixels[i] = 0; // Set all pixels as up to date.
	}
}

W taki sposób:

void SSD1327writeFullBuffer(){ //Outputs the full framebuffer to the display
	SSD1327setWriteZone(0,0,63,127); //Full display
//	for(int i = 0; i < 8192; i++){
//		SSD1327writeData(frameBuffer[i]);
//	}

	DC_SET;
	CS_RESET;
	HAL_SPI_Transmit_DMA(&spi2,frameBuffer,8192);
	CS_SET;	
	
	
	for (uint16_t i = 0; i < 1024; i++) {
		changedPixels[i] = 0; // Set all pixels as up to date.
	}
}

W main jest przykładowy kod z biblioteki

  while (1)
  {
    static uint32_t lastTimer = 0;

    if(HAL_GetTick() > lastTimer)
    {
    	HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
       	lastTimer = HAL_GetTick() + 200;
//        SSD1327clearBuffer();
//        SSD1327drawString(16, 16, "Oled", 0x1, 32);
//        SSD1327drawString(16, 48, "TEST 1", 0x2, 32);
//        SSD1327drawString(20, 48+48, "16:32:55", 0xF, 16);
//        SSD1327setContrast(50);
//        SSD1327writeFullBuffer();
        framecount++;

        SSD1327clearBuffer();

        for (int x = 0; x < 128; x++) {
          for (int y = (sin(((float)x+framecount)/16)*32)+64; y < 128; y++) {
             SSD1327drawPixel(x, y, 3, false);
           }
        }

        SSD1327drawCharArray(24, 0, timeText, 0xF, 32);
        SSD1327drawString(0, 112, "-12.5C", 0xF, 16);
        SSD1327drawString(84, 112, "52.1%", 0xF, 16);

        SSD1327writeFullBuffer();
    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }



Tyle że zamiast delay, użyłem timera programowego.  Niestety DMA nie wysyła danych na SPI. Czy jeśli SPI jest skonfigurowane do pracy z DMA to mogę używać go też "normalnie" tj: część danych np ustawienia wysyłać z funkcji a część za pomocą DMA? 

Edytowano przez _LM_
Link do komentarza
Share on other sites

(edytowany)

Wrzucę cały projekt, chyba będzie prościej

oled1.zip

Jeszcze jak na złość wczoraj uszkodziłem ten wyświetlacz i teraz mam takie paski 😕

IMG_20220424_115515.thumb.jpg.e6ce10d31f66d192dde2786a0bc8bcb8.jpg

 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Paski zauważyłem dzisiaj, jestem pewny że to jest uszkodzenie mechaniczne, wyświetlacz ma uszczerbiony prawy dolny róg(od strony tasiemki). Musiałem go uszkodzić kiedy pakowałem razem z komputerem do torby. Z resztą, sprawdziłem wersję bez DMA. Trzeba mi nabrać nieco praktyki z DMA bo to ekstra sprawa, tak samo można by ładować wzory czcionek do ram przez ten interfejs, po co zajmować czas CPU jak jest taki mechanizm

Edytowano przez _LM_
Link do komentarza
Share on other sites

Szkoda, bo program raczej nie ma szans działać poprawnie, więc dziwna zawartość ekranu nie musiała oznaczać błędu sprzętowego.

Jako ciekawostkę proponuję zmienić funkcję writeFullBuffer() i dodać do niej delay:

	DC_SET;
	CS_RESET;
	HAL_SPI_Transmit_DMA(&spi2,frameBuffer,8192);
	HAL_Delay(100);
	CS_SET;	

 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Nie, tutaj raczej nie chodzi o flagę zajętości DMA (robi to HAL).

Ale zrozumienie dlaczego ten program nie działa to świetne ćwiczenie, więc nie będę przynudzał tłumaczeniem 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Ahh tak, pewnie chodzi o to że zlecam wysyłkę i natychmiast ustawiam CS, więc trzeba poszukać przerwania od zakończenia transferu i wtedy podnieść ten pin. Lub

  • ustawiać CS automatycznie w ustawieniach SPI
  • zostawić na stałe ściągnięty do masy bo i tak jednego urządzenia używam

Dzięki @Elvis !

Edytowano przez _LM_
Link do komentarza
Share on other sites

1 minutę temu, Elvis napisał:

CS było ewidentnym błędem, dlatego nic nie działało.

Masz oko, niema co 🙂 nie pierwszy raz wyłapujesz takie błędy. 

3 minuty temu, Elvis napisał:

Ale warto jeszcze pomyśleć co dzieje się z buforem obrazu.

W tej bibliotece jest więcej rzeczy do usprawnienia, póki co chciałem ją w ogóle uruchomić.

DMA jest dla mnie nowością, zbyt długo siedziałem w AVR. Także wiele przede mną.

Link do komentarza
Share on other sites

Jak chodzi o ten bufor - to jest o tyle dobrze, że to zmienna globalna, ale musisz uważać żeby go nie zmieniać podczas transmisji przez DMA. A ponieważ program poza rysowaniem prawie nic nie robi, więc używanie DMA to trochę sztuka dla sztuki, bo i tak trzeba czekać na zakończenie transmisji.

Można co prawda dodać drugi bufor, tylko pytanie, czy to ma jakikolwiek sens? Jeśli masz SPI na 10MHz, to przesłanie całej ramki zajmuje jakieś 6,5ms, a w pętli głównej i tak masz delay na 200ms. Więc większość czasu procesor nic nie robi, oczywiście można optymalizować program, ale tutaj nie jest to chyba niezbędne.

Link do komentarza
Share on other sites

2 minuty temu, Elvis napisał:

Można co prawda dodać drugi bufor

Albo wykorzystać przerwanie od połowy połowy transferu, 

 

3 minuty temu, Elvis napisał:

Jeśli masz SPI na 10MHz

Dokładnie tak jest

4 minuty temu, Elvis napisał:

w pętli głównej i tak masz delay na 200ms

Kiedy coś testuję to nie jadę na fullspeed 🙂 teraz timer programowy leci na 10mS i elegancko śmiga

Link do komentarza
Share on other sites

(edytowany)

No można podmieniać zawartość bufora po przesłaniu połowy tablicy, ciekawa właściwość moim zdaniem. W tym przypadku jej nie wykorzystam bo to tylko test ale przyszłościowo widziałbym zastosowania dla takiego dzielenia

Edytowano przez _LM_
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.