历史上的今天

今天是:2024年10月17日(星期四)

正在发生

2019年10月17日 | STM32 3个硬件SPI的使用

发布者:梦想学院 来源: eefocus关键字:STM32  硬件SPI 手机看文章 扫描二维码
随时随地手机看文章

硬件平台:STM32F103

SPI1初始化过程


static OS_EVENT *spi1_sem_event;

static void SPI1SemInit(void)

{

    spi1_sem_event = OSSemCreate(1);

}


extern void SPI1SemGet(void)

{

    uint8_t err;


    OSSemPend(spi1_sem_event, 0, &err);

}


extern void SPI1SemPut(void)

{

    OSSemPost(spi1_sem_event);

}

static void Spi1_Init(void)

{

    SPI_InitTypeDef  SPI_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;


    /* Enable SPI1 and GPIO clocks */

    /*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,

       SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO

       and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */


    /*!< SPI_FLASH_SPI Periph clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    /*!< AFIO Periph clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);



    /*!< Configure SPI_FLASH_SPI pins: SCK */

    GPIO_InitStructure.GPIO_Pin = PIN_SPI1_SCLK;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(PORT_SPI1_SCLK, &GPIO_InitStructure);


    /*!< Configure SPI_FLASH_SPI pins: MISO */

    GPIO_InitStructure.GPIO_Pin = PIN_SPI1_MISO;

    GPIO_Init(PORT_SPI1_MISO, &GPIO_InitStructure);


    /*!< Configure SPI_FLASH_SPI pins: MOSI */

    GPIO_InitStructure.GPIO_Pin = PIN_SPI1_MOSI;

    GPIO_Init(PORT_SPI1_MOSI, &GPIO_InitStructure);


    /* SPI1 configuration */

    // W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.

    // Data on the DO and DIO pins are clocked out on the falling edge of CLK.

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置SPI工作模式:设置为主SPI

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构

#if 0

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样

#else

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;      //时钟悬空低

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    //数据捕获于第1个时钟沿

#endif

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//定义波特率预分频的值:波特率预分频值为2

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始

    SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式

    SPI_Init(SPI1, &SPI_InitStructure);


    /* Enable SPI1  */

    SPI_Cmd(SPI1, ENABLE);

    SPI1SemInit();

}

extern void SPI1_SetSpeed(u8 SpeedSet)

{

    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_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    //如果速度设置输入0,则低速模式,非0则高速模式

    if(SpeedSet == 1)

    {

        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

    }

    else

    {

        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

    }

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI1, &SPI_InitStructure);

}


extern void spi1WriteData(Uchar *buf,Uint len)

{

    for (; len ; len--,buf++)

    {

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

        SPI_I2S_SendData(SPI1, *buf);

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

        SPI_I2S_ReceiveData(SPI1);

    }

}


extern u8 SPI1_Swap_DataMSB(u8 byte)

{

    u8 retry=0;

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位

    {

        retry++;

        if(retry>200)return 0;

    }

    SPI_I2S_SendData(SPI1, byte); //通过外设SPIx发送一个数据

    retry=0;


    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位

    {

        retry++;

        if(retry>200)return 0;

    }

    return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据

}


SPI2初始化过程


static OS_EVENT *spi2_sem_event;

static void SPI2SemInit(void)

{

    spi2_sem_event = OSSemCreate(1);

}


extern void SPI2SemGet(void)

{

    uint8_t err;


    OSSemPend(spi2_sem_event, 0, &err);

}


extern void SPI2SemPut(void)

{

    OSSemPost(spi2_sem_event);

}


extern void Spi2_Init(void)

{

    SPI_InitTypeDef  SPI_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    /*!< AFIO Periph clock enable */

    //RCC_APB2PeriphClockCmd(RCC_APB1Periph_AFIO, ENABLE);



    GPIO_InitStructure.GPIO_Pin = PIN_SPI2_SCLK;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(PORT_SPI2_SCLK, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = PIN_SPI2_MISO;

    GPIO_Init(PORT_SPI2_MISO, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = PIN_SPI2_MOSI;

    GPIO_Init(PORT_SPI2_MOSI, &GPIO_InitStructure);


    /* SPI2 configuration */

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

#if 1

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

#else

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;      //时钟悬空低

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        //数据捕获于第1个时钟沿

#endif

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);


    /* Enable SPI2  */

    SPI_Cmd(SPI2, ENABLE);

    SPI2SemInit();

}


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

* Function Name  : SPI_SetSpeed

* Description    : SPI设置速度为高速

* Input          : u8 SpeedSet

*                  如果速度设置输入0,则低速模式,非0则高速模式

*                  SPI_SPEED_HIGH   1

*                  SPI_SPEED_LOW    0

* Output         : None

* Return         : None

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

void SPI2_SetSpeed(u8 SpeedSet)

{

    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_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    //如果速度设置输入0,则低速模式,非0则高速模式

    if(SpeedSet == 1)

    {

        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

    }

    else

    {

        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

    }

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);

}


extern void spi2WriteData(Uchar *buf,Uint len)

{

    for (; len ; len--,buf++)

    {

        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

        SPI_I2S_SendData(SPI2, *buf);

        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

        SPI_I2S_ReceiveData(SPI2);

    }

}


extern u8 SPI2_Swap_DataMSB(u8 byte)

{

  /* Loop while DR register in not emplty */

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);


  /* Send byte through the SPI1 peripheral */

  SPI_I2S_SendData(SPI2, byte);


  /* Wait to receive a byte */

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);


  /* Return the byte read from the SPI bus */

  return SPI_I2S_ReceiveData(SPI2);

}


SPI3初始化过程


static OS_EVENT *spi3_sem_event;


static void SPI3SemInit(void)

{

    spi3_sem_event = OSSemCreate(1);

}


extern void SPI3SemGet(void)

{

    uint8_t err;


    OSSemPend(spi3_sem_event, 0, &err);

}


extern void SPI3SemPut(void)

{

    OSSemPost(spi3_sem_event);

}


static void Spi3_Init(void)

{

    SPI_InitTypeDef  SPI_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;


    /* Enable SPI1 and GPIO clocks */

[1] [2] [3]
关键字:STM32  硬件SPI 引用地址:STM32 3个硬件SPI的使用

上一篇:STM32F103使用SPI3总结
下一篇:msp430输出PWM波

推荐阅读

RCC实例详解#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)//如果定义了这些系统时钟将设为24M,如果没有定义则为72M #define SYSCLK_FREQ_24MHz 24000000#else #define SYSCLK_FREQ_72MHz 72000000 //系统时钟默认值的定义 ,如果没有定义外部高速时钟则用内部高速时钟,为8000000#endif #i...
如果我们阅读行业杂志或上网查询,可能很快会产生这样的印象:当今的世界是数字化的,模拟技术已成为过去。事实真是如此吗? 不完全是。每一个物理元素,无论是音频信号还是温度,都是一个模拟量;要测量或管理这些模拟量,都需要用到模拟技术。每个高速的数字信号传输过程都必须处理好其中的模拟问题,只有非常了解模拟技术才能明白如何进行优化。一旦你...
近日,美国专利商标局正式公布了苹果公司新获得的66项专利,其中有一项跟苹果公司的“泰坦项目”有关,介绍了利用电永磁体改善车辆主动悬架系统,从而减少车辆能耗的方法。该项专利名为“配备电永磁体的主动悬架系统”,利用控制系统识别车辆运行特性的变化,并根据识别到的变化,利用该控制系统向致动器系统输出稳定指令,并基于接收到的稳定指令,利用该...
10月15日晚,广和通发布公告称,前三季度实现营收28.5亿元,同比增长45.03%;归属于上市公司股东的净利润为3.23亿元,同比增长44.45%。其中,第三季度实现营收10.32亿元,同比增长47.16%;归属于上市公司股东的净利润为1.21亿元,同比增长39.94%。报告期内,广和通拟向深圳市创新投资集团有限公司、深圳前海红土并购基金合伙企业(有限合伙)、深圳建华开...

史海拾趣

问答坊 | AI 解惑

到底如何上手学ARM(

老手讲心得,新手讲迷惑 每个人都经历过初学阶段,有些很顺利,有些则很曲折,有些甚至还在徘徊!更有一些感叹!那就都在这说出来吧,说说自己的经历,自己难忘的经历!当作是一种回味,也给后来人一些经验和教训!   新手也要抓紧时间,有 ...…

查看全部问答∨

对特性阻抗的一种浅显易懂的解释

抽象又复杂的数位高速逻辑原理,与传输线中方波讯号的如何传送, 以及如何确保其讯号完整性(Signal Integrity),降低其杂讯(Noise)减少之误动作等专业表达,若能以简单的生活实例加以说明,而非动则搬来一堆数学公式与难懂的物理语言者,则对新 ...…

查看全部问答∨

wince SDK升级后,如何能降低对上层应用程序的影响?

开发初期,wince的SDK版本不稳定,需要升级多次,怎么样能使在原SDK上开发的应用程序不用进行修改,或只需要修改应用程序的配置就可以了? 就是说对于上层应用程序来说,只需要重新安装新的SDK,不需要重建工程…

查看全部问答∨

规划未来2年的路线:开发20款ARM/MIPS开发板,请大家帮忙芯片选型和推荐!

目前已经成功开发了 S3C44B0X、S3C2410、S3C2440、AT91SAM9260、AT91SAM9261、AT91SAM9263、JZ4755。 接着打算做 PXA270(目前市场上还有不少270芯片,可以低价购买) PXA310(这个暂时还犹豫不决,还没找到合适的SDK) S3C2416(资料丰富,批量价 ...…

查看全部问答∨

100分求硬盘UBA(UNIT BLOCK ADDRESSING)寻址方式的资料

求硬盘UBA(UNIT BLOCK ADDRESSING)寻址方式的资料 不是普通的chs或lba寻址,uba寻址是和硬盘的固件区相关的 贴链接,贴例子都可以 只要和uba有关的都给分 顶者给分 chs或lba的资料的不给分 …

查看全部问答∨

正弦波,三角波。锯齿波的产生?

如何利用FPGA能产生正弦波,三角波。锯齿波,但是不能用DAC芯片。望各位高手指教。。…

查看全部问答∨

求购一个100G左右的SATA移动硬盘

本帖最后由 ddllxxrr 于 2016-1-7 17:00 编辑 RT. 笔记本的坏了,新的太贵。买个旧的来用着先。联系QQ523335234 注明硬盘 …

查看全部问答∨

DIY一款LED节能灯电路,,,,

      环保节能概念是当今时尚的话题,照明用电节能最好的方法是使用LED节能灯,LED节能灯不但节能,而且有寿命长等优点,深受人们欢迎!现为大家介绍一款可以自己打造的LED节能灯制作及过程,希望大家可以在制作动起手来,也 ...…

查看全部问答∨

传感器工作电压与称重芯片工作电压如何搭配才合理?

最近做称重方面的计量。遇到的问题:    称重传感器的推荐激励电压是10V。 选用了CS5532的这个芯片。 。为了减少干扰,想采取比率的电路接法。也就是把芯片的参考电压由称重传感器的工作电压分压得到。   查阅了网上的很多资 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved