初级会员

- 积分
- 161
- 金钱
- 161
- 注册时间
- 2014-1-7
- 在线时间
- 24 小时
|
1金钱
各位大大好,小弟要实现DMA自动采集ADC的数据,ADC是SPI接口的,ADC的INT引脚为低电平时代表数据有效,此时需要发送固定的15个字节数据来完成ADC读书和状态清除,
于是我就想到用stm32F103定时器TIM2 CH4输入捕获触发DMA,
DMA的外设地址设置SPI1->DR,内存地址设置为15个字节对应的数组地址,数据长度设置为15,
通过调试发现定时器每次下降沿只能通过SPI发送1个字节,并不能1此发送完15个字节,
请各位大神帮我看看是哪里设置的不对,谢谢!
下面附上相关程序
- 通用定时器2中断初始化
- //这里时钟选择为APB1的2倍,而APB1为36M
- //arr:自动重装值。
- //psc:时钟预分频数
- //这里使用的是定时器2!
- void TIM2_Int_Init(u16 arr,u16 psc)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- DMA_InitTypeDef DMA_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM2_ICInitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
-
- GPIO_InitStructure.GPIO_Pin= GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //配置IO为上拉输入模式
- GPIO_Init(GPIOA,&GPIO_InitStructure); //把配置好的IO口初始化一下
-
- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
- TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
-
- // TIM_ITConfig(TIM2,TIM_IT_CC4,ENABLE ); //使能指定的TIM2中断,允许CC4捕获中断
- TIM2_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=04 选择输入端 IC1映射到TI4上
- TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //下降沿捕获
- TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
- TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
- TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
- TIM_ICInit(TIM2, &TIM2_ICInitStructure);
- TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE); //使能或者失能指定的TIMx的DMA请求
-
- TIM_Cmd(TIM2,ENABLE);//开启定时器2
- //启动DMA时钟
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- //DMA1通道3配置
- DMA_DeInit(DMA1_Channel7);
- //外设地址
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI1_DR_Addr;
- //内存地址
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI1_TX_Buff;
- //dma传输方向单向
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //Memory_to_Peripheral
- //设置DMA在传输时缓冲区的长度
- DMA_InitStructure.DMA_BufferSize = SPI_TX_Len;
- //设置DMA的外设递增模式,一个外设
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- //设置DMA的内存递增模式
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- //外设数据字长
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- //内存数据字长
- DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
- //设置DMA的传输模式
- // DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
- //设置DMA的优先级别
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
- //设置DMA的2个memory中的变量互相访问
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA1_Channel7,&DMA_InitStructure);
- DMA_Cmd(DMA1_Channel7,ENABLE);
- }
- /********************************************************************************************************
- ** 函数名称:
- ** 功能描述:
- ** 输 入:无
- ** 输 出:无
- ** 全局变量:无
- ** 调用模块:RCC_APB2PeriphClockCmd
- RCC_APB1PeriphClockCmd
- GPIO_Init
- GPIO_SetBits
- SPI_Init
- SPI_Cmd
- SPI2_RWByte
- ********************************************************************************************************/
- void SPI1_Init(void)
- {
- SPI_InitTypeDef SPI_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA,ENABLE);
- // //配置SPI1引脚:SCK, MISO and MOSI
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
- GPIO_Init( GPIOA, &GPIO_InitStructure );
- GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PB5/6/7上拉
- //SPI1配置
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //选择了串行时钟空闲时为低电平
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于时钟上升沿
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部NSS信号有SSI位控制
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //波特率预分频值为32(72M/32) 2.25MHz
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
- SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
- SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
- // SPI1->DR = 0xFF ; //接送前读一次SPI1->DR,保证接收缓冲区为空
- SPI1->CR2 |=0x03; //发送缓冲区DMA使能;//接收缓冲区DMA使能;
- SPI_Cmd(SPI1, ENABLE); //使能SPI外设
- }
- void SPI1_DMA_Configuration( void )
- {
- RCC->AHBENR |= 1<<0 ; //DMA1时钟使能
- /*------------------配置SPI1_RX_DMA通道Channel2---------------------*/
- DMA1_Channel2->CCR &= ~( 1<<14 ) ; //非存储器到存储器模式
- DMA1_Channel2->CCR |= 2<<12 ; //通道优先级高
- DMA1_Channel2->CCR &= ~( 3<<10 ) ; //存储器数据宽度8bit
- DMA1_Channel2->CCR &= ~( 3<<8 ) ; //外设数据宽度8bit
- DMA1_Channel2->CCR |= 1<<7 ; //存储器地址增量模式
- DMA1_Channel2->CCR &= ~( 1<<6 ) ; //不执行外设地址增量模式
- DMA1_Channel2->CCR &= ~( 1<<5 ) ; //执行循环操作
- DMA1_Channel2->CCR &= ~( 1<<4 ) ; //从外设读
- DMA1_Channel2->CNDTR &= 0x0000 ; //传输数量寄存器清零
- DMA1_Channel2->CNDTR = SPI1_DMA_RXsize ; //传输数量设置为buffersize个
- DMA1_Channel2->CPAR = SPI1_DR_Addr ; //设置外设地址,注意PSIZE
- DMA1_Channel2->CMAR = (u32)SPI1_RX_Buff ; //设置DMA存储器地址,注意MSIZE
- DMA1_Channel2->CCR |= 1 << 0 ; //开启DMA通道2
-
- }
复制代码
|
|