历史上的今天
返回首页

历史上的今天

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

正在发生

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

2019-10-17 来源:eefocus

硬件平台: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 */

推荐阅读

史海拾趣

AVAGO公司的发展小趣事

随着公司规模的扩大和技术的不断积累,AVAGO公司开始寻求多元化的发展道路。除了继续深耕半导体领域外,公司还积极拓展其他相关领域,如传感器、无线通信等。同时,公司还与其他行业的领军企业建立了紧密的战略合作关系,共同推动技术创新和市场拓展。

AZ Displays公司的发展小趣事

随着技术的不断进步和市场需求的不断变化,AZ Displays的产品应用领域也在不断拓展。除了传统的消费电子领域外,公司的产品还广泛应用于航空电子、医疗、导航系统、工业控制等多个领域。通过与各行业合作伙伴的紧密合作,AZ Displays成功打开了新的市场大门,实现了业务的快速增长。

Crane Connectors公司的发展小趣事

Crane Connectors公司自创立之初,便致力于电子连接器技术的研发与创新。面对激烈的市场竞争,公司不断投入研发资源,推出了一系列具有自主知识产权的新型连接器产品。这些产品凭借出色的性能、稳定性和可靠性,迅速获得了市场的认可,为公司赢得了大量订单。随着技术的不断升级和产品的持续优化,Crane Connectors逐渐在电子连接器领域树立了良好的品牌形象,实现了市场的快速扩张。

Auris公司的发展小趣事

Auris公司在技术研发方面取得了显著成果。其中,一款名为Auris Robotic Endoscopy System(ARES)的医疗机器人尤为引人注目。这款机器人能够通过精准的操控,帮助医生在不切口的情况下发现早期肺癌,提高了诊断的精确性。20XX年,食品与药品监督管理局(FDA)正式批准了ARES机器人的使用,这是对Auris公司技术实力和产品质量的高度认可。

南京绿芯(Grenergy)公司的发展小趣事

Auris公司在技术研发方面取得了显著成果。其中,一款名为Auris Robotic Endoscopy System(ARES)的医疗机器人尤为引人注目。这款机器人能够通过精准的操控,帮助医生在不切口的情况下发现早期肺癌,提高了诊断的精确性。20XX年,食品与药品监督管理局(FDA)正式批准了ARES机器人的使用,这是对Auris公司技术实力和产品质量的高度认可。

AB Connectors Ltd公司的发展小趣事

在快速发展的过程中,AB Connectors Ltd始终将品质管理放在首位。公司建立了完善的质量管理体系,从原材料采购、生产加工到产品出厂检验等各个环节都实行严格的质量控制。此外,公司还引进了先进的生产设备和检测技术,不断提高产品的精度和稳定性。这些措施有效提升了产品的品质水平,赢得了客户的信任和好评。

问答坊 | AI 解惑

基于S52的超声波测距仪

基于S52的超声波测距仪…

查看全部问答>

浅谈电视监控系统智能化和集约化方案

视频监控一直是安防技术应用的热点之一,以其直观、方便、信息内容丰富而被广泛应用于军队、银行、海关、机场、高速公路、商场、医院、学校、机关、社会小区、家庭等各种场合。视频监控系统的智能化水平和集成化发展速度,也直接反映了不同阶段电子 ...…

查看全部问答>

vs2008下安装sqlce

1.安装哪个版本的sqlce? 2.如何配置 3.基本增删查改和SQL Server是否一致?…

查看全部问答>

买个无线网卡,却无法上网!

每次拨号连接网络都提示“设置系统参数失败”!! 前几天还好好的,刚出现的这个毛病。…

查看全部问答>

电脑蓝屏

宏基笔记本,刚给电脑除尘,给电脑装了一个2G的内存条,重装了好几次系统,玩一会就出现蓝屏STOP 0x000000c2 (0x00000007, 0x00000CD4, 0x00000000, 0xE2195AF8),各位大侠,快点告诉我这到底是什么问题?…

查看全部问答>

有人知道ADV7170/7171可以用VGA连接到电脑显示器上显示吗

我现在在做一个板子,输出的DA用的ADV7170,准备输出RGB信号通过VGA连接到电脑显示器上显示,同步信号通过FPGA产生 但是我了解到这个芯片输出的RGB好像是欧洲SCART的标准,就是隔行的,但是我知道电脑上的VGA都是逐行的信号吧,那这么做兼容吗? ...…

查看全部问答>

PCB加工快速焊接

北京力合安达电路科技有限公司 徐晓红:13671271976…

查看全部问答>

nbcool 帮帮我吧

我真的不知道哪里出错了 就是改不出来 你看看我的帖子 你给我回后 我又回复了 谢谢阿   …

查看全部问答>

大家有没有人了解武汉爱维特公司的?

我在网上投递了他们公司的嵌入式开发工程师,今天他们打电话给我说要先培训四个月,然后才能上班,并且让我交5000元的培训费,这个公司我咋感觉是骗子公司呢!~…

查看全部问答>

DK-LM3S9B96下载程序问题请教

     初学LM3S9B96,现遇到问题:      1.用DK-LM3S9B96开发板自带的IDCI下载程序,报错不能下载成功,错误为“Could not find an Cortex-M device”,见贴图;      2.用JLINK下载 ...…

查看全部问答>