博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32的SPI采用DMA方式传输测试
阅读量:3949 次
发布时间:2019-05-24

本文共 3891 字,大约阅读时间需要 12 分钟。

分享一下我老师大神的人工智能教程!零基础,通俗易懂!

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

STM32的SPI采用DMA方式传输测试

 

文博客链接:,作者:jdh,转载请注明.

环境:

主机:WIN7

开发环境:MDK4.23

MCU:STM32F103CBT6

 

说明:

参考链接:

SPI传输数据分为连续传输和非连续传输.

连续传输时序图:

非连续传输时序图:

非连续传输模式可以参考上篇文章:

 

官方pdf关于连续和非连续传输的说明: 

当在主模式下发送数据时,如果软件足够快,能够在检测到每次TXE的上升沿(或TXE中断),并立即在正在进行的传输结束之前写入SPI_DR寄存器,则能够实现连续的通信;此时,在每个数据项的传输之间的SPI时钟保持连续,同时BSY位不会被清除。

简而言之,就是要及时监测TXE.在SPI在1M以上波特率传输时,传输一位时间为1us,导致软件不能及时判断,此时可以用dma的方式来进行SPI传输.

 

源代码:

配置:

#define buffersize 512#define SPI1_DR_Addr ( (u32)0x4001300C )extern uint8_t SPI1_TX_Buff[buffersize];extern uint8_t SPI1_RX_Buff[buffersize];

 

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 = buffersize ;       //传输数量设置为buffersize个 DMA1_Channel2->CPAR = SPI1_DR_Addr ;      //设置外设地址,注意PSIZE DMA1_Channel2->CMAR = (u32)SPI1_RX_Buff ; //设置DMA存储器地址,注意MSIZE /*------------------配置SPI1_TX_DMA通道Channel3---------------------*/ DMA1_Channel3->CCR &= ~( 1<<14 ) ;        //非存储器到存储器模式 DMA1_Channel3->CCR |=    0<<12   ;        //通道优先级最低 DMA1_Channel3->CCR &= ~( 3<<10 ) ;        //存储器数据宽度8bit DMA1_Channel3->CCR &= ~( 3<<8 )  ;        //外设数据宽度8bit DMA1_Channel3->CCR |=    1<<7    ;        //存储器地址增量模式 DMA1_Channel3->CCR &= ~( 1<<6 )  ;        //不执行外设地址增量模式 DMA1_Channel3->CCR &= ~( 1<<5 ) ;         //不执行循环操作 DMA1_Channel3->CCR |=    1<<4    ;        //从存储器读 DMA1_Channel3->CNDTR &= 0x0000   ;        //传输数量寄存器清零 DMA1_Channel3->CNDTR = buffersize ;       //传输数量设置为buffersize个  DMA1_Channel3->CPAR = SPI1_DR_Addr ;      //设置外设地址,注意PSIZE DMA1_Channel3->CMAR = (uint32_t)SPI1_TX_Buff ; //设置DMA存储器地址,注意MSIZE     }

接收与发送:

void SPI1_ReceiveSendByte( u16 num ){ DMA1_Channel2->CNDTR = 0x0000   ;           //传输数量寄存器清零 DMA1_Channel2->CNDTR = num ;         //传输数量设置为buffersize个 DMA1_Channel3->CNDTR = 0x0000   ;           //传输数量寄存器清零 DMA1_Channel3->CNDTR = num ;         //传输数量设置为buffersize个 DMA1->IFCR = 0xF0 ;                         //清除通道2的标志位 DMA1->IFCR = 0xF00 ;                        //清除通道3的标志位 SPI1->DR ;         //接送前读一次SPI1->DR,保证接收缓冲区为空 while( ( SPI1->SR & 0x02 ) == 0 );  DMA1_Channel3->CCR |= 1 << 0 ;              //开启DMA通道3 DMA1_Channel2->CCR |= 1 << 0 ;              //开启DMA通道2  while( ( DMA1->ISR & 0x20 ) == 0 ); DMA1_Channel3->CCR &= ~( 1 << 0 ) ;         //关闭DMA通道3 DMA1_Channel2->CCR &= ~( 1 << 0 ) ;         //关闭DMA通道2}
//SPI发送一个字节static uint8 SPI_SendByte(uint8 Data){ #ifndef SPI_DMA  // Loop while DR register in not emplty while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) == RESET ) ; // Send byte through the SPI1 peripheral SPI_I2S_SendData( SPI1, Data ) ; // Wait to receive a byte while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) == RESET ) ; // Return the byte read from the SPI bus return SPI_I2S_ReceiveData( SPI1 ) ;  #else SPI1_TX_Buff[0] = Data; SPI1_ReceiveSendByte(1); return (SPI1_RX_Buff[0]); #endif}//SPI读取Len字节void SPI_ReadBytes( uint8 Addr, NtrxBufferPtr Buffer, uint8 Len ){ #ifndef SPI_DMA if( ( Len > 0x80 ) || ( Len == 0 ) )  Len = 1 ; SPI_SendByte( Len ) ; SPI_SendByte( Addr ) ; while( Len-- )     {      *Buffer = SPI_SendByte( 0xFF ) ;  Buffer ++ ; } #else uint8 i = 0; if( ( Len > 0x80 ) || ( Len == 0 ) )  Len = 1 ; SPI1_TX_Buff[0] = Len; SPI1_TX_Buff[1] = Addr; SPI1_ReceiveSendByte(Len + 2); for (i = 0;i < Len;i++) {   *Buffer++ = SPI1_RX_Buff[i + 2];  } #endif}
           

给我老师的人工智能教程打call!

这里写图片描述
你可能感兴趣的文章
LTE - CSFB技术
查看>>
GSM链路层信令协议
查看>>
技术道德
查看>>
“需求为王”才是根本
查看>>
高效率的危害
查看>>
寻找边缘性创新
查看>>
让创意瞄准市场
查看>>
高效经理人应具有的八个重要习惯
查看>>
优秀的领导者能读懂人才
查看>>
大智若愚也是领导力
查看>>
android如何编译MTK的模拟器
查看>>
android如何添加AP中要使用的第三方JAR文件
查看>>
利用sudo命令为Ubuntu分配管理权限
查看>>
Ubuntu下几个重要apt-get命令用法与加速UBUNTU
查看>>
Ubuntu中网页各种插件安装命令
查看>>
使用tar命令备份Ubuntu系统
查看>>
ubuntu flash 文字乱码解决方案
查看>>
在ubuntu中运行exe文件
查看>>
ubuntu安装命令
查看>>
Android学习笔记(四十):Preference的使用
查看>>