Autor Tema: ATtiny2313 SPI por software  (Leído 4380 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
ATtiny2313 SPI por software
« en: 06 de Octubre de 2010, 12:37:55 »
Hola, tratando de encontrar información sobre como implementar el bus SPI en micros AVR encontré mucha información interesante y muy documentada con librerías dedicadas y demás. Ahora las implementaciones que he encontrado son solo para micros con módulo SPI integrado, mirando la hoja de datos del ATtiny2313 me he encontrado que no tiene módulo SPI dedicado sino que lo implementa en la USI (Universal Serial Interface).

Alguien del foro ha implementado el bus SPI por software o tiene alguna nota de aplicación de como podría realizarse ??

Estoy programando en AVR GCC   

Saludos  :-/

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: ATtiny2313 SPI por software
« Respuesta #1 en: 06 de Octubre de 2010, 13:16:05 »
Que modo de SPI deseas implementar? Sabiendo eso, sabrás cual será el estado de la linea SCK, cuando cambiar el estado del bit de salida y cuando leer el bit de entrada. Con eso, hacer la rutina parece sencillo  :?


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: ATtiny2313 SPI por software
« Respuesta #2 en: 06 de Octubre de 2010, 22:29:08 »
Hola Suky como estás.

La rutina para SPI ya la tengo , lo que pasa es que tengo que depurar algunos puntos por que no me está funcionando  :?

Lo que pasa es que el micro que estoy usando tiene el puerto SPI sobre las líneas de ISP del micro, con lo cuál se me está presentando algunas complicaciones de hardware.

Si querés ver la rutina:
Código: C
  1. /*****************************************************************
  2.    Fecha: Setiembre del 2010.
  3.    Programa: Setea un valor en un potenciómetro digital MCP41010.
  4.    Cristal:  4Mhz.
  5.    Programador: PK2-ISP.
  6.  *****************************************************************/
  7. #include <avr/io.h>     // Definiciones de hardware.
  8.  
  9. // Declaramos funciones utilizadas.
  10. void    spi_init(uint8_t velocidad);  // Inicia el bus SPI y setea velocidad de trabajo.  
  11. uint8_t spi_write(uint8_t dato);      // Escribe un dato en el bus SPI.
  12.  
  13. // Definimos los pines para la comunicación SPI.
  14. #define SDI PINB5  // Pin B5 como MOSI.
  15. #define SDO PINB6  // Pin B4 como MISO.
  16. #define SCK PINB7  // Pin B7 como SCK.
  17.  
  18. void spi_init(uint8_t velocidad) {
  19.  
  20.  if (velocidad==1) { // Si velocidad = 1, la velocidad del bus es máxima.
  21.         PORTB |= (1<<SDO)|(1<<PINB4);      
  22.         DDRB = (1<<SCK)|(1<<SDI)|(1<<PINB4);
  23.         USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK);
  24.         PORTB &= ~(1<<PINB4);    // Habilitamos esclavo.
  25.     } else { // Si velocidad es 0....
  26.         PORTB |= (1<<PINB4);     // Deshabilitamos esclavo.
  27.         DDRB &= ~((1<<SCK)|(1<<SDO)|(1<<SDI)|(1<<PINB4));
  28.         USICR = 0;
  29.     }
  30. }
  31.  
  32. uint8_t spi_write(uint8_t dato) {
  33.  
  34.  USIDR = dato; // Carga el dato a enviar.
  35.     USISR = (1<<USIOIF);
  36.     do {
  37.         USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC); // Configuramos la USI.
  38.     } while ((USISR & (1<<USIOIF)) == 0); // En caso de que termine de enviar el dato, retorna el valor
  39.                                                 // De USIDR.
  40.     return USIDR;      
  41. }
  42.  
  43.  
  44. int main(void) {
  45.  
  46.  DDRB = 0x07; // PB0--PB3 como salidas.
  47.  PORTB = 0x00; // Limpiamos el puerto B.
  48.  
  49.   while(1) {
  50.  
  51.     spi_init(1);     // Iniciamos las comunicaciones con el esclavo MCP41010.
  52.          spi_write(0x11); // Cargamos byte de comando.
  53.       if(spi_write(0x11)==1) { // Si todavía no termina de mandar el dato..
  54.             PORTB = 0x01; // Espera a mandarlo....
  55.                 }
  56.          else
  57.           spi_write(0x80); // Seteamos valor del potenciómetro digital.
  58.             if(spi_write(0x11)==1) { // Si todavía no termina de mandar el dato..
  59.             PORTB = 0x01; // Espera a mandarlo....
  60.                 }
  61.          else
  62.           spi_init(0); // Apagamos el potenciometro.
  63.          }
  64.        
  65.         }

El spi está implementado por software usando la USI del ATtiny2313. Estoy leyendo la aplicación AVR319 que muestra un ejemplo de lo mismo que estoy haciendo yo pero para el micro ATmega169...la diferencia es que este micro los pines del módulo SPI están separados de los pines de programación...

De a poco lo voy sacando...espero que para mañana o pasado tenga algo funcionando.

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: ATtiny2313 SPI por software
« Respuesta #3 en: 06 de Octubre de 2010, 23:35:16 »
Suky respondiendo a tus preguntas de manera más concisa, el modo de SPI que implemento es el 0. Usando el módulo USI del ATtiny2313 los modos posible son el 0 y el 1.

Saludos y que andes bien !

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: ATtiny2313 SPI por software
« Respuesta #4 en: 08 de Octubre de 2010, 12:55:42 »
Bueno luego de correjir algunas cosas acá les dejo mi código funcionando:
Código: C
  1. /*****************************************************************
  2.    Fecha: Setiembre del 2010.
  3.    Programa: Setea un valor en un potenciómetro digital MCP41010.
  4.    Cristal:  4Mhz.
  5.    Programador: PK2-ISP.
  6.  *****************************************************************/
  7. #include <avr/io.h>     // Definiciones de hardware.
  8. #include <util/delay.h>
  9.  
  10. // Declaramos funciones utilizadas.
  11. void    spi_init(uint8_t velocidad);  // Inicia el bus SPI y setea velocidad de trabajo.
  12. uint8_t spi_write(uint8_t dato);      // Escribe un dato en el bus SPI.
  13.  
  14. // Definimos los pines para la comunicación SPI.
  15. #define SDI PINB6  // Pin B5 como MOSI.
  16. #define SDO PINB5  // Pin B4 como MISO.
  17. #define SCK PINB7  // Pin B7 como SCK.
  18.  
  19. void spi_init(uint8_t velocidad) {
  20.  
  21.  if (velocidad==1) { // Si velocidad = 1, la velocidad del bus es máxima.
  22.         PORTB |= (1<<SDO)|(1<<PINB4);      
  23.         DDRB = (1<<SCK)|(1<<SDI)|(1<<PINB4);
  24.         USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK);
  25.         PORTB &= ~(1<<PINB4);    // Habilitamos esclavo.
  26.     } else { // Si velocidad es 0....
  27.         PORTB |= (1<<PINB4);     // Deshabilitamos esclavo.
  28.         DDRB &= ~((1<<SCK)|(1<<SDO)|(1<<SDI)|(1<<PINB4));
  29.         USICR = 0;
  30.     }
  31. }
  32.  
  33. uint8_t spi_write(uint8_t dato) {
  34.  
  35.  USIDR = dato; // Carga el dato a enviar.
  36.     USISR = (1<<USIOIF);
  37.     do {
  38.         USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC); // Configuramos la USI.
  39.     } while ((USISR & (1<<USIOIF)) == 0); // En caso de que termine de enviar el dato, retorna el valor
  40.                                            // De USIDR.
  41.     return USIDR;    
  42. }
  43.  
  44.  
  45. int main(void) {
  46.  
  47.  DDRB = 0x07; // PB0--PB3 como salidas.
  48.  PORTB = 0x00; // Limpiamos el puerto B.
  49.  
  50.  
  51.  
  52.     spi_init(1);     // Iniciamos las comunicaciones con el esclavo MCP41010.
  53.     spi_write(0x11); // Cargamos byte de comando.
  54.      
  55.      spi_write(0x45); // Seteamos valor del potenciómetro digital.
  56.      
  57.         _delay_ms(3000);
  58.      spi_init(0); // Apagamos el potenciometro.
  59.    
  60.    }

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: ATtiny2313 SPI por software
« Respuesta #5 en: 08 de Octubre de 2010, 13:25:27 »
Ups! Se me paso el tema  :oops: Me alegro que ya funcione.

Una consulta respecto al compilador, los 1<<USIWM0,  .... ect, realiza las rotaciones y luego el Or lógico, o lo interpreta directamente? Yo, lo poco que hice en AVR (Lo básico, LCD, GLCD, UART...), fue en CodeVisionAVR  :mrgreen:


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado jonathanPIC888

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: ATtiny2313 SPI por software
« Respuesta #6 en: 08 de Octubre de 2010, 13:58:05 »
Ahi hace la interpretación directa , es más es la forma más eficiente según el manual del WinAVR. Yo hace poco empecé con esto de los micros AVR pero la idea es aprender C y hacer cosas más interesantes. :-/

También lo podés hacer de esta manera:
Código: C
  1. USIWM0|= 0x01

Yo probé hacerlo de las 2 maneras ahora en el compilador y me dá el mismo tamaño de rom consumido  ;-)

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: ATtiny2313 SPI por software
« Respuesta #7 en: 08 de Octubre de 2010, 14:13:18 »
Muchas gracias jonathan!


Saludos!
No contesto mensajes privados, las consultas en el foro