io口spi模拟主从机通讯例程

                                     IO口模拟spi主从机通讯例程

                   下面这两幅图是,关于SPI数据读取或发送的时序图。

 

1、  主机 io口模拟spi通讯例程

//**spi io 口初始化 **//

void SPI_init(void)

{

         gpio_configure_fpin(SPI_MISO,IO_TYPE_INPUT);//配置成输入模式

         gpio_configure_fpin(SPI_MOSI,IO_OUTPUT_1);//配置成输出模式

         gpio_configure_fpin(SPI_SCK,IO_OUTPUT_1); //配置成输出模式

         gpio_configure_fpin(SPI_CS,IO_OUTPUT_1); //配置成输出模式

 

         clr_spi_GPIO(SPI_SCK);//拉低 SPI_SCK

         set_spi_GPIO(SPI_CS);//拉高  SPI_SCK

         clr_spi_GPIO(SPI_MOSI);//拉低 SPI_MOSI

}

//**主机spi读取一字节api**//

unsigned char SPI_ReadByte(void){       

         unsignedchar i,rByte=0;

         clr_spi_GPIO(SPI_CS);

 for(i=0;i<8;i++){ 

                   clr_spi_GPIO(SPI_SCK);//clr_spi_sck;     

                   delay_us(3);                             

                   rByte<<=1; 

   if(MISO_is_status())//   

                   //M16MISO---PB6        

                            rByte|=1; 

                   set_spi_GPIO(SPI_SCK);//set_spi_sck;    

                   delay_us(3); 

         }

         clr_spi_GPIO(SPI_SCK);

         set_spi_GPIO(SPI_CS);

 return rByte;

 }

 

//** 读取miso 的电平 **//

char MISO_is_status(void)

{

         if(red_spi_GPIO(SPI_MISO))//

                   return1;

         else

                   return0;                    

}

 //**主机spi写入一字节api**//

void SPI_WriteByte(unsigned charwByte){ 

 unsigned char i;

         clr_spi_GPIO(SPI_CS); 

 for(i=0;i<8;i++){

                   clr_spi_GPIO(SPI_SCK);//    

                   delay_us(3);//

   if(wByte&0x80){ 

                                     set_spi_GPIO(SPI_MOSI);//

                   } 

   else{ 

                                     clr_spi_GPIO(SPI_MOSI);//

                                     } 

                   wByte=wByte<<1;                      

                   set_spi_GPIO(SPI_SCK);//set_spi_sck;    

                   delay_us(3);//

         }

                   clr_spi_GPIO(SPI_SCK);

                   set_spi_GPIO(SPI_CS);

}

////////////////////////////////////////////////////////////////////////////////////

注意,我写的主从机的io口对接如下

主机io                                                    从机io

SPI_MISO    ------------------------- SPI_MISO

SPI_MOSI                   ---------------------------SPI_MOSI

SPI_SCK             ---------------------------SPI_SCK

SPI_CS               --------------------------SPI_CS

可能有的人对上面的io口对接的方式感到奇怪,请仔细看我对这几个io口做的初始化设置就可以明白。其实左边SPI_MOSI是为主机的数据输出,SPI_MISO 为主机的数据输入。

而右边是SPI_MOSI是为从机的数据输入,SPI_MISO 为从机的数据输出。这个输入输出的设置主要还是对io口的初始化的地方做设置。

/*************************************************************/

2、  从机 io口模拟spi通讯例程

//**从机spi io 口初始化 **//

void SPI_init(void)

{

         gpio_configure_fpin(SPI_MISO,IO_OUTPUT_0); //配置成输出模式

         gpio_configure_fpin(SPI_MOSI,IO_TYPE_INPUT); //配置成输入模式

         gpio_configure_fpin(SPI_SCK,IO_TYPE_INPUT); //配置成输入模式

         gpio_configure_fpin(SPI_CS,HFM_IO_TYPE_INPUT);//配置成输入模式

}

//**从机spi读取一字节api**//

unsigned char SlaveSPI_read(void)

{

         unsignedchar i,rrbyte=0,rflag=0,SPICS_pin=0,SPISCK_pin=0;

         SPICS_pin=red_spi_GPIO(SPI_CS);

         SPISCK_pin=red_spi_GPIO(SPI_SCK);

         if((!(red_spi_GPIO(SPI_CS)))  ){

         for(i=0;i<8;i++){

                   rflag=1;

                   while(!(red_spi_GPIO(SPI_SCK)) );

                   rrbyte=rrbyte<<1;

                   if(red_spi_GPIO(SPI_MOSI))

                            rrbyte|=1;

                   while((red_spi_GPIO(SPI_SCK)) );  

         }

         while(       !(red_spi_GPIO(SPI_CS)) );

}

         if(rflag)

         returnrrbyte;

         else

                   return0;

}

//**从机spi写入一字节api**//

void SlaveSPI_write(unsigned char wByte)

{       

         unsignedchar i;

         if((!(red_spi_GPIO(SPI_CS)))  ){

                   for(i=0;i<8;i++){

                   while((red_spi_GPIO(SPI_SCK)) );

                   if(wByte&0x80){ 

                                     set_spi_GPIO(SPI_MISO);}//set_spi_si;

                   else{ 

                                     clr_spi_GPIO(SPI_MISO);}  //clr_spi_si;

                  

                            while(!(red_spi_GPIO(SPI_SCK)) );

                            wByte<<=1;

                   }

                   while(       !(red_spi_GPIO(SPI_CS)) );       }

}

 

上面的主从机通讯,我在M3的MCU中已经测试通过的。相信大家看以上例程也明白,这段代码对在什么环境中跑没什么关系,只需要你对相应的MCU环境做好相应IO口初始化就可以了。

 

我写这个是因为看到网上没有对这方面主从机通讯有系统的整理的。对初学者,有较好的帮助。对大牛的话,请不要扔砖啊,扔鸡蛋啊,谢谢!

 

总结,写spi  io口初始化,一定要仔细看时序,还有就是主从机间的IO口,一定要结对。本人刚开始就是在io口上接反了条线,读出数据老是变化不对,纠结了非常久,希望对后面的单片机的学习爱好者有所帮助。

转发请注明原创!http://blog.csdn.net/hwh20095000060

你可能感兴趣的:(io口模拟spi主从机)