完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
求教:本人想用输入捕获来读取遥控的数据,然后通过DMA来传输数据。本人主要的程序配置如下所示,但是一直没有读数(为0)。如果用中断的方式来读的话,数据倒是正常的。暂时想不出什么解决的方法,希望群里的大神们能够给予指点,或者有已经成功了的程序,能够
发来共享,供本人研究学习下。PS:本人不是伸手党啊!仅仅是学习参考用的。 //定时器的配置 void Capture_Init(u16 arr,u16 psc) { //此部分需手动修改 IO口设置 RCC->APB2ENR|=1<<0; // 开启辅助功能IO时钟 RCC->APB1ENR|=1<<0; //tiM2 时钟使能 RCC->APB2ENR|=1<<2; //使能PORTA时钟 TIM2->ARR=arr; //设定计数器自动重装值//刚好1ms TIM2->PSC=psc; //预分频器, GPIOA->CRL =0XFFFFFFF0;//PA0 输出 GPIOA->CRL|=0X00000004;//复用功能输出 GPIOA->ODR|=1<<0;//PA0 上拉 TIM2->SMCR|=0x00D4;//从模式控制器 //TIM2->SMCR|= 1<<5; //MSM=1 主/从模式 //TIM2->SMCR|= 5<<4; //TS=101 触发选择 //TIM2->SMCR|= 4<<0; //SMS=100 复位模式 TIM2->CCMR1|=1<<0;//CC1S=01 选择输入端 TIM2->CCMR1|=3<<4; //IC1F=0011配置输入滤波器 TIM2->CCER|=0<<1; //CC1P=0 选择有交转换边沿 TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频 TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中 //TIM2->DIER|=1<<1; //允许更新捕获中断 TIM2->DIER|=1<<9; //允许DMA捕获请求 //TIM2_EGR|=1<<1; TIM2->CR2|=0<<3; //当发生CC1事件时,送出CC1的DMA请求 TIM2->CR1|=0x01; //使能计数器2 MY_NVIC_Init(1,3,TIM2_IRQn,2);//抢占1,子优先级3,组2 } //DMA配置 void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr) { u32 DR_Base; //做缓冲用,不知道为什么.非要不可 RCC->AHBENR|=1<<0;//开启DMA1时钟 DR_Base=cpar; DMA_CHx->CPAR=DR_Base; //DMA1 外设地址 DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址 DMA1_MEM_LEN=cndtr; //保存DMA传输数据量 DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量 DMA_CHx->CCR=0X00000000;//复位 DMA_CHx->CCR|=0<<4; //从外设读 DMA_CHx->CCR|=1<<5; //循环模式 DMA_CHx->CCR|=0<<6; //外设地址非增量模式 DMA_CHx->CCR|=1<<7; //存储器增量模式 DMA_CHx->CCR|=2<<8; //外设数据宽度为32位 DMA_CHx->CCR|=2<<10; //存储器数据宽度32位 DMA_CHx->CCR|=2<<12; //高等优先级 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式 } //开启一次DMA传输 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx) { DMA_CHx->CCR =~(1<<0); //关闭DMA传输 // Get_Adc(0); DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量 DMA_CHx->CCR|=1<<0; //开启DMA传输 } //主函数处理 #define BUF_SIZE 2 u32 IC2Value[BUF_SIZE]={0};//地址 float pro=0;//进度 int main(void) { STM32_Clock_Init(9); //系统时钟设置 delay_init(72);//延时函数初始化 uart_init(72,115200); LED_Init() ; Capture_Init(5000,72-1); //65535 MYDMA_Config(DMA1_Channel5,(u32)( TIM2->CCR1),(u32)IC2Value,2);//sizeof(IC2Value) // MYDMA_Enable(DMA1_Channel5); while(1) { // TIM2->CR2|=0<<3; //当发生CC1事件时,送出CC1的DMA请求 TIM2->DIER|=1<<9; //允许DMA捕获请求 MYDMA_Enable(DMA1_Channel5); //开始一次DMA传输 while(1) { if(DMA1->ISR (1<<1))//等待通道1传输完成 { LED1=0; //亮灯检验 DMA1->IFCR|=1<<1;//清除通道1传输完成标志 break; } pro=DMA1_Channel5->CNDTR;//得到当前还剩余多少个数据 } delay_ms(500); LED1=1; //关灯 // printf("IC2Value = %drn",IC2Value[0]); // printf("TIM2->CCR1 = %drn",TIM2->CCR1); } } [/td] 以下内容为评论 [td]下面是本人根据原子哥之前的例程以及查数据手册等初略调试写出的一个程序,可以实现定时器输入捕获PWM信号同时通过DMA传输的实验程序。经过本人实验,是稳定可靠能用的,对遥控器的通道的读取能保证在0到100 之间的数据范围同时通道间不互相影响。因为只是实验的版本,所以写得有点乱,请勿喷,希望在这方面有所研究的朋友能共同交流,能够写出更好的程序出来。芯片用到的是STM32F051,主要程序配置如下: /************************************** * 函数名 : timer1_init * 描述 : 定时器1的输入捕获加DMA初始化配置 * 输入参数 : 无 * 返回值 : 无 **************************************/ #define BUF_SIZE_TIM1 2 //定义数据的长度 uint32_t IC2Value_TIM1[BUF_SIZE_TIM1]={0,0}; //数据存放的数组 void timer1_init(uint16_t arr,uint16_t psc) { RCC->APB2ENR|=1<<11; //TIM1 时钟使能 RCC->AHBENR|=1<<17; //使能PORTA时钟 // PA引脚设置 GPIOA->MODER|=0x00820000; // PA.8、PA.11设置为AF模式; GPIOA->OTYPER =~0x0900; // 设置推挽输出; GPIOA->OSPEEDR|=0x00c30000; // 设置IO口高速翻转; GPIOA->PUPDR|=0x00820000; // 内部下拉; GPIOA->AFR[1]|=0X02002; // AF2; /*输入捕获需要用到中断的时候再打开*/ // // 配置NVIC,中断向量号TIM1_CC_IRQn= 14 // NVIC_SetPriority(TIM1_CC_IRQn, 0); // NVIC->ISER[0] = (uint32_t)0x01 <<14; // 使能NVIC; TIM1->ARR=arr; //设定计数器自动重装载值 TIM1->PSC=psc; //预分频器 TIM1->CCMR1|=1<<0; //CC1S=01 选择输入端 IC1映射到TI1上 TIM1->CCMR1|=0<<4; //IC1F=0000 配置输入滤波器 不滤波 TIM1->CCMR1|=0<<2; //IC1PS=00 配置输入分频,不分频 TIM1->CCMR2|=1<<8; //CC4S=01 选择输入端 IC4映射到TI4上 TIM1->CCMR2|=0<<12; //IC4F=0000 配置输入滤波器 不滤波 TIM1->CCMR2|=0<<10; //IC4PS=00 配置输入分频,不分频 TIM1->CCER|=0<<1; //CC1P=0 上升沿捕获 TIM1->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中 TIM1->CCER|=0<<13; //CC4P=0 上升沿捕获 TIM1->CCER|=1<<12; //CC4E=1 允许捕获计数器的值到捕获寄存器中 /*DMA配置*/ MYDMA_Config(DMA1_Channel2,(uint32_t)( TIM1->CCR1),(uint32_t)( IC2Value_TIM1[0]),1); // MYDMA_Config(DMA1_Channel4,(uint32_t)( TIM1->CCR4),(uint32_t)( IC2Value_TIM1[1]),1); /*定时器打开DMA传输的配置*/ TIM1->CR2|=0<<3; //当发生CCx事件时,送出CCx的DMA请求 TIM1->DIER|=1<<9; //允许CCR1 DMA捕获请求 //TIM1->DIER|=1<<12; //允许CCR4 DMA捕获请求 /*定时器打开中断传输的配置*/ // TIM1->DIER|=1<<1; //允许捕获1中断 // TIM1->DIER|=1<<4; //允许捕获4中断 // TIM1->DIER|=1<<0; //允许更新中断 TIM1->CR1|=0x01; //使能定时器1 } ///////////////DMA配置///////////////// uint16_t DMA1_MEM_LEN;//保存DMA每次数据传送的长度 void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,uint32_t cpar,uint32_t cmar,uint32_t cndtr) { uint32_t DR_Base; //做缓冲用,不知道为什么.非要不可 RCC->AHBENR|=1<<0;//开启DMA1时钟 DR_Base=cpar; DMA_CHx->CPAR=DR_Base; //DMA1 外设地址 DMA_CHx->CMAR=(uint32_t)cmar; //DMA1,存储器地址 DMA1_MEM_LEN=cndtr; //保存DMA传输数据量 DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量 DMA_CHx->CCR=0X00000000;//复位 DMA_CHx->CCR|=0<<4; //从外设读 DMA_CHx->CCR|=1<<5; //循环模式 DMA_CHx->CCR|=0<<6; //外设地址非增量模式 DMA_CHx->CCR|=1<<7; //存储器增量模式 DMA_CHx->CCR|=2<<8; //外设数据宽度为32位 DMA_CHx->CCR|=2<<10; //存储器数据宽度32位 DMA_CHx->CCR|=2<<12; //高等优先级 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式 // /* 开启DMA1_Channel2、DMA1_Channel3通道中断控制,0级先占优先级,0级次占优先级*/ // // 配置NVIC,中断向量号DMA1_Ch2_3= 10 // NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0); // NVIC->ISER[0] = (uint32_t)0x01 <<10; // 使能NVIC; } //开启一次DMA传输 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx) { DMA_CHx->CCR =~(1<<0); //关闭DMA传输 DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量 DMA_CHx->CCR|=1<<0; //开启DMA传输 } /*TIM1数据采集回来后的处理程序*/ uint8_t TIM1_CAPTURECH_STA1=0; //输入捕获状态 uint8_t TIM1_CAPTURECH_STA4=0; //输入捕获状态 uint8_t duty_b_CH5=0; //遥控最终的读数 uint8_t duty_b_CH6=0; //遥控最终的读数 uint16_t TIM1_CH1ReadValue= 0; //TIM1->CCR1采集的数值 uint16_t TIM1_CH4ReadValue= 0; //TIM1->CCR4采集的数值 uint32_t temp_CH5=0; uint32_t temp_CH6=0; void TIM1CH1_CaptureHandle_Program(void) { if(TIM1_CAPTURECH_STA1 0X40) //捕获到一个下降沿 { TIM1_CAPTURECH_STA1|=0X80; //标记成功捕获到一次高电平脉宽 TIM1_CH1ReadValue=IC2Value_TIM1[0]; //获取当前的捕获值. temp_CH5=TIM1_CAPTURECH_STA1 0X3F; temp_CH5+=TIM1_CH1ReadValue; //得到总的高电平时间 duty_b_CH5=(uint8_t)((temp_CH5-2000)*0.1); if((0CCER =~(1<<1); //CC1P=0 设置为上升沿捕获 }else //还未开始,第一次捕获上升沿 { TIM1_CAPTURECH_STA1=0; //清空 TIM1_CH1ReadValue=0; // TIM1_CAPTURECH_STA1|=0X40; //标记捕获到了上升沿 TIM1->CNT=0; //计数器清空 TIM1->CCER|=1<<1; //CC1P=1 设置为下降沿捕获 } } /************************************** * 函数名 : main * 描述 : 主函数 * 输入参数 : 无 * 返回值 : 无 **************************************/ int main(void) { UserSystemClock48MInit(Internal_Clock_Source); LED_Init(); SysTick_Init(); //开启延时 USART_Configuration(); /* USART1 config 115200 8-N-1 */ //LED灯控制程序 UserTIMER1617PWMInit(1000); //1000hz频率 //遥控通道 timer1_init(65535,48-1);// 定时器初始化配置 48/48=1M的计数频率,自动重装载值为65536 while (1) { MYDMA_Enable(DMA1_Channel2); //开始一次DMA传输 if(DMA1->ISR (1<<5))//等待通道2传输完成 { LED_ON_D4; TIM1CH1_CaptureHandle_Program(); DMA1->IFCR|=1<<5;//清除通道2传输完成标志 } } } |
|
相关推荐
1个回答
|
|
|
从您提供的代码片段来看,您正在尝试使用定时器输入捕获功能来读取遥控数据,并通过DMA传输数据。然而,您遇到了一些问题,导致无法成功读取数据。以下是一些建议和可能的原因:
1. 确保定时器配置正确:首先,请确保您的定时器配置正确,包括时钟源、预分频器(PSC)、自动重载寄存器(ARR)等。这些参数需要根据您的具体需求进行设置。 2. 确保输入捕获通道配置正确:检查您的输入捕获通道配置,包括输入捕获模式、极性、输入捕获通道的GPIO配置等。确保这些设置与您的硬件和需求相匹配。 3. 确保DMA配置正确:检查您的DMA配置,包括DMA通道、源地址、目标地址、数据宽度、传输方向等。确保这些设置正确无误。 4. 确保中断和DMA请求使能:如果您使用DMA传输数据,需要确保定时器的DMA请求使能。此外,如果需要使用中断,请确保相应的中断使能。 5. 检查GPIO配置:确保您的遥控信号输入引脚的GPIO配置正确,包括引脚模式、速度、上拉/下拉等。 6. 检查代码逻辑:仔细检查您的代码逻辑,确保在读取数据、启动定时器、启动DMA等操作的顺序和条件都正确。 7. 调试和测试:使用调试工具(如Keil uVision、STM32CubeIDE等)逐步执行您的代码,观察变量值和寄存器状态,以便找到问题所在。 8. 参考成功案例:查找一些成功的输入捕获和DMA传输的示例代码,以便了解正确的实现方式。这些示例代码可以帮助您发现潜在的问题,并为您提供解决方案。 9. 考虑使用中断:如果DMA传输仍然无法正常工作,您可以考虑使用中断来读取遥控数据。虽然这可能不是您的首选方案,但它可以作为一个备选方案,确保您的程序能够正常运行。 10. 寻求社区帮助:如果您仍然无法解决问题,可以在相关的技术论坛和社区(如STM32官方论坛、EEVblog等)寻求帮助。许多经验丰富的开发者可能会提供有价值的建议和解决方案。 总之,要解决您遇到的问题,需要仔细检查和调试您的代码和硬件配置。希望以上建议对您有所帮助。祝您学习顺利! |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4191 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3255 浏览 1 评论
2787 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2219 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
15105 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3154浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1932浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2101浏览 3评论
2012浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2205浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-11 01:55 , Processed in 0.891794 second(s), Total 76, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1163