TODOPIC
Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: bitpic en 30 de Mayo de 2013, 16:31:14
-
Hola foreros,
Soy novato con esto de los STM32 y despues de probar y entender (o eso creo) como funcionan los I/O simples, ahora quería pasar a probar y comprender como controlar el SPI.
Tengo una tarjeta con un STM32F103RC el cual tiene conectado al bus SPI1 un MC33972, el cual permite gobernar entradas y salidas. Este MC33972 tiene conectados a su salidas SGx unos mosfet que a su vez controlan unos relés.
(http://imageshack.us/a/img832/5317/sinttulosyr.png)
No consigo hacer funcionar estos reles y sospecho de que no estoy enviando bien los comandos del MC33972. Estos comandos son de 24 bits y el SPI puedes configurarlo para enviar datos de 8 o 16 bits. Yo lo que hago es enviar 3 datos de 8 bits
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"
void Comando_SPI(char a, char b, char c);
int main(void)
{
int i;
/* Initialize Leds mounted on STM32 board */
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Enable peripheral clocks ----------------------------------------------*/
/* GPIOA, GPIOB and SPI1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1, ENABLE);
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure the SPI_CS pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure SPI1 pins: SCK, MISO and MOSI -------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI1 Configuration ----------------------------------------------------*/
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
/* Pulso para pasar a modo normal */
GPIO_SetBits(GPIOA,GPIO_Pin_4); // pin SPI_CS
for(i=0;i<0x100000;i++);
/* Send wetting current timer command SG disabled */
Comando_SPI(0b00001000,0b00000000,0b00000000);
/* Send metallic command –Set SGn to 16mA. */
Comando_SPI(0b00000101,0b11111111,0b11111111);
while (1)
{
GPIO_SetBits(GPIOB,GPIO_Pin_11); // pin LED
/* Send tri-state command SG ON */
Comando_SPI(0b00001010,0b11111111,0b11111111);
/* delay */
for(i=0;i<0x300000;i++);
GPIO_ResetBits(GPIOB,GPIO_Pin_11); // pin LED
/* Send tri-state command SG ON */
Comando_SPI(0b00001010,0b00000000,0b00000000);
/* delay */
for(i=0;i<0x300000;i++);
}
}
void Comando_SPI(char a, char b, char c){
int j;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY));
GPIO_ResetBits(GPIOA,GPIO_Pin_4); // pin SPI_CS LOW
for(j=0;j<0x1000;j++);
SPI_I2S_SendData(SPI1, a);
SPI_I2S_SendData(SPI1, b);
SPI_I2S_SendData(SPI1, c);
GPIO_SetBits(GPIOA,GPIO_Pin_4); // pin SPI_CS HIGH
}
La tarjeta funciona correctamente, venia con un programa precargado que hacia funcionar todo.
¿Alguien puede echarme una mano a encontrar que hago mal? :?
EDITO: He corregido algunas cosas del programa, pero continua sin funcionar
-
Parece que te salteaste de tema antes de llegar a los micro-controladores tendrías que saber cómo controlar los mosfet.
Ese divisor resistivo de R45, R46 de 10K es mucho para los 3.6Vdc máximo que puede salir del pin eso según la fuente de alimentación, seria 1.8V para activar el Mosfet no da para nada.
Prueba con R45 100 Ohm.
-
Hola Cristian,
El circuito no lo he diseñado yo, la tarjeta es así. Y la empresa que la diseño es de fiar.
Como decía anteriormente, la tarjeta funciona correctamente. El programa que venía en ella estaba funcionando sin ningún problema. Es más he visto muchas de estas tarjetas funcionar durante mucho tiempo y no suelen dar problemas.
El problema que tengo es del micro. No se si es que estoy configurando mal el SPI, o que estoy enviando mal la configuración del MC33972 o que tal y como tengo el programa no envía correctamente los comandos por el SPI.
En cualquiera de los tres casos el problema es mio que soy un novato con estos micros, pero la tarjeta funciona correctamente, es de lo único que estoy seguro.
Otra cosa que no se ve, es que el MC33972 se alimenta por un lado a 3.3V la parte de control y por otro 24V la parte de las I/O. Perdonad que no ponga el esquema completo pero no puedo, digamos que estoy haciendo un poco de ingeniería inversa y no me quiero meter en un lio.... jejej :D (Vamos que el diseño de la placa no es mio y no me gustaría que me llamarán la atención por algún motivo)
(http://imageshack.us/a/img526/2416/sinttuloqbf.png)
-
¿ Seguro que el chip es un MC33972A de Freescale ?
Según el datasheet, ese chip SOLO tiene entradas, no salidas.
Multiple Switch Detection Interface with Suppressed Wake-up
The 33972 Multiple Switch Detection Interface with suppressed wake-up is designed to detect the closing and opening of up to 22 switch contacts. The switch status, either open or closed, is transferred to the microprocessor unit (MCU) through a serial peripheral interface (SPI). The device also features a 22-to-1 analog multiplexer for reading inputs as analog. The analog input signal is buffered and provided on the AMUX output pin for the MCU to read.
Features
Designed to operate 5.5V ≤ VPWR ≤ 26V
Switch input voltage range -14V to VPWR, 40V Max
Interfaces directly to MPU using 3.3V / 5.0V SPI protocol
Selectable wake-up on change of state
Selectable wetting current (16mA or 2.0mA)
8 programmable inputs (switches to battery or ground)
14 switch-to-ground inputs
Typical standby current - VPWR = 100µA and VDD
(http://cache.freescale.com/files/graphic/block_diagram/MC33972BD.gif)
-
Si, estoy seguro.
Ya se que es curioso esta manera de hacerlo, pero si te fijas hay un punto del datasheet "MOSFET or LED Driver Output" que explica como activar LEDs y Mosfets. Dice que puedes hacerlo activando y descativando el modo tri-state.
-
Una duda:
Los comandos del MC33972A son de 24 bits. Si no me equivoco el SPI del STM32 lo puedes configurar como 8 bits o como 16 bits.
Lo que hago yo es configurar el SPI del micro como 8bits y hago lo siguiente:
// Configuración PIN CS
#define NSS_HIGH GPIO_SetBits(GPIOB,GPIO_Pin_4);
#define NSS_LOW GPIO_ResetBits(GPIOB,GPIO_Pin_4);
NSS_LOW; /* CS nivel low para activar SPI */
SPI_I2S_SendData(SPI1,data1);
SPI_I2S_SendData(SPI1,data2);
SPI_I2S_SendData(SPI1,data3);
NSS_HIGH; /* CS nivel high para activar SPI */
¿Esto me enviaría un dato de 24bits o me equivoco?
Creo que esto va a ser la escusa para comprarme un osciloscopio, porque no hay manera de saber si me esta funcionando la señal del SPI o no...
-
:shock: Interesante integrado este .......en la pag 23 del datasheet se ve el método driver del mosfet
Acá en argentina solo queda soñar con estos dispositivos :embarrassed:
-
Creo que esto va a ser la escusa para comprarme un osciloscopio, porque no hay manera de saber si me esta funcionando la señal del SPI o no...
Mucho mejor y más útil, un analizador lógico, para comprobar señales digitales.
Sobre el software para el STM32, no te puedo ayudar, todavía no me he metido con los ARM, pero estoy a punto de pedirme la Discovery y la Beagleboard Black.
¿ has metido el tester en los puertos SGx, a ver si se activan las resistencias de pull-up internas ?.
-
El modo de mandar los 24bits si la función "SPI_I2S_SendData(SPI1,data )" manda 8 bits en tres datos consecutivos si funciona. El modo SPI parece modo 0, tendría que leer el pdf del MC33972A para saber en qué modo recibe los datos.
-
:shock: Interesante integrado este .......en la pag 23 del datasheet se ve el método driver del mosfet
Acá en argentina solo queda soñar con estos dispositivos :embarrassed:
Pues si manutek, es interesante, pero no consigo controlarlo :?
Creo que esto va a ser la escusa para comprarme un osciloscopio, porque no hay manera de saber si me esta funcionando la señal del SPI o no...
Mucho mejor y más útil, un analizador lógico, para comprobar señales digitales.
Sobre el software para el STM32, no te puedo ayudar, todavía no me he metido con los ARM, pero estoy a punto de pedirme la Discovery y la Beagleboard Black.
¿ has metido el tester en los puertos SGx, a ver si se activan las resistencias de pull-up internas ?.
Planeta9999 habia pensado comprarme este http://www.satkit.com/b2c/index.php?page=pp_producto.php&md=0&ref=5125, ¿como lo veis? mirare lo del analizador logico a ver que me interesa más, creo que con el osciloscopio tendre más opciones de medida...
Yo tengo una Discovery también, de echo empece con esa tarjeta, pero quise aprovechar que tenía esta para aprender a usarla. Pero no he pasado de las entradas y salidas digitales jejejeje a sido pasar al SPI y encallaarme. Voy a tener que volver a la Discovery e ir paso a paso...
El modo de mandar los 24bits si la función "SPI_I2S_SendData(SPI1,data )" manda 8 bits en tres datos consecutivos si funciona. El modo SPI parece modo 0, tendría que leer el pdf del MC33972A para saber en qué modo recibe los datos.
Cristian_elect ¿a que te refieres con modo 0? la configuración que tengo del SPI ahora la tengo así:
void SPI_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure the SPI_CS pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure SPI1 pins: SCK, MISO and MOSI -------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI1 Configuration ----------------------------------------------------*/
auto SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; /* 4MHz CLK */
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 NSS output for master mode */
SPI_SSOutputCmd(SPI1, ENABLE);
/* NSS a nivel alto por defecto */
NSS_HIGH;
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
(http://imageshack.us/a/img845/3395/sinttulocmx.png)
-
Ese integrado lo estoy usando yo, pero como detector de switchs no como activador de mosfets xD
Has probado a ver que responde el SPI? Puede que el problema sea del modo del spi que no estes poniendo el correcto, a veces pasa esto y te vuelves loco buscando el problema.
Aqui tienes una pagina con toda la informacion:
http://www.gammon.com.au/forum/?id=10892
Vete al apartado "Modes"
-
Viendo el programa y revisando algunos foros esta SPI modo 1. Y de eso de configuracion de SPI de STM32F si esta disponible en la red.
-
Corregidme si me equivoco, pero tal y como tengo la configuración del SPI es Modo 1
(http://imageshack.us/a/img841/6979/sinttulodlw.png)
Y por el datasheet del MC33972A entiendo que es el correcto ¿no?
(http://imageshack.us/a/img845/3395/sinttulocmx.png)
MerLiNz, ahora mismo no tengo ni osciloscopio ni analizador lógico. Lo tengo un poco difícil para ver que esta ocurriendo en la señal...
-
Hay parece que funciona en modo 0 y modo 2.
-
Hay parece que funciona en modo 0 y modo 2.
A mi me parece que es Modo 1. Si te fijas, el Modo 0 valida el bit en el flanco ascendente de clock y el modo 2 el MOSI en modo idle es High.
Me da la sensación que hay algo que hago mal y que no llego a activar el SPI (a ver si puedo hacerme con un analizador logico o un osciloscopio lo antes posible, igual la semana que viene me compro uno que ya toca) lo digo porque he querido hacer una prueba con el USART. Esta placa lleva dos puertos RS485 y tengo un conversor de RS485 a USB (con puerto serie virutal en el PC). He hecho un programa simple que envía un dato por el puerto serie cada X segundos pero no funciona.
Esto mismo lo probe con un Arduino y me encendia el LED de Tx del conversor USB-RS485 como es normal. Pero lo he intentado con esta placa y no se me enciende el LED ni recibo ningún dato en el Hyperterminal.
El programa es muy sencillo y me da la sensación que hay un paso que desconozco que activa el USART, o lo que me esta costando más ahora mismo el SPI y que no hago.
Creo que lo mejor va a ser que le conecte un osciloscopio o analizador y a partir de ahí podré avanzar... ahora mismo me da la impresión de que todo lo que intento hacer son suposiciones y por eso no avanzo...
-
Planeta9999 habia pensado comprarme este http://www.satkit.com/b2c/index.php?page=pp_producto.php&md=0&ref=5125, ¿como lo veis? mirare lo del analizador logico a ver que me interesa más, creo que con el osciloscopio tendre más opciones de medida..
Hace años tuve un osciloscopio HP de 2x100Mhz, digital aunque con pantalla CRT, y lo terminé vendiendo, porque no lo usaba para nada.
Para trastear con microcontroladores, y en general todo lo digital, mucho más útil un Analizador Lógico.
Yo tengo un Hantek LA5034 de 34 canales y 500 Msa/s. http://www.hantek.com/english/produce_list.asp?unid=44
Por ejemplo, con un analizador lógico, podrías ver perfectamente en tiempo real el cronograma de señales MISO, MOSI, SCLK, CS del SPI, con un osciloscopio no. También se pueden capturar y guardar los trenes de impulsos, para verlos congelados o paso a paso.
(http://su-embroidery.com/pic/hantek/la5034/a3.jpg)
(http://www.hantek.com.cn/Upfiles/200872135862.jpg)
-
Planet9999 me he pedido uno parecido de Digilent. No es que sea barato, pero espero que me vaya bien para mis proyectos. Es de 100 MSPS solo.
(http://kamami.com/published/publicdata/BTC10/attachments/SC/products_pictures/digilent_analog_discovery.jpg)
Link Analizador logico Digilent (http://www.digilentinc.com/press/SalesSheets/AnalogDiscovery-datasheet-4.pdf)
Creo que me llegara en un par de días, veremos a ver si es el SPI :D
-
Planet9999 me he pedido uno parecido de Digilent. No es que sea barato, pero espero que me vaya bien para mis proyectos. Es de 100 MSPS solo.
Link Analizador logico Digilent (http://www.digilentinc.com/press/SalesSheets/AnalogDiscovery-datasheet-4.pdf)
Creo que me llegara en un par de días, veremos a ver si es el SPI :D
¿ Que te ha costado ?
Lo bueno de los Hantek, es que son muy baratos y se los puedes pedir directamente a los chinos por Ebay, el LA5034 lo tienes por unos 170 dólares.
-
Yo me pille uno por 20€, al principio mire estos que estais poniendo, pero para el uso que le iba a dar me venia perfecto y por 20€ fue una ganga
-
Pues viendo el precio del tuyo me ha salido cara :D Eso me pasa por impaciente.
Me ha costado 162€. Vi que podías usarlo de analizador lógico, osciloscoipo (aunque con poco ancho de banda) y como generador de señales y ni me lo pensé....
Bueno, ahora ya esta hecho, espero que al menos le saque partido.
-
Hola,
Ya me ha llegado el analizador y he podido hacer algunas pruebas y sacar algunas conclusiones:
Necesito enviar 24 bits por el SPI, para ello yo hago esto:
void SPI_Send(char data1, char data2, char data3){
NSS_LOW; /* CS nivel low para activar SPI */
SPI_I2S_SendData(SPI1,data1);
SPI_I2S_SendData(SPI1,data2);
SPI_I2S_SendData(SPI1,data3);
NSS_HIGH; /* CS nivel high para activar SPI */
}
Tengo el SPI configurado para enviar datos de 8 bits, por lo que el código SPI_Send me debería enviar los 24 bits, pero veo que solo me envía 16 bits.
Otra cosa curiosa es que el pin CS lo pongo a 0 antes de enviar y a 1 cuando se han enviado los 3 datos (24 bits) pero veo que se pone a 0 antes de comenzar a enviar y se pone a 1 en el 6º bit...
Me parece curioso todo esto, alguien tiene alguna idea de que hago mal....
Os dejo unas imágenes con el SPI configurado a 8 bits y a 16 bits ( 0 clock - 1 dato - 2 CS )
(http://imageshack.us/a/img153/8865/sinttuloma.png)
(http://imageshack.us/a/img585/6829/sinttulokun.png)
-
Lo del CS ocurre porque debes esperar a que se envien los datos, seguramente este spi traera un buffer tipo fifo donde puedes meter X datos en cola y se van enviando consecutivamente para ello tendrias que buscar que registro indica el final del envio de todos los datos seria algo asi:
CS_L
spi_send
spi_send
while(x);
CS_H
siendo X la funcion/registro que determina cuando se han enviado los datos
-
Gracias MerLiNz,
He hecho lo que me comentabas y ya funciona
Me faltaba esto después de cada SPI_Send
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
y ahora ya me aparecen los 24 bits y el CS correcto
(http://imageshack.us/a/img833/3949/sinttulougn.png)
Gracias
-
No hace falta ponerlo despues de cada send, con que lo pongas en el ultimo, vale.