Table of Contents

Actividad 6 y 7. STM32 y Arduino: SPI y UART

Temas

Precauciones

Instrucciones generales

  1. Lea completamente todos los pasos de la guía de esta actividad
  2. Anote, responda y agregue al reporte todas las preguntas e instrucciones que se realicen en la guía. Dichas preguntas e instrucciones se pueden denotar al estar enumeradas con el siguiente formato: “1) Anote el puerto asignado a su dispositivo Arduino”
  3. Debe realizar una descripción de lo logrado a lo largo de la actividad, incluyendo las dificultades que se presentaron. Una bitácora de lo sucedido es lo mejor. (Anote no solo lo que usted ejecutó sino también el resultado de lo que ejecuta)
  4. El reporte debe ser entregado mediante correo electrónico al asistente con copia al profesor del curso mediante correo electrónico. Debe utilizar formato PDF.
  5. El correo electrónico del reporte debe llevar el siguiente formato en el “subject”: “IE0624 - Reporte N”, donde N es el número de la actividad realizada.

Evaluación

El reporte debe incluir las siguientes secciones (se incluye el porcentaje de nota de cada sección)

  1. Portada (curso, semestre, año, fecha, número y nombre de práctica, integrantes). 2%
  2. Bitácora de trabajo describiendo el resultado de todos los pasos seguidos de la guía incluyendo dificultades y/o situaciones inesperadas. 30%
  3. Capturas o fotografías de puntos importantes realizadas durante la actividad (el circuito ensamblado, resultados observables en el osciloscopio, etc) 20%
  4. Respuestas al cuestionario de la guía. 20% (deben estar claramente identificadas con el número de pregunta, sin confundirse con otra numeración en el reporte)
  5. Todo el código fuente de todos los programas utilizados a lo largo de la actividad. Debe agregar al inicio del código una descripción sobre dicho código (a qué parte de la práctica corresponde, la función que cumple dicho código). 20%
  6. Referencias utilizadas en caso de acceder a alguna fuente de información de Internet o bibliográfica durante la realización de la actividad. 8%

Guía de laboratorio

Parte 1. Arduino SPI

La libraría integrada de funciones de arduino contiene funciones de conveniencia para la comunicación utilizando el puerto SPI.

Arduino y SPI

  #include <SPI.h>
  #include <avr/pgmspace.h>
 
  const int CSpin = 10;
  const int DCpin = 2;
 
  void setup() {
    Serial.begin(9600);
 
    // start the SPI library:
    SPI.begin();
    SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
    // initalize the  data ready and chip select pins:
    pinMode(CSpin, OUTPUT);
    pinMode(DCpin, OUTPUT);
    digitalWrite(CSpin, HIGH);
    digitalWrite(DCpin, HIGH);
    delay(10);
    sendCmd(0xAF); //Display ON
    delay(10);
    sendCmd(0xA5); //All display ON
    delay(10);
    sendCmd(0x81); //Set contrast
    delay(10);
    sendCmd(0xFF); // Contrast
    delay(10);
    sendCmd(0xA4); //All display from mem
    delay(10);
    sendCmd(0x20); //Horizontal Addressing mode
    delay(100);
    sendCmd(0x00); //Horizontal Addressing mode
    delay(100);
    sendCmd(0x21); //Set col address
    delay(100);
    sendCmd(0x00); //Start col
    delay(100);
    sendCmd(0x7F); //End col
    delay(100);
    sendCmd(0x22); //Set page address
    delay(100);
    sendCmd(0x00); // Page start address
    delay(100);
    sendCmd(0x07); // Page end address
    delay(100);
    sendCmd(0x40); // Set display start line
    delay(100);
    sendCmd(0xA1); // Set segment remap
    delay(100);
    blankScreen();
  }
 
  const PROGMEM uint8_t I[] = { 0b00000000,
                               0b00000000,
                               0b01000010,
                               0b01111110,
                               0b01000010,
                               0b00000000,
                               };
 
  const PROGMEM uint8_t E[] = { 0b00000000,
                               0b01000010,
                               0b01000010,
                               0b01011010,
                               0b01011010,
                               0b01111110,
                               };
 
  const PROGMEM uint8_t space[] = { 0b00000000,
                                   0b00000000,
                                   0b00000000,
                                   0b00000000,
                                   0b00000000,
                                   0b00000000,
                                   };
 
  const PROGMEM uint8_t love[] = { 0b00000000,
                                  0b00111000,
                                  0b01000100,
                                  0b00100010,
                                  0b01000100,
                                  0b00111000,
                                  };
 
  uint8_t temp;
  int col=0;
 
  void printLetter(const uint8_t* letter) {
    for (int i=6; i>=0; i--){
      temp=pgm_read_word_near(letter+i);
      sendData(temp);
      col++;
    }
  }
 
  const uint8_t* letters[]={love, space, E, I, E, space, love, space};
 
  void loop() {
      Serial.print("test\n");
        delay(10);
        //sendData(0b00010001);
        int i=0;
        while (col<(128-6)) {
              printLetter(letters[i]);
              i++;
              if (i>7) {
                 i=0;
              }
        }
        for (int j=0;j<(128-col); j++) {
            sendData(0x00);
        }
        col=0;
  }
 
  void sendData(byte data) {
      digitalWrite(CSpin, LOW);
      digitalWrite(DCpin, HIGH);
      SPI.transfer(data);
      digitalWrite(DCpin, HIGH);
      digitalWrite(CSpin, HIGH);
  }
 
  void sendCmd(byte cmd) {
      digitalWrite(CSpin, LOW);
      digitalWrite(DCpin, LOW);
      SPI.transfer(cmd);
      digitalWrite(DCpin, HIGH);
      digitalWrite(CSpin, HIGH);
  }
 
  void blankScreen() {
     for (int i=0; i<1024; i++){
        //delay(10);
        sendData(0x00);
     }
  }
Arduino OLED
+5V Vcc
GND GND
+5V RES
D13 D0
D11 D1
D10 CS
D2 DC
  sendCmd(0xFF); // Contrast

Así:

  sendCmd(0x7F); // Contrast
            if (i>7) {

Parte 2. STM32 UART

STM32 UMFT234XF
GND GND
PA3 TXD
PA2 RXD
sudo minicom -s

Parte 3. STM32 SPI

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/gpio.h>
 
#define LBLUE GPIOE, GPIO8
#define LRED GPIOE, GPIO9
#define LORANGE GPIOE, GPIO10
#define LGREEN GPIOE, GPIO11
#define LBLUE2 GPIOE, GPIO12
#define LRED2 GPIOE, GPIO13
#define LORANGE2 GPIOE, GPIO14
#define LGREEN2 GPIOE, GPIO15
 
#define LD4 GPIOE, GPIO8
#define LD3 GPIOE, GPIO9
#define LD5 GPIOE, GPIO10
#define LD7 GPIOE, GPIO11
#define LD9 GPIOE, GPIO12
#define LD10 GPIOE, GPIO13
#define LD8 GPIOE, GPIO14
#define LD6 GPIOE, GPIO15
 
#define OLEDCS GPIOA, GPIO8
#define OLEDDC GPIOA, GPIO15
 
static void spi_setup(void)
{
	rcc_periph_clock_enable(RCC_SPI1);
	/* For spi signal pins and OLED chip select */
	rcc_periph_clock_enable(RCC_GPIOA);
	/* For spi mode select on the l3gd20 */
	rcc_periph_clock_enable(RCC_GPIOE);
 
	/* Setup GPIOA8 pin for spi mode OLED select. */
	gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
	/* Setup GPIOA15 pin for OLED command/data signal. */
	gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO15);
	/* Setup GPIOE3 pin for l3gd20 select. */
	gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
	/* Start with OLED spi communication disabled */
	gpio_set(OLEDCS);
	/* Disable l3gd20 select signal. We are not using this IC */
	gpio_set(GPIOE, GPIO3);
 
	/* Setup GPIO pins for AF5 for SPI1 signals. */
	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
			GPIO5 | GPIO6 | GPIO7);
	gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO6 | GPIO7);
 
	//spi initialization;
	spi_set_master_mode(SPI1);
	spi_set_baudrate_prescaler(SPI1, SPI_CR1_BR_FPCLK_DIV_8);
	spi_set_clock_polarity_0(SPI1);
	spi_set_clock_phase_0(SPI1);
	spi_set_full_duplex_mode(SPI1);
	spi_set_unidirectional_mode(SPI1); /* bidirectional but in 3-wire */
	spi_set_data_size(SPI1, SPI_CR2_DS_8BIT);
	spi_enable_software_slave_management(SPI1);
	spi_send_msb_first(SPI1);
	spi_set_nss_high(SPI1);
	//spi_enable_ss_output(SPI1);
	spi_fifo_reception_threshold_8bit(SPI1);
	SPI_I2SCFGR(SPI1) &= ~SPI_I2SCFGR_I2SMOD;
	spi_enable(SPI1);
}
 
static void usart_setup(void)
{
	/* Enable clocks for GPIO port A (for GPIO_USART2_TX) and USART2. */
	rcc_periph_clock_enable(RCC_USART2);
	rcc_periph_clock_enable(RCC_GPIOA);
 
	/* Setup GPIO pin GPIO_USART2_TX/GPIO9 on GPIO port A for transmit. */
	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);
	gpio_set_af(GPIOA, GPIO_AF7, GPIO2| GPIO3);
 
	/* Setup UART parameters. */
	usart_set_baudrate(USART2, 115200);
	usart_set_databits(USART2, 8);
	usart_set_stopbits(USART2, USART_STOPBITS_1);
	usart_set_mode(USART2, USART_MODE_TX_RX);
	usart_set_parity(USART2, USART_PARITY_NONE);
	usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
 
	/* Finally enable the USART. */
	usart_enable(USART2);
}
 
static void gpio_setup(void)
{
	rcc_periph_clock_enable(RCC_GPIOE);
	gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
		GPIO8 | GPIO9 | GPIO10 | GPIO11 | GPIO12 | GPIO13 |
		GPIO14 | GPIO15);
}
 
static void my_usart_print_int(uint32_t usart, int32_t value)
{
	int8_t i;
	int8_t nr_digits = 0;
	char buffer[25];
 
	if (value < 0) {
		usart_send_blocking(usart, '-');
		value = value * -1;
	}
 
	if (value == 0) {
		usart_send_blocking(usart, '0');
	}
 
	while (value > 0) {
		buffer[nr_digits++] = "0123456789"[value % 10];
		value /= 10;
	}
 
	for (i = nr_digits-1; i >= 0; i--) {
		usart_send_blocking(usart, buffer[i]);
	}
 
	usart_send_blocking(usart, '\r');
	usart_send_blocking(usart, '\n');
}
 
static void clock_setup(void)
{
	rcc_clock_setup_hsi(&rcc_hsi_8mhz[RCC_CLOCK_64MHZ]);
}
 
static void delay(int t) {
  for (int i = 0; i < 10000*t; i++) /* Wait a bit. */
    __asm__("nop");
}
 
 
static void sendData(int8_t data) {
      gpio_clear(OLEDCS);
      gpio_set(OLEDDC);
      spi_send8(SPI1, data);
      spi_read8(SPI1);
      gpio_set(OLEDDC);
      gpio_set(OLEDCS);
 }
 
static void sendCmd(int8_t cmd) {
      gpio_clear(OLEDCS);
      gpio_clear(OLEDDC);
      spi_send8(SPI1, cmd);
      spi_read8(SPI1);
      gpio_set(OLEDDC);
      gpio_set(OLEDCS);
 }
 
static void blankScreen(void) {
     for (int i=0; i<1024; i++){
        sendData(0x00);
     }
}
 
static void oled_setup(void)
{
  gpio_set(OLEDCS);
  gpio_set(OLEDDC);
  delay(10);
  sendCmd(0xAF); //Display ON
  delay(10);
  sendCmd(0xA5); //All display ON
  delay(1000);
  sendCmd(0x81); //Set contrast
  delay(10);
  sendCmd(0xFF); // Contrast
  delay(10);
  sendCmd(0xA4); //All display from mem
  delay(10);
  sendCmd(0x20); //Horizontal Addressing mode
  delay(100);
  sendCmd(0x00); //Horizontal Addressing mode
  delay(100);
  sendCmd(0x21); //Set col address
  delay(100);
  sendCmd(0x00); //Start col
  delay(100);
  sendCmd(0x7F); //End col
  delay(100);
  sendCmd(0x22); //Set page address
  delay(100);
  sendCmd(0x00); // Page start address
  delay(100);
  sendCmd(0x07); // Page end address
  delay(100);
  sendCmd(0x40); // Set display start line
  delay(100);
  sendCmd(0xA1); // Set segment remap
  delay(100);
  blankScreen();
}
 
const uint8_t I[] = { 0b00000000,
                      0b00000000,
                      0b01000010,
                      0b01111110,
                      0b01000010,
                      0b00000000,
};
 
const uint8_t E[] = { 0b00000000,
                      0b01000010,
                      0b01000010,
                      0b01011010,
                      0b01011010,
                      0b01111110,
};
 
 
const uint8_t space[] = { 0b00000000,
                          0b00000000,
                          0b00000000,
                          0b00000000,
                          0b00000000,
                          0b00000000,
};
 
 
const uint8_t love[] = { 0b00000000,
                         0b00111000,
                         0b01000100,
                         0b00100010,
                         0b01000100,
                         0b00111000,
};
 
uint8_t temp;
int col=0;
 
void printLetter(const uint8_t* letter) {
  for (int i=6; i>=0; i--){
    temp=*(letter+i);
    sendData(temp);
    col++;
  }
}
 
const uint8_t* letters[]={space, love, space, E, I, E, space, love};
 
int main(void)
{
  uint8_t temp;
  uint16_t data_in;
  clock_setup();
  gpio_setup();
  usart_setup();
  spi_setup();
  oled_setup();
 
  while (1) {
    int j=0;
    while (col<(128-6)) {
      printLetter(letters[j]);
      j++;
      if (j>7) {
        j=0;
      }
    }
    for (int j=0;j<(128-col); j++) {
      sendData(0x00);
    }
    col=0;
    data_in=usart_recv_blocking(USART2);
    usart_send_blocking(USART2, data_in);
  }
}
STM32 OLED
+5V Vcc
GND GND
+5V RES
PA5 D0
PA7 D1
PA8 CS
PA15 DC

Referencias

http://libopencm3.org/

https://github.com/libopencm3/libopencm3/wiki/Datasheets

https://github.com/libopencm3/libopencm3-examples

Hoja de fabricante SSD1780

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

https://www.arduino.cc/en/Reference/SPI