gd32 spi 发送&中断接收例程

Master
SPI0_NSS PA4 AF5
SPI0_SCK PA5 AF5
SPI0_MISO PA6 AF5
SPI0_MOSI PA7 AF5

Slave
SPI1_NSS PB12 AF5
SPI1_SCK PB13 AF5
SPI1_MOSI PC1 AF5
SPI1_MISO PC2 AF5

main.c

/*!
    \file    main.c
    \brief   running LED

    \version 2023-03-31, V1.0.0, firmware for GD32H7xx
*/


#include "gd32h7xx.h"
#include "systick.h"

#include "string.h"
#include "stdio.h"


/*!
    \brief      enable the CPU Chache
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void cache_enable(void)
{
    /* Enable I-Cache */
    SCB_EnableICache();

    /* Enable D-Cache */
//    SCB_EnableDCache();
}

void led_config()
{
    rcu_periph_clock_enable(RCU_GPIOJ);

    gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);

    gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9);

    gpio_bit_set(GPIOJ, GPIO_PIN_8);
    gpio_bit_set(GPIOJ, GPIO_PIN_9);

}

void usart_config()
{
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_USART0);

    gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6);
    gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);

    usart_deinit(USART0);
    usart_word_length_set(USART0, USART_WL_8BIT);
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_baudrate_set(USART0, 921600U);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_enable(USART0);
}

void usart_transmit(char* buff, int size)
{
    for (int i = 0; i < size; ++i) {
        usart_data_transmit(USART0, buff[i]);
        while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {}
    }
}


/*
 * Master
 * SPI0_NSS  PA4 AF5
 * SPI0_SCK  PA5 AF5
 * SPI0_MISO PA6 AF5
 * SPI0_MOSI PA7 AF5
 */
void spi0_config()
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);

    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);


    spi_i2s_deinit(SPI0);

    spi_parameter_struct spi_init_struct;
    spi_struct_para_init(&spi_init_struct);
    spi_init_struct.device_mode = SPI_MASTER;
    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.data_size = SPI_DATASIZE_8BIT;
    spi_init_struct.nss = SPI_NSS_HARD;
    spi_init_struct.endian = SPI_ENDIAN_MSB;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.prescale = SPI_PSC_64;
    spi_init(SPI0, &spi_init_struct);

    spi_byte_access_enable(SPI0);
    spi_nss_output_enable(SPI0);


    spi_enable(SPI0);
}

void spi0_transmit(char* buff, int size)
{
    spi_master_transfer_start(SPI0, SPI_TRANS_START);

    for (int i = 0; i < size; ++i) {
        spi_i2s_data_transmit(SPI0, buff[i]);
        while(spi_i2s_flag_get(SPI0, SPI_FLAG_TP) == RESET) {}
    }

    spi_master_transfer_start(SPI0, SPI_TRANS_IDLE);
}


/*
 * Slave
 * SPI1_NSS  PB12 AF5
 * SPI1_SCK  PB13 AF5
 * SPI1_MOSI PC1  AF5
 * SPI1_MISO PC2  AF5
 */
void spi1_config()
{
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_SPI1);

    gpio_af_set(GPIOB, GPIO_AF_5, GPIO_PIN_12 | GPIO_PIN_13);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12 | GPIO_PIN_13);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_12 | GPIO_PIN_13);

    gpio_af_set(GPIOC, GPIO_AF_5, GPIO_PIN_1 | GPIO_PIN_2);
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1 | GPIO_PIN_2);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_1 | GPIO_PIN_2);


    spi_i2s_deinit(SPI1);

    spi_parameter_struct spi_init_struct;
    spi_struct_para_init(&spi_init_struct);
    spi_init_struct.device_mode = SPI_SLAVE;
    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.data_size = SPI_DATASIZE_8BIT;
    spi_init_struct.nss = SPI_NSS_HARD;
    spi_init_struct.endian = SPI_ENDIAN_MSB;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.prescale = SPI_PSC_64;
    spi_init(SPI1, &spi_init_struct);

    spi_byte_access_enable(SPI1);

    spi_i2s_interrupt_enable(SPI1, SPI_I2S_INT_RP);

    nvic_irq_enable(SPI1_IRQn, 2, 0);

    spi_enable(SPI1);
}

void SPI1_IRQHandler(void)
{
    if(RESET != spi_i2s_interrupt_flag_get(SPI1, SPI_I2S_INT_FLAG_RP)) {
        uint8_t data = spi_i2s_data_receive(SPI1);

        usart_transmit(&data, 1);

        gpio_bit_toggle(GPIOJ, GPIO_PIN_8);
    }
}


/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* enable the CPU Cache */
    cache_enable();

    /* configure systick */
    systick_config();


    led_config();
    usart_config();

    spi0_config();
    spi1_config();


    char msg[] = "Hello World\r\n";
    usart_transmit(msg, strlen(msg));


    int cnt = 0;
    while(1) {

        char buff[32];
        snprintf(buff, 32, "cnt:%d\r\n", cnt++);

        spi0_transmit(buff, strlen(buff));

        delay_1ms(1000);
    }
}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个基于STM32HAL库的CAN中断接收例程: ```c #include "stm32f4xx_hal.h" CAN_HandleTypeDef hcan1; void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) { if (hcan->Instance == CAN1) { // 处理接收到的数据 uint8_t data[8]; for (int i = 0; i < 8; i++) { data[i] = hcan->pRxMsg->Data[i]; } // 继续等待下一次接收 HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); } } int main(void) { HAL_Init(); __HAL_RCC_CAN1_CLK_ENABLE(); hcan1.Instance = CAN1; hcan1.Init.Mode = CAN_MODE_NORMAL; hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan1.Init.TimeSeg1 = CAN_BS1_6TQ; hcan1.Init.TimeSeg2 = CAN_BS2_3TQ; hcan1.Init.Prescaler = 2; hcan1.Init.SJW = CAN_SJW_1TQ; HAL_CAN_Init(&hcan1); CAN_FilterTypeDef can_filter; can_filter.FilterIdHigh = 0xFFFF; can_filter.FilterIdLow = 0xFFFF; can_filter.FilterMaskIdHigh = 0x0; can_filter.FilterMaskIdLow = 0x0; can_filter.FilterFIFOAssignment = CAN_FilterFIFO0; can_filter.FilterMode = CAN_FILTERMODE_IDMASK; can_filter.FilterScale = CAN_FILTERSCALE_32BIT; can_filter.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(&hcan1, &can_filter); HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); while (1) { // 主循环中可以处理其他事情 } } ``` 在这个例程中,我们使用了 `HAL_CAN_RxCpltCallback()` 函数作为 CAN 接收中断的回调函数,实现了接收到数据后的处理。在 `main()` 函数中,我们先初始化 CAN 模块和过滤器,然后调用 `HAL_CAN_Receive_IT()` 函数启动接收中断。在 `while` 循环中,我们可以处理其他事情,接收中断的处理会在中断发生时自动调用回调函数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值