OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3516|回复: 7

SPI的TI模式主机程序,采用DMA。

[复制链接]

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2019-11-21 14:08:41 | 显示全部楼层 |阅读模式
昨天下午调试了SPI的TI模式程序。实现主机的发送和接收数据。
#include "spi1.h"
#include "led.h"
#include "dma.h"
#include "exti.h"
#include "delay.h"
#include "string.h"
//以下是SPI模块的初始化代码,配置成主机模式         
//SPI口初始化
//这里针是对SPI1的初始化
SerialBuf1 SPIBuf1;
void SPI1_Init(void)
{  
     u16 tempreg=0;
     RCC->AHB1ENR|=1<<0;     //使能PORTA时钟   
     RCC->APB2ENR|=1<<12;    //SPI1时钟使能
     
     GPIO_Set(GPIOA,0x0F<<4,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PA5~7复用功能输出
     GPIO_AF_Set(GPIOA,4,5); //PA5,AF5
     GPIO_AF_Set(GPIOA,5,5); //PA5,AF5
     GPIO_AF_Set(GPIOA,6,5); //PA6,AF5
     GPIO_AF_Set(GPIOA,7,5); //PA7,AF5
   
     //这里只针对SPI口初始化
     RCC->APB2RSTR|=1<<12; //复位SPI11
     RCC->APB2RSTR&=~(1<<12);//停止复位SPI1
     //tempreg|=0<<10;   //全双工模式
     //tempreg|=1<<9;   //软件nss管理
     //tempreg|=1<<8;   
     tempreg|=(1<<2);   //SPI主机 -------------------------------
   
     tempreg|=0<<11;  //8位数据格式 ------------------------------
   
     //tempreg|=1<<1;   //空闲模式下SCK为1 CPOL=1
     //tempreg|=1<<0;   //数据采样从第2个时间边沿开始,CPHA=1  
     //对SPI1属于APB2的外设.时钟频率最大为84Mhz频率.
     //tempreg|=5<<3;   //Fsck=Fpclk1/2    10.5M
     tempreg|=6<<3;   //Fsck=Fpclk1/256 --------------------------
     
     //tempreg|=0<<7;   //MSB First  
     tempreg|=1<<6;     //SPI启动
     
  //  SPI1->CR1=tempreg;  //设置CR1  
  //  SPI1->SR&=~RXNE;
     SPI1->CR2|=0x03;     //TXDMAEN,RXDMAEN
     SPI1->CR2|=1<<4;     //FRF
     SPI1->CR1=tempreg;   //设置CR1
     SPI1->I2SCFGR&=~(1<<11);//选择SPI模式
   
//    MYDMA_Config(DMA2_Stream0,3,(u32)&SPI1->DR,(u32)SPIBuf1.RecBuf,255,DMA_DIR_PeripheralToMemory,NormalMode,Size_Byte);   //
//    DMA2_Stream0->CR|=1<<0;      //开启DMA传输
//    DMA2->LIFCR|=1<<5;
//    MY_NVIC_Init(3,2,DMA2_Stream0_IRQn,2);  //抢占3,子优先级2,组2
//    DMA2_Stream0->CR|=1<<4;  
//    memset(SPIBuf1.SendBuf,0,256);
}  
//SPI1速度设置函数
//SpeedSet:0~7
//SPI速度=fAPB2/2^(SpeedSet+1)
//fAPB2时钟一般为84Mhz
void SPI1_SetSpeed(u8 SpeedSet)
{
  SpeedSet&=0X07;   //限制范围
  SPI1->CR1&=0XFFC7;
  SPI1->CR1|=SpeedSet<<3; //设置SPI1速度  
  SPI1->CR1|=1<<6;   //SPI设备使能   
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{      
  while((SPI1->SR&1<<1)==0);  //等待发送区空
  SPI1->DR=TxData;           //发送一个byte  
  while((SPI1->SR&1<<0)==0);  //等待接收完一个byte  
  return SPI1->DR;            //返回收到的数据        
}
void StatusCheck(void)
{
     if(SPIBuf1.TXflage)
     {
        SPIBuf1.Status=TXStatus;
     }
     else if(SPIBuf1.RXflage)
     {
         SPIBuf1.Status=RXStatus;
     }
     else
     {
        SPIBuf1.Status=IDILStatus;
     }      
     
}
void SPI_ReceiveSendByte(u8 num,u8 Data[])
{
     //CS0=0;
     //while(flage==0);
     //flage=0;
     DMA2->LIFCR|=1<<27;
     DMA2_Stream3->CR&=~(1<<0);       //关闭发关DMA传输
     //DMA2->LIFCR|=1<<5;
     //DMA2_Stream0->CR&=~(1<<0);      //关闭接收DMA传输
     //SPIBuf1.TXflage|=1;
     //StatusCheck();
     MYDMA_Config(DMA2_Stream3,3,(u32)&SPI1->DR,(u32)Data,num,MemoryToDMA_DIR_Peripheral,NormalMode,Size_Byte);
     DMA2_Stream3->CR|=1<<0;      //开启DMA传输
     MY_NVIC_Init(3,2,DMA2_Stream3_IRQn,2);  //抢占3,子优先级2,组2
     DMA2_Stream3->CR|=1<<4;

//     MYDMA_Config(DMA2_Stream0,3,(u32)&SPI1->DR,(u32)SPIBuf1.RecBuf,255,DMA_DIR_PeripheralToMemory,NormalMode,Size_Byte);   //
//     DMA2_Stream0->CR|=1<<0;      //开启DMA传输
//     MY_NVIC_Init(3,2,DMA2_Stream0_IRQn,2);  //抢占3,子优先级2,组2
//     DMA2_Stream0->CR|=1<<4;  
     //CS0=1;
}
void DMA2_Stream0_IRQHandler(void)     //RX
{
    if(DMA2->LISR&(1<<5))
   {
    DMA2->LIFCR|=1<<5;
     MYDMA_Enable(DMA2_Stream0,255);
   }
}
void DMA2_Stream3_IRQHandler(void)     //TX
{
    if(DMA2->LISR&(1<<27))
    {
       DMA2->LIFCR|=1<<27;
       CS0=1;
//       if(SPIBuf1.Status==TXStatus)
//       {
//          if(SPIBuf1.TXflage)
//          {
//             SPIBuf1.TXflage=0;
//             if(SPIBuf1.RXflage)
//             {
//                MYDMA_Config(DMA2_Stream0,3,(u32)&SPI1->DR,(u32)SPIBuf1.RecBuf,255,DMA_DIR_PeripheralToMemory,NormalMode,Size_Byte);   //
//                DMA2_Stream0->CR|=1<<0;      //开启DMA传输
//                DMA2->LIFCR|=1<<5;
//                MY_NVIC_Init(3,2,DMA2_Stream0_IRQn,2);  //抢占3,子优先级2,组2
//                DMA2_Stream0->CR|=1<<4;
//                SPI_ReceiveSendByte(255,SPIBuf1.SendBuf);
//                SPIBuf1.Status=RXStatus;
//             }
//             else
//             {
//                SPIBuf1.Status=IDILStatus;
//             }
//          }
//                  
//       }
//       else if(SPIBuf1.Status==RXStatus)
//       {
//           
//       }
//     if(SPIBuf1.RXflage==0)
//    {
//      DMA2_Stream3->CR&=~(1<<0);   //关闭DMA传输
//      SPIBuf1.TXflage&=0xfe;
//    }
//     else
//    {
//     if(SPIBuf1.TXflage==0x81)
//     {
//        SPIBuf1.TXflage&=0xfe;
//        MYDMA_Config(DMA2_Stream3,3,(u32)&SPI1->DR,(u32)SPIBuf1.SendBuf,255,MemoryToDMA_DIR_Peripheral,NormalMode,Size_Byte);
//        DMA2_Stream3->CR|=1<<0;          //开启DMA传输
//        MY_NVIC_Init(3,2,DMA2_Stream3_IRQn,2);  //抢占3,子优先级2,组2
//        DMA2_Stream3->CR|=1<<4;
//     }
//    }
//      SPIBuf1.TXflage=0;
//     LED0=~LED0;
    }
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

27

帖子

0

精华

高级会员

Rank: 4

积分
830
金钱
830
注册时间
2017-8-3
在线时间
145 小时
发表于 2019-11-21 18:37:18 | 显示全部楼层
请问一下,你注释掉的使用DMA接收功能有调通吗?
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
 楼主| 发表于 2019-11-21 18:50:33 | 显示全部楼层
是通的!
回复 支持 反对

使用道具 举报

4

主题

27

帖子

0

精华

高级会员

Rank: 4

积分
830
金钱
830
注册时间
2017-8-3
在线时间
145 小时
发表于 2019-11-21 20:08:09 | 显示全部楼层

我目前使用HAL库调试DMA接收,数据总是零。不清楚是Cache没处理好的问题还是接收没配置好
回复 支持 反对

使用道具 举报

0

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2018-12-5
在线时间
39 小时
发表于 2019-12-18 16:42:21 | 显示全部楼层
原子哥的例程是用的Motorola模式,请问亲,为什么使用TI模式,而且使用DMA通信。感谢。
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
 楼主| 发表于 2019-12-27 14:57:07 | 显示全部楼层
TI模式是硬件自动管理CS脚,双机通信时是硬件管理同步。
回复 支持 反对

使用道具 举报

7

主题

237

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1111
金钱
1111
注册时间
2019-5-6
在线时间
128 小时
发表于 2020-4-6 18:15:43 | 显示全部楼层
xuyan021 发表于 2019-12-27 14:57
TI模式是硬件自动管理CS脚,双机通信时是硬件管理同步。

楼主,留个微信或者QQ号,向您请教个问题
一步一个脚印
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-12-4
在线时间
56 小时
发表于 2020-9-25 15:21:29 | 显示全部楼层
楼主有没有库函数版的?寄存器版看不懂
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-16 18:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表