CHIP KIDD

[ARM] 엘레베이터 프로젝트 - SPI 통신을 이용한 OLED 구현 본문

전기전자/ARM

[ARM] 엘레베이터 프로젝트 - SPI 통신을 이용한 OLED 구현

쑨야미 2021. 3. 18. 20:21

 

UART I2C SPI
1:1  1:N 1:N
비동기 동기 동기
  slave device 주소 chip select (pin 개수 증가 단점)
  slow fast
통신 단순 복잡 단순

동기 vs 비동기

기준신호 : Clock

Clock을 생성하는 것 : Master / Clock을 받는 것 : Slave

→ Clock을 기준으로 동작 하는 것 : 동기

 

SPI 동작 구조

SPI 동작 구조

※ MOSI : Master Out Slave In  → Write

   MISO : Master In Slave Out  → Read

 

특징

  • Bit 단위 신호로 데이터 전송
  • SCLK (동기신호)에 맞춰 Write 하고 Read 함
    • CPOL (0) : 시작위치 HIGH         (1) : 시작위치 LOW
    • CPHA (0) : 첫번째 Edge에서 동기화        (1) : 두번쨰 Edge에서 동기화

#include <stdio.h>
#include "../ssd1306/ssd1306.h"
#include "../ssd1306/ssd1306_tests.h"
#include "../ssd1306/bitmap.h"

#include <stdbool.h>
#include <math.h>

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int centerX, centerY;
centerX = SSD1306_WIDTH/2;
centerY = SSD1306_HEIGHT/2;

void drawSec(int sec)
{
	float x2, y2;
	x2 = (centerY-10) * sin(sec * 6 * 0.0175);
	y2 = (centerY-10) * cos(sec * 6 * 0.0175);
	ssd1306_Line(centerX+35, centerY-6, (centerX+35) + x2, (centerY-6) - y2,White);
}

void drawMin(int min)
{
	float x2, y2;
	x2 = (centerY-15) * sin(min * 6 * 0.0175);
	y2 = (centerY-15) * cos(min * 6 * 0.0175);
	ssd1306_Line(centerX+35, centerY-6, (centerX+35) + x2, (centerY-6) - y2,White);
}
void drawHour(int hour, int min)
{
	float x2, y2;
	hour = (hour *30) + (min*0.5);
	x2 = (centerY-20) * sin(hour * 6 * 0.0175);
	y2 = (centerY-20) * cos(hour * 6 * 0.0175);
	ssd1306_Line(centerX+35, centerY-6, (centerX+35) + x2, (centerY-6) - y2,White);

}

void drawClock(int hour, int min, int sec)
{
	ssd1306_DrawCircle(centerX+35, centerY-6, centerY-7, White);
	drawSec(sec);
	drawMin(min);
	drawHour(hour, min);
}
/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_SPI1_Init();
	/* USER CODE BEGIN 2 */
	ssd1306_Init();
	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	char strBuff[50];
	//int count = 0;
	int sec, min, hour = 0;


	while (1)
	{
		ssd1306_Fill(Black);
		drawClock(hour,min,sec);

		ssd1306_SetCursor(72,54);
		sprintf(strBuff, "%02d:%02d:%02d", hour, min, sec);
		ssd1306_WriteString(strBuff, Font_7x10, White);

		ssd1306_SetCursor(12,2);
		sprintf(strBuff, "X F");
		ssd1306_WriteString(strBuff, Font_11x18, White);
		ssd1306_UpdateScreen();
		sec++;
		if(sec >= 60){
			sec = 0;
			min++;
			if(min >= 60){
				min=0;
				hour++;
				if(hour>=24){
					hour =0;
				}
			}
		}
		HAL_Delay(50);