记录单极性归零码控制LED,GD32F330+SPI+DMA方式

因为软件模拟的方式,io翻转和条件判断时间过长,不能满足归零码的时序,只能采用DMA+SPI硬件传输的方式。 

SPI配置,因为只使用mosi模拟单极性归零码,所以直接把SPI的4个脚直接配置成复用模式,nss配置为soft或hard都能用,没有影响

注意LF配置(.endian),endian为MSB(高位先发)。因为归零码要求低电平复位,因此可在发送数组中多加一位,固定发0x00,空闲时就是低电平了。

void SPI0_config()
{
    spi_parameter_struct spi_init_struct;

    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI1);

	//端口直接配置为复用模式,GPIO_PUPD_PULLDOWN或GPIO_PUPD_NONE没区别
	gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN,GPIO_PIN_12 | GPIO_PIN_13 |         
                   GPIO_PIN_14 | GPIO_PIN_15);
    gpio_af_set(GPIOB, GPIO_AF_0,GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_12 | 
                            GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);


    spi_init_struct.trans_mode = SPI_TRANSMODE_BDTRANSMIT;//SPI_TRANSMODE_FULLDUPLEX;//
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;//SPI_NSS_HARD;//
    spi_init_struct.prescale             = SPI_PSC_8;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;	   
    spi_init(SPI1, &spi_init_struct);


	spi_dma_enable(SPI1,SPI_DMA_TRANSMIT);	//发送使用dma
    spi_crc_polynomial_set(SPI1, 7);
    spi_enable(SPI1);
}

DMA配置,配置结束不急着开启

void SPI_DMA_config(void)
{
    dma_parameter_struct dma_init_struct;
    rcu_periph_clock_enable(RCU_DMA);
    dma_struct_para_init(&dma_init_struct);


    dma_deinit(DMA_CH4);
    dma_struct_para_init(&dma_init_struct);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = (uint32_t)sendbuff;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;        //内存递增
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;


    dma_init_struct.number = RGB_SEND_SIZE;
    dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI1);                //注意&符号
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;        //外设不递增
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH4, &dma_init_struct);
    dma_memory_to_memory_disable(DMA_CH4);
    dma_circulation_disable(DMA_CH4);
    dma_interrupt_disable(DMA_CH4, DMA_INT_FTF); 
//    dma_channel_enable(DMA_CH4);                      //使能关闭,发送前开启
}

发送流程,DMA启动SPI发送的流程为,先配置好SPI(只需要一次),再配置好DMA(每次发送前都要配置,配置好自动发送)就可以了。

其实每次DMA启动只需要部分配置参数,这里为了省事直接调用初始化配置函数。

void spi_dma_send(void)
{
    dma_channel_disable(DMA_CH4);
    SPI_DMA_config();
    dma_channel_enable(DMA_CH4);
    while(RESET == dma_flag_get(DMA_CH4,DMA_FLAG_FTF));
}
 

发送前将数据更新到DMA配置的内存地址中就OK了。

memcpy(sendbuff,sendbuff,SEND_SIZE);      //第一个sendbuff是全局变量,第二个是局部变量
spi_dma_send();

模拟归零码的原理就是,调整SPI周期,使得SPI传输8个字节的时间约等于归零码一个高-低电平周期的时间,这样控制SPI发送的1个字节的数据,相当于传输归零码1位的数据。下面是SPI总线42Mhz,8分频之后归零码0、1对应的spi字节宏定义,SPI发送1位数据大约0.2us,要求严格的话,也可以配置成4分频,采用16字节数据传输,根据需求合理配置。

#define lowbit 0x80
#define highbit 0xf8

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值