Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
8 years, 4 months ago.
SPI strange issues
Hello and thanks for your help.
I have finished programming my Nucleo with SPI (using the SPI2 module). Basically I have another microprocessor that acts like a mirror slave. It transmits back everything it receives. The Nucleo is connected to a text LCD which shows what the master sends and what it receives from the slave.
Everything works fine. Of course there is a delay of 1, meaning that for example when I send one by one "Adapt LAB", when I send the "A" I receive garbage, and I receive that "A" (or I should!) when I transmit the "d". That is what in theory it should happen.
Well, it does happen like this with all character except the first one! When I send the first one and receive garbage, then I send the second one and again receive a weird character. After that everything works like wonders. but that first mistake is bugging me. Can anyone help me with what is going on here??
-
By the way, I solved the above problem by first sending a 0x00, before starting sending anything, (by the way I tried the clear_transfer_buffer method as indicated in the documentation but >>it does not exist<< (at least that is what mbed said- as well as abort_transfer)
Is this how it should be done in mbed? or with Nucleo?? (I have programmed SPI in other architectures and this was not necessary)
I leave here my code if anyone wants to see it. (you can see that I repeat the same thing twice- it was done just to see that it fails the first time but works ok the second time)
#include "mbed.h" #define MASK (0xFF) // Pins 0,1,4,5,6,7 PortOut lcd_port(PortA,MASK); // For data we are going to use only PA_4 to PA_7 DigitalOut LCD_ENout(PA_0); //Enable DigitalOut LCD_RSout(PA_1); // RS #define lcdLINE1 0x00 #define lcdLINE2 0x40 SPI device(PB_15, PB_14, PB_13); DigitalOut CS(PB_12); void strobeLCD(void){ LCD_ENout=1; wait_us(2);// 2 us // is there a way to delay micro seconds??? LCD_ENout=0; } void writeLCD(unsigned char dat){ lcd_port = lcd_port & 0x0F; //clear the bits 4 to 7 lcd_port = lcd_port | (dat & 0xF0); //combine with upper nibble leave lower the same strobeLCD(); wait_us(1); lcd_port = lcd_port & 0x0f; //clear upper bits lcd_port = lcd_port | ((dat<<4)&(0xF0)); //combine with lower nibbles leave lowe the same strobeLCD(); wait_ms(2); } void lcd_cmd(unsigned char cmd){ LCD_RSout=0; //select command wait_us(1); writeLCD(cmd); } void lcd_data(unsigned char dat){ LCD_RSout=1; //select data wait_us(1); writeLCD(dat); } void lcd_init(void){ lcd_port =lcd_port &0x0F; //clear upper bits lcd_port = lcd_port |0x30; // directr data to LCD 7-4 LCD_RSout=0; strobeLCD(); wait_ms(10); strobeLCD(); wait_ms(10); strobeLCD(); wait_ms(10); lcd_port =lcd_port &0x0F; //clear upper bits lcd_port =lcd_port |0x20; // directr data to LCD 7-4 strobeLCD(); wait_ms(10); lcd_cmd(0x28); //Function set 4-bit mode 2 line 5x7 font lcd_cmd(0x0E); //Display ON cursor ON blink OFF lcd_cmd(0x06); // automatic increament no display shift lcd_cmd(0x80); //Address DDRAM with 0 offset 80h } void lcd_WriteStr(const unsigned char *c){ while(*c!='\0'){ lcd_data(*c); c++; } } void lcd_SetCursor(unsigned char loc){ lcd_cmd(loc|0x80); //send "set DDRAM address cmd } void lcd_LINE1(void){ lcd_SetCursor(lcdLINE1); } void lcd_LINE2(void){ lcd_SetCursor(lcdLINE2); } void lcd_clear(void){ lcd_cmd(0x01); } int main(){ unsigned char spi_read_data; unsigned char data3[]="Adapt LAB"; wait(0.3); lcd_init(); lcd_clear(); lcd_LINE1(); lcd_WriteStr("Salvor HardinSMT"); lcd_LINE2(); lcd_WriteStr("Demo SPI"); wait(2); device.format(8,1); //change mode // device.clear_transfer_buffer(); // device. clear_transfer_buffer(); // device.abort_transfer(); CS=0; device.write(0x00); CS=1; // device.write(0x00); lcd_clear(); lcd_LINE1(); lcd_WriteStr("M: "); lcd_LINE2(); lcd_WriteStr("S: "); lcd_SetCursor(lcdLINE1+3); lcd_WriteStr(data3); unsigned int i=0,b=3; // device.write(data3[0]); // device.write(data3[1]); while ( data3 [i] != '\0' ) { // here write and read SPI CS=0; spi_read_data= device.write(data3[i]); CS=1; if(i!=0) //skip garbage { lcd_SetCursor(lcdLINE2+b); lcd_data(spi_read_data); b++; } i++; }// while //last one // here read and write SPI CS=0; spi_read_data= device.write(0x00); CS=1; lcd_SetCursor(lcdLINE2+b); lcd_data(spi_read_data); wait(2); lcd_clear(); lcd_LINE1(); lcd_WriteStr("M: "); lcd_LINE2(); lcd_WriteStr("S: "); lcd_SetCursor(lcdLINE1+3); lcd_WriteStr(data3); i=0;b=3; while ( data3 [i] != '\0' ) { // here write and read SPI CS=0; spi_read_data= device.write(data3[i]); CS=1; if(i!=0) //skip garbage { lcd_SetCursor(lcdLINE2+b); lcd_data(spi_read_data); b++; } i++; }// while //last one // here read and write SPI CS=0; spi_read_data= device.write(0x00); CS=1; lcd_SetCursor(lcdLINE2+b); lcd_data(spi_read_data); while(1); }