STM32F4 SPI2初始化及收发数据【使用库函数】

        我的STM32F4 Discovery上边有一个加速度传感器LIS302DL。在演示工程中,ST的工程师使用这个传感器做了个很令人羡慕的东西:解算开发板的姿态。当开发板倾斜时候,处于最上边的LED点亮,其他LED不亮。同时,用MicroUSB数据线将开发板连接电脑时,开发板就会虚拟成一个鼠标。倾斜开发板时,鼠标指针会向倾斜的方向移动。归根结底,就是牛B的ST工程师用加速度传感器完成了姿态解算。

        在开发板上,加速度传感器使用了SPI方式用STM32F4芯片进行通信。STM32F4的SPI1 作为主机,与LIS302Dl进行通信,读取或者写入数据。由于我没有使用过STM32的SPI口,因此在板子的空余资源中找到了SPI2接口来做实验。实验是这样的:将SPI的MISO和MOSI脚相连。这样SPI发送了什么数据,就能接收到什么数据。不需要额外的器件就能试验。

        引脚:将PB13、PB14、PB15三个引脚的复用功能,分别对应于SPI2SCK、SPI2MISO、SPI2MOSI。

     引脚初始化:

void SPI_GPIOConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);  //开启时钟
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //引脚初始化
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);  //打开引脚的复用功能
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
}

SPI2功能初始化:

void SPI_Config(void)
{
    SPI_GPIOConfig();
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);  //时钟
    
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //全双工模式
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;   //作为主机使用
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;   //数据长度8
    SPI_InitStructure.SPI_CPOL  = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   //软件设置NSS功能
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2,&SPI_InitStructure);
    SPI_Cmd(SPI2,ENABLE);
}

之后就可以收发数据了:

void MySPI_SendData(char da)
{
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);
    SPI_SendData(SPI2,da);
}

uint8_t MySPI_ReceiveData(void)
{
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET);
    return SPI_ReceiveData(SPI2);
}

https://blog.csdn.net/niepangu/article/details/45171271?locationNum=7&fps=1&utm_medium=distribute.pc_relevant.none-task-blog-title-6&spm=1001.2101.3001.4242

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是实现DMX512数据收发程序的基本步骤: 1. 配置串口 首先,需要在STM32F4芯片上选择一个串口作为DMX512数据收发口,并配置串口的波特率、数据位、停止位和奇偶校验位等参数。同时,还需要开启串口的中断功能,以便能够及时处理收到的数据。 2. 初始化DMX512数据帧 DMX512数据通信协议是基于RS485总线的,每个DMX512设备都需要初始化一个512字节的数据帧。可以使用数组来存储这个数据帧,并在程序一开始进行初始化。 3. 发送DMX512数据 在发送DMX512数据时,需要先发送起始码,并将起始码后的512字节数据帧通过串口发送出去。如果发送的是广播数据,则需要将接收器的地址设置为0。 4. 接收DMX512数据 接收DMX512数据时,需要等待串口中断发生,并在中断处理函数中读取串口接收寄存器中的数据。根据DMX512协议,数据帧的第一个字节为起始码,如果接收到的是起始码,则将接收到的数据存储到数据帧中相应的位置中。 5. 处理DMX512数据 当接收到完整的数据帧后,需要对数据进行处理。可以根据不同的应用需求,对数据进行解析、转换或控制等操作。 下面是使用keil库函数进行编写的代码示例: ```c #include <stdio.h> #include "stm32f4xx.h" #include "stm32f4xx_usart.h" #define DMX_CHANNEL_NUM 512 #define DMX_START_CODE 0x00 #define DMX_BAUD_RATE 250000 uint8_t dmxData[DMX_CHANNEL_NUM]; USART_InitTypeDef USART_InitStructure; void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { static uint16_t dmxIndex = 0; uint8_t dmxByte = (uint8_t)USART_ReceiveData(USART2); if (dmxIndex == 0 && dmxByte == DMX_START_CODE) { dmxData[0] = dmxByte; dmxIndex++; } else if (dmxIndex > 0 && dmxIndex < DMX_CHANNEL_NUM) { dmxData[dmxIndex] = dmxByte; dmxIndex++; } } } void setupUSART2(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // Configure USART2 Tx (PA.2) and Rx (PA.3) pins GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); // Connect USART2 pins to AF7 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // Configure USART2 USART_StructInit(&USART_InitStructure); USART_InitStructure.USART_BaudRate = DMX_BAUD_RATE; USART_Init(USART2, &USART_InitStructure); // Enable USART2 interrupt NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART2, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); } int main(void) { setupUSART2(); while (1) { // Send DMX512 data uint16_t i = 0; USART_SendData(USART2, DMX_START_CODE); for (i = 1; i <= DMX_CHANNEL_NUM; i++) { USART_SendData(USART2, dmxData[i-1]); } // Handle DMX512 data // ... } } ``` 在以上代码中,程序首先调用了setupUSART2()函数来配置USART2串口和中断,并初始化了dmxData数组。在USART2中断处理函数中,程序会读取串口接收寄存器中的数据,并将数据存储到dmxData数组中。在main()函数中,程序会循环发送DMX512数据,并在需要时对数据进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值