stm32 SPI DMA读取ADS8345数据

本文详细介绍了STM32中DMA模块的配置方法,包括初始化、通道设置、传输方向、缓冲区大小、优先级等关键步骤,并以SPI接口为例演示了如何实现双向数据传输。通过实例代码,读者可以深入了解DMA与外设的连接方式,提高嵌入式系统数据传输效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

研究了两天的SPI通过DMA操作.

过程:怎样启用DMA?首先,众所周知的是初始化,任何设备启用前都要对其进行初始化,要对模块初始化,还要先了解该模块相应的结构及其函数,以便正确的设置;由于DMA较为复杂,我就只谈谈DMA的基本结构和和常用函数,这些都是ST公司提供在库函数中的。

1、  下面代码是一个标准DMA设置,当然实际应用中可根据实际情况进行裁减: 

  DMA_DeInit(DMA_Channel1);

  上面这句是给DMA配置通道,根据ST提供的资料,STM3210Fx中DMA包含7个通道(CH1~CH7),也就是说可以为外设或memory提供7座“桥梁”(请允许我使用桥梁一词,我觉得更容易理解,哈哈,别“拍砖”呀!); 

  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

  上面语句中的DMA_InitStructure是一个DMA结构体,在库中有声明了,当然使用时就要先定义了;DMA_PeripheralBaseAddr是该结构体中一个数据成员,给DMA一个起始地址,好比是一个buffer起始地址,数据流程是:外设寄存器à DMA_PeripheralBaseAddàmemory中变量空间(或flash中数据空间等),ADC1_DR_Address是我定义的一个地址变量; 

  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;

  上面这句很显然是DMA要连接在Memory中变量的地址,ADC_ConvertedValue是我自己在memory中定义的一个变量; 

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  上面的这句是设置DMA的传输方向,就如前面我所说的,DMA可以双向传输,也可以单向传输,这里设置的是单向传输,如果需要双向传输:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。 

 DMA_InitStructure.DMA_BufferSize = 2;

  上面的这句是设置DMA在传输时缓冲区的长度,前面有定义过了buffer的起始地址:ADC1_DR_Address ,为了安全性和可靠性,一般需要给buffer定义一个储存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的2个half-word(见下面的设置);32位的MCU中1个half-word占16 bits。 

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  上面的这句是设置DMA的外设递增模式,如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;我的例子里DMA只与ADC1建立了联系,所以选用DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

上面的这句是设置DMA的内存递增模式,DMA访问多个内存参数时,需要使用DMA_MemoryInc_Enable,当DMA只访问一个内存参数时,可设置成:DMA_MemoryInc_Disable。 

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

上面的这句是设置DMA在访问时每次操作的数据长度。有三种数据长度类型,前面已经讲过了,这里不在叙述。 

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

与上面雷同。在此不再说明。 

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  上面的这句是设置DMA的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal 

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  上面的这句是设置DMA的优先级别:可以分为4级:VeryHigh,High,Medium,Low. 

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  上面的这句是设置DMA的2个memory中的变量互相访问的 

  DMA_Init(DMA_Channel1,&DMA_InitStructure);

  前面那些都是对DMA结构体成员的设置,在次再统一对DMA整个模块做一次初始化,使得DMA各成员与上面的参数一致。 

  /*DMA Enable*/

  DMA_Cmd(DMA_Channel1,ENABLE);

  哈哈哈!这一句我想我就不罗嗦了,大家一看就明白。 

至此,整个DMA总算设置好了,但是,DMA通道又是怎样与外设联系在一起的呢?哈哈,这也是我当初最想知道的一个事情,别急!容我想喝口茶~~~~~~哈哈哈!

要使DMA与外设建立有效连接,这不是DMA自身的事情,是各个外设的事情,每个外设都有 一个xxx_DMACmd(XXXx,Enable )函数,如果使DMA与SPI建立有效联系,就使用SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE);

具体代码如下:

 

void DMA_Configuration_SPI1_RX(u16 bufsize)
{
  DMA_DeInit(DMA1_Channel2);
  DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&SPI1->DR;;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Usart_TX_Buf;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //DMA单向传输
  DMA_InitStructure.DMA_BufferSize = bufsize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //DMA内存地址自动增加模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    //循环模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel2, &DMA_InitStructure);
}

/* 使用软件模拟SPI读写时序,进行初始化 */
void ADS8345_PORT_INIT( void ) 
{
  SPI_InitTypeDef SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;


 /*spi1 port_init*/
    /* Configure SPI1 pins: SCK, NSS and MOSI ---------------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA,GPIO_Pin_3);

  /*miso*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure) ;

          /* Configure SPI1 pins:  NSS ---------------------------------*/
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA,GPIO_Pin_4);

  /* SPI1 Configuration (Master Tx, 14 MBaud) --------------------------------*/
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode =  SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; 
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;  
  SPI_Init(SPI1, &SPI_InitStructure); 
  /* Enable SPI1 */
  SPI_Cmd(SPI1, ENABLE);
}

 

void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);
 
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
 
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* ADCCLK = PCLK2/4 */
    RCC_ADCCLKConfig(RCC_PCLK2_Div4);
 
    /* PLLCLK = 8MHz * 7 = 56 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }

  /* Enable DMA clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_SPI1, ENABLE);                 
}

 

 在main中:

 

    RCC_Configuration();    
    /*System tick init*/
    delay_init(72);    
    ADS8345_PORT_INIT();
    /*SPI RX DMA enable*/
    DMA_Configuration_SPI1_R(2);
//     NVIC_Configuration();
    DMA_Cmd(DMA1_Channel2,ENABLE);    
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE);
    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC | DMA_IT_HT, ENABLE);
 

然后直接就可以去Usart_TX_Buf中读数了!

 

转载于:https://www.cnblogs.com/sankye/archive/2012/04/20/2459264.html

ads834516-Bit, 8-Channel Serial Output Sampling ANALOG-TO-DIGITAL CONVERTER FEATURES ● BIPOLAR INPUT RANGE ● PIN-FOR-PIN COMPATIBLE WITH THE ADS7844 AND ADS8344 ● SINGLE SUPPLY: 2.7V to 5V ● 8-CHANNEL SINGLE-ENDED OR 4-CHANNEL DIFFERENTIAL INPUT ● UP TO 100kHz CONVERSION RATE ● 85dB SINAD ● SERIAL INTERFACE ● QSOP-20 AND SSOP-20 PACKAGES DESCRIPTION The ADS8345 is an 8-channel, 16-bit, sampling Analog-to-Digital (A/D) converter with a synchronous serial interface. Typical power dissipation is 8mW at a 100kHz throughput rate and a +5V supply. The reference voltage (VREF) can be varied between 500mV and VCC/2, providing a corresponding input voltage range of ±VREF. The device includes a shutdown mode which reduces power dissipation to under 15µW. The ADS8345 is ensured down to 2.7V operation. Low-power, high-speed, and an onboard multiplexer make the ADS8345 ideal for battery-operated systems such as personal digital assistants, portable multi-channel data log- gers, and measurement equipment. The serial interface also provides low-cost isolation for remote data acquisition. The ADS8345 is available in a QSOP-20 or SSOP-20 package and is ensured over the –40°C to +85°C temperature range. CDAC SAR Comparator 8-Channel Multiplexer Serial Interface and Control CH4 CH5 CH6 CH7 COM VREF CS SHDN DIN DOUT BUSY DCLK CH0 CH1 CH2 CH3 ® A D S 8 3 4 5 ® ADS8345 ADS8345 SBAS177C – FEBRUARY 2001 – REVISED APRIL 2003 www.ti.com PRODUCTION DATA information is current as of publication date. Products conform to specifications per the terms of Texas Instruments standard warranty. Production processing does not necessarily include testing of all parameters. Copyright © 2001-2003, Texas Instruments Incorporated Please be aware that an important notice concerning availability, standard warranty, and use in critical applications of Texas Instruments semiconductor products and disclaimers thereto appears at the end of this data sheet. APPLICATIONS ● DATA ACQUISITION ● TEST AND MEASUREMENT EQUIPMENT ● INDUSTRIAL PROCESS CONTROL ● PERSONAL DIGITAL ASSISTANTS ● BATTERY-POWERED SYSTEMS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值