完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F103ZE 串口1发送DMA
最近在使用stm32f103ze-144pin做一个案子,记录一下,毕竟网上有些人也在寻找,或许和我遇到的问题相同,供好学者参考,减少时间。以下程序都基于V3.5.0在野火串口TX-DMA例程基础上进行调整改动,以实现能够软件可控DMA-TX 案子需要使用串口TX-DMA功能,使用这个的原因在于:不需要用死循环等待发送完成标志位,程序如下: (while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);), 我们都知道,死循环会导致mcu在main函数里面占有很大的无用时间,只能通过中断可以介入触发,而现实中,中断也不是无穷多,并且中断触发过多和中断内容过多,会导致打乱main函数程序,因此在我看来,定时中断函数内容尽可能短,触发时间我一般定为100us,时间长短每个人各不相同,可以根据需要设定。 进入正题,设定串口DMA程序,我直接贴下: 1,开RCC-DMA时钟,程序: RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 2,开NVIC中断,用于在发送一次完成后,DMA触发中断,以此来停止多次循环(DMA_Mode_Circular),程序: NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//组0 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //DMA1通道4 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 3,设定DMA相关函数,程序: #define USART1_DR_Base 0x40013804 //串口1TX寄存器地址 #define SENDBUFF_SIZE 10 //10个byte uint8_t SendBuff[SENDBUFF_SIZE];//数组存放数据 DMA_DeInit(DMA1_Channel4);//缺省 DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; // 串口1寄存器地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;//变量指针空间地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//方向,从内存到外设 DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设地址不增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据单位,8bit DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //循环发送,此处如果为normal模式,只会发一次,后面不会再发 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,中 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止内存到内存的传输 DMA_Init(DMA1_Channel4, &DMA_InitStructure); // 配置DMA1通道 4 DMA_Cmd (DMA1_Channel4,ENABLE); //使能DMA1通道4 DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); //DMA发送完后产生中断 对于为什么串口1发送地址是 0x40013804 ,在《stm32f103数据手册》中有提到,截图如下: 然后在《stm32f10xxxxx使用手册》中提到了串口发送寄存器USART-DR的相关偏移地址: 对于选择DMA1通道4的理由在于,32已经规定了DMA1-Channel4是几种外设资源的DMA,而UART1-TX就是其中一种,这一点《stm32f10xxxxx使用手册》也提到了,因此在调用ADC或者是UART2等资源的DMA时候就要注意了。 4,主函数,程序: main() { //初始化; while(1) { //1s定时器标志位,每1s进入一次,使用定时中断,或者delay { for(i=0;i<10;i++)//发10个 { SendBuff = i; } USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//启动发送DMA请求 } } } 以上就是将数据i内容压入SendBuff,就可以让DMA发送啦 5,中断函数,程序: void DMA1_Channel4_IRQHandler(void) { if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET) //判断是否DMA-TX发送完毕 { USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);//失能TX请求,让DMA不再循环发送,没有这句,会一直不断循环发送 DMA_ClearFlag(DMA1_FLAG_TC4); //清除中断标志位,下次不再进入 } } 串口相关程序已被我省略,烦请调通串口轮循发送模式后,再看此份文章,谢谢。以上就是我在调试DMA-TX中的设置程序,目前每秒只发送固定10个byte,可通过修改SENDBUFF_SIZE来改变传输数据量。 如有问题,那也没辙。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 03:38 , Processed in 0.810122 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号