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.
9 years, 11 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);
}