User Tools

Site Tools


Writing /var/lib/dokuwiki/data/meta/teaching/ie0624/actividad_stm32_arduino_spi.meta failed
teaching:ie0624:actividad_stm32_arduino_spi

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
teaching:ie0624:actividad_stm32_arduino_spi [2017/07/05 13:53] adminteaching:ie0624:actividad_stm32_arduino_spi [2022/09/20 00:08] (current) – external edit 127.0.0.1
Line 36: Line 36:
  
 La libraría integrada de funciones de arduino contiene funciones de conveniencia para la comunicación utilizando el puerto SPI. La libraría integrada de funciones de arduino contiene funciones de conveniencia para la comunicación utilizando el puerto SPI.
- 
-Los pasos de las primeras actividades del curso hicieron uso del programa arduino que es parte de los repositorios oficiales de la distribución de Linux: Debian GNU/Linux. El problema es que la versión que se encuentra en el repositorio de Debian es muy antigua (versión 1.0.5) la cual contiene funciones para utilizar el puerto SPI obsoletas. 
- 
-Necesitamos instalar una versión más actualizada de Arduino. Por ejemplo, la versión 1.8.3. Pero primero es recomendable actualizar el sistema operativo Debian a su última versión Debian Unstable para evitar posibles problemas de incompatibilidad de librerías con Arduino. 
- 
-=== Actualización de la distribución de Linux Debian a la última versión de Debian Unstable === 
- 
-  * Siga la guía para la "Actualización al sistema debian unstable (sid)" disponible [[teaching:ie0117:experimento_1|aquí]]. Solo debe seguir la sección para actualizar a debian unstable. 
- 
-=== Instalación de nueva versión de Arduino === 
- 
-  * Descargue la última versión de Arduino (para Linux de 64bits) desde aquí: [[https://www.arduino.cc/en/Main/Software]] 
-  * Descargue el archivo en el directorio "~/local/src" 
-  * Descomprima dicho archivo: 
- 
-  cd ~/local/src 
-  tar -xzf arduino-1.8.3-linux64.tar.xz 
- 
-  * Para ejecutar arduino, siempre desde una nueva consola, debe realizar los siguientes pasos: 
- 
-  cd ~/local/src/arduino-1.8.3/ 
-  ./arduino 
- 
-  * Si no lo realiza de esta forma estará ejecutando el arduino antiguo. Siempre corrobore la versión que se encuentra ejecutando observando la barra superior de la aplicación gráfica de arduino. 
  
 === Arduino y SPI === === Arduino y SPI ===
Line 65: Line 41:
   * Programe y cargue el siguiente programa en el Arduino:   * Programe y cargue el siguiente programa en el Arduino:
  
 +<code C>
   #include <SPI.h>   #include <SPI.h>
   #include <avr/pgmspace.h>   #include <avr/pgmspace.h>
Line 201: Line 178:
      }      }
   }   }
 +</code>
  
   * Apague el arduino   * Apague el arduino
   * Utilizando una la protoboard conecte el arduino y el módulo OLED de la siguiente manera:   * Utilizando una la protoboard conecte el arduino y el módulo OLED de la siguiente manera:
  
-^ Arduino ^ OLED+^ Arduino ^ OLED ^
 | +5V | Vcc | | +5V | Vcc |
 | GND | GND | | GND | GND |
Line 214: Line 192:
 | D2  | DC  | | D2  | DC  |
  
 +
 +  * Encienda el Arduino y compruebe que la pantalla OLED despliega "<3 EIE <3 <3 EIE <3 <3 "
 +  * Modifique el programa para desplegar el siguiente texto: "Lu RZ " (Labo micros Rulez). **1) Mencione las modificaciones realizadas al programa para lograr esto.**
 +  * Modifique la línea:
 +
 +    sendCmd(0xFF); // Contrast
 +
 +Así:
 +
 +    sendCmd(0x7F); // Contrast
 +
 +  * **2) Describa lo que sucede**
 +  * **3) Qué indica el número "7" de la línea: ?**
 +
 +              if (i>7) {
 +
 +  * **4) Para qué sirve la función pgm_read_word_near() ?**
 +  * **5) En qué tipo de memoria del microprocesador Arduino se están almacenando los "pixeles" de las letras o símbolos?**
 +  * **6) Cuál es la resolución en pixeles de cada símbolo gráfico en este programa?** 
 +  * **7) Explique la función de cada pin (desde la perspectiva del puerto de comunicación SPI) que está siendo conectado entre el Arduino y el OLED.**
  
 ==== Parte 2. STM32 UART ==== ==== Parte 2. STM32 UART ====
  
-TBA+  * En el repositorio que en la práctica anterior usted descargó (libopencm3-examples) diríjase al ejemplo adc (para stm32f3discovery). Compile y cargue dicho ejemplo en el STM32. Todavía no conecte el STM32 a la protoboard. 
 +  * Apague el STM32. 
 +  * Alambre una resistencia variable de la siguiente forma: 
 + 
 +{{:teaching:ie0624:pot.png?200|}} 
 + 
 +  * Solde "pines" en las señales GND, TXD y RXD del módulo UMFT234XF de tal forma que lo pueda utilizar en la protoboard. 
 +  * Solde o "cierre" el jumper "JP1" del UMFT234XF. **8) Cuál es la función de este jumper?**  
 +  * Interconecte el módulo UMFT234XF con el STM32 de la siguiente manera: 
 + 
 +^ STM32 ^ UMFT234XF ^ 
 +| GND | GND | 
 +| PA3 | TXD | 
 +| PA2 | RXD | 
 + 
 +  * Conecte el cable microusb del UMFT234XF a la PC 
 +  * Ejecute: 
 + 
 +  sudo minicom -s 
 + 
 +  * Configure el puerto serial de tal forma que utilice el puerto correspondiente del módulo UMFT234XF (/dev/ttyUSB0 típicamente) 
 +  * Configure la velocidad del puerto en minicom para que coincida con la del programa ejemplo adc.c 
 +  * Encienda el STM32 
 +  * Compruebe que está recibiendo datos en minicom. Varíe el potenciómetro de arriba. **9) Qué datos recibe en la pantalla de mínicom? 10) Cómo se relacionan estos datos con la variación del potenciómetro?**
  
 ==== Parte 3. STM32 SPI ==== ==== Parte 3. STM32 SPI ====
  
-TBA+  * Desconecte el circuito del potenciómetro de la parte anterior. 
 +  * Utilizando el mismo repositorio de ejemplos del STM32 (libopencm3-examples), compile y cargue el programa ejemplo "spi" 
 +  * Utilice nuevamente minicom para observar los datos transmitidos por el stm32. 
 +  * **11) Qué datos observa en minicom? 12) Cuál sensor está enviando datos (debe mencionar el número de fabricante)?** (lea con detenimiento el código del ejemplo) **13) Qué función tiene dicho sensor?** 
 +  * Apague el STM32 y desconecte el usb del umft234xf. 
 +  * Sustituya el código de spi.c por el siguiente código: 
 + 
 +<code C> 
 +#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); 
 +  } 
 +
 +</code> 
 + 
 +  * Compile y cargue dicho código en el STM32 (antes desconecte todo) 
 +  * Apague el STM32. 
 +  * Alambre el stm32 con la pantalla OLED de la siguiente manera (no retire el UMFT234XF del circuito): 
 + 
 +^ STM32 ^ OLED ^ 
 +| +5V | Vcc | 
 +| GND | GND | 
 +| +5V | RES | 
 +| PA5 | D0  | 
 +| PA7 | D1  | 
 +| PA8 | CS  | 
 +| PA15| DC  | 
 + 
 +  * En su pantalla debería aparecer "EIE" entre corazones en la línea de abajo. 
 +  * En minicom presione teclas. Asegúrese que las letras presionadas aparecen en la pantalla de la computadora (en minicom). El programa anterior está realizando un "eco" de lo que se envía hacia el microcontrolador. Al mismo tiempo deberían aparecer nuevas líneas de "EIE" entre corazones. 
 +  * **14) Mida y anote el periodo y la frecuencia de la señal de reloj del SPI.** (D0 en el OLED) 
 +  * **15) Escriba la fórmula para calcular la frecuencia del punto anterior basado en los registros del microcontrolador y la frecuencia sysclk del stm32.** 
 +  * **16) En qué modo de comunicación se encuentra configurado el módulo OLED (utilice la hoja de fabricante SSD1780).** 
 +  * **17) Capture una transferencia de información SPI con el osciloscopio. Debe mostrar en el canal A la señal de reloj y en el canal B la señal de datos SPI.** 
 +  * Modifique el programa anterior para recibir las letras vocales "a, e, i, o, u" y espacio desde la PC (minicom) y desplegarlas a la largo de la última línea del módulo OLED. Incluya una fotografía del OLED mostrando la secuencia de letras: "E A I AEIE"
  
 ===== Referencias ===== ===== Referencias =====
Line 231: Line 554:
  
 https://github.com/libopencm3/libopencm3-examples 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
 +
  
teaching/ie0624/actividad_stm32_arduino_spi.1499262817.txt.gz · Last modified: 2022/09/20 00:08 (external edit)