我使用PDMA和SPI和下位通信,但是下位机总是只能接收到1个数据,谁能帮忙看下代码
//===================================================================
// File Name : spi.c
// Function : SPI通讯驱动
// By : lfy
// Date : 04, 10, 2015
// Version : 0.0
// History :
//===================================================================
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
//=======================
//#include "core/includes.h" /* uC/OS interface */
#include "ucos_ii.h"
//=======================
#include "lcd.h"
#include "smdong.h"
#include "sm.h"
#include "smgn1.h"
#include "glib.h"
#include "smpage.h"
#include "HmiStart.h"
#include "def.h"
#include "initmain.h"
#include "smHzk16.h"
#include "math.h"
#include "usbin.h"
#include "MsgShow.h"
#include "DataTransmissionC.h"
#include "Timer.h"
#include "Macro_File.h"
#include "UpLoadRecipeData.h"
#include "Penetrate.h"
#include "rtc.h"
#include "w55fa93_gpio.h"
#include "DrvEDMA.h"
#include "common.h"
#include "spi.h"
/*****************************************************************
SPI发送完成需要接收必须发送RX_COUNT个填充字节为从机提供CLK
例如可以发送:0xff
******************************************************************/
/********************************************************/
/*************下面是SPI的DMA数据结构***********************/
/********************************************************/
#define SPI_MAX_LENTH 8 //最大一次接收发送1K
#define SPI_TX_BASE (U32)(&SPI0_TX0)
#define SPI_RX_BASE (U32)(&SPI0_RX0)
/***************SPI发送错误码**************************/
#define SPI0_Right 0
#define SPI0_LenthError 1
#define SPI0_Busy 2
/*****************************************/
U8 SPI0_DMA_TX[SPI_MAX_LENTH]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}; //DMA发送内存池
U8 SPI0_DMA_RX[SPI_MAX_LENTH]; //DMA接收内存池
struct spi0 *SPI0;
static void EDMA_CH1_Enable(void)
{
PDMA_CSR1|=(1<<0);
}
static void EDMA_CH1_Disable(void)
{
PDMA_CSR1&=~(1<<0);
}
void EDMA_IRQHandler(void)
{
u8 tmp=0;
PDMA_ISR|=1<<1;
#if 0
if(SPI0->RW_Count < SPI0->RW_Lenth)
{
if(SPI0->IfWrRe==2)//读从设备
{
SPI0_DMA_RX[SPI0->RW_Count]=SPI0_RX0;
}
sysprintf("C\r\n");
SPI0->RW_Count+=1;
PDMA_CSR1|=(1<<23);
SPI0_EDMA|=(1<<0);
}
else
{
if(SPI0->IfWrRe==2)//读从设备
{
SPI0->Recive_Finish=1;//接收完成
}
PDMA_CSR1|=(1<<1); //Soft Reset
SPI0->IfWrRe=0;//读写和计数值复位
SPI0->RW_Count=0;
}
#endif
{
EDMA_CH1_Disable();
}
}
/*===================================================================
SPI读取从设备一般流程:
1:确定读取长度SPI0->RW_Lenth,注意不要超过设定最大值
2:OS轮询SPI0->Recive_Finish是否为1,则表示读取完成
3:调用SPI_Read,查看返回值,返回right表示读取成功,但并不表示读取完成
读取错误对应不同错误代码
4:轮询到SPI0->Recive_Finish=1即可从SPI0_DMA_RX[SPI_MAX_LENTH]取出数据
即可
====================================================================*/
u8 SPI_Read(void)
{
if(SPI0->RW_Lenth>SPI_MAX_LENTH)//大于约束长度
{
return SPI0_LenthError;
}
if(SPI0->IfWrRe==1)//正在写
{
return SPI0_Busy;
}
SPI0->IfWrRe=2;
SPI0->RW_Count=0;
PDMA_CSR1|=(1<<1); //Reset Point
PDMA_BCR=SPI0->RW_Lenth; //Lenth
PDMA_CSR1|=(1<<23); //Start DMA
SPI0_EDMA|=(1<<0);
return SPI0_Right; //此次返回值只代表发送执行,并不代表发送完成
}
/*===================================================================
SPI写从设备一般流程:
1:确定写入长度SPI0->RW_Lenth,注意不要超过设定最大值
2:对SPI0_DMA_TX[SPI_MAX_LENTH]进行赋值,注意格式为U8
3:调用SPI_Write,查看返回值,返回right表示写入成功,但并不表示写入完成
写入错误对应不同错误代码
====================================================================*/
u8 SPI_Write(void)
{
SPI0->RW_Lenth=8;
if(SPI0->RW_Lenth>SPI_MAX_LENTH)//大于约束长度
{
return SPI0_LenthError;
}
if(SPI0->IfWrRe==2)//正在读
{
return SPI0_Busy;
}
SPI0_EDMA&=~(1<<1);//write
PDMA_CSR1|=(1<<1); //Soft Reset
SPI0->IfWrRe=1;
SPI0->RW_Count=0;
PDMA_BCR=SPI0->RW_Lenth; //Lenth
PDMA_CSR1|=(1<<23); //Start DMA
SPI0_EDMA|=(1<<0);
return SPI0_Right; //此次返回值只代表发送执行,并不代表发送完成
}
void SPI0_PDMA_Init(void)
{
/*****************PDMA发送初始化,目的地址为TX0,源地址为内存池***********************/
PDMA_CSR1|=(1<<8);
PDMA_CSR1&=~(1<<8);//Rest DMA CH1
EDSSR|=(7<<0);
EDSSR&=~(7<<16);
SPI0_PDMACLK_ENABLE; //Enable CH1 CLK
PDMA_CSR1|=(1<<1); //Soft Reset
PDMA_CSR1|=(1<<0);
PDMA_CSR1|=(1<<19); //Width 8 bit
PDMA_CSR1|=(1<<3); //MEN--->APB
PDMA_SAR=(U32)SPI0_DMA_TX;//Source Address
PDMA_DAR=(U32)SPI_TX_BASE; //Direction Address
PDMA_CSR1|=(3<<4); //Source Address INC
PDMA_CSR1|=(1<<7); //Dir Address Fixed
PDMA_BCR=SPI_MAX_LENTH;
PDMA_CSR1|=(1<<12);
PDMA_IER|=1<<2;//使能传输完成和读写异常中断
PDMA_ISR|=1<<1;
PDMA_ISR|=1<<0;
sysInstallISR(IRQ_LEVEL_1, IRQ_EDMA, (PVOID)EDMA_IRQHandler);
sysEnableInterrupt(IRQ_EDMA);
/*****************PDMA发送初始化,目的地址为TX0,源地址为内存池***********************/
}
/*SYS_CLK=192MHZ , HCLK=96MHZ , PCLK=48MHZ*/
u8 SPI_Init(void)
{
U16 dat;
//delayy1(1000);delayy1(1000);delayy1(1000);delayy1(1000);delayy1(1000);
/*
GPIOD_12----SPI_CLK
GPIOD_13----SPI_CS
GPIOD_14----SPI_MISO
GPIOD_15----SPI_MOSI
打开内部上拉电阻,外部无上拉
*/
GPIOD_PUEN|=((1<<15)|(1<<14)|(1<<13)|(1<<12));
GPIOD_FUN&=~((3<<30)|(3<<28)|(3<<26)|(3<<24));
GPIOD_FUN|=((2<<30)|(2<<28)|(2<<26)|(2<<24));
GPIOD_OMD&=~(1<<14);//MISO
GPIOD_OMD|=(1<<12);//CLK
GPIOD_OMD|=(1<<13);//CS
GPIOD_OMD|=(1<<15);//MOSI
SPI0_CLK_ENABLE;//时钟使能
SPI0_SSR&=~(1<<2);//CS低电平片选
SPI0_CNTRL&=~(1<<18);//SPI_Master
SPI0_CNTRL&=~(1<<10);;//MSB Frist
SPI0_CNTRL|=(1<<2);//Tx信号在时钟下降沿改变
SPI0_CNTRL&=~(1<<1);//Rx信号在上升沿锁存//
SPI0_CNTRL&=~(3<<8);//1次传输1字节
SPI0_CNTRL|=(8<<3);//一次传输8bit
/*CLK=fPCLK/((DIV+1)*2)*/
SPI0_DIVIDER&=0xffff0000;
SPI0_DIVIDER|=1;//clk=48M/(2*2)=12M
SPI0_SSR &= ~(1<<3); //Slave Select non-auto
SPI0_PDMA_Init();
/*SPI参数复位*/
SPI0->Recive_Finish=0;
SPI0->IfWrRe=0;
SPI0->RW_Count=0;
dat=SPI_Write();
sysprintf("dat=%d\r\n",dat);
while(1);
}
|