DSP

UART接口定义为DMA模式接收数据

2019-07-13 18:33发布

问题是这样:我把BF533的UART接口定义为DMA模式接收数据,但是接收到的数据总是零. 我不知道是不是我的配置有问题. 
  请高手指点一下.多谢. 配置如下:
void Init_DMA(void)
{
    *pDMA6_PERIPHERAL_MAP = 0x6000;
    *pDMA6_CONFIG = WDSIZE_8 |DI_EN ; (传输大小为字节 | 接收完成产生中断)
    *pDMA6_X_COUNT = 0xa; (大小为10个字节的buffer)
    *pDMA6_X_MODIFY = 1;
}
main()
{
   unsigned char rec_buffer[10];
   Init_DMA( );
  
   .......
   *pDMA6_START_ADDR = (unsigned char *)rec_buffer; (DMA的开始地址)
   *pDMA6_CONFIG = (*pDMA6_CONFIG | DMAEN); (DMA使能)
   *pUART_IER = 0x1;  (第一次,请求数据)
   while(*pDMA6_IRQ_STATUS&0x8); (等待完成)
   ............
}
通过超级终端给BF533发数据,无论键入什么字符,当DMA完成后,查看数组rec_buffer的值.全都是零..不知道是为什么. 请高手指点一下! 谢谢~ ------------------------------------------------------------------------------- 注意每句MMR赋值语句后面要加入ssync ------------------------------------------------------------------------------- 都加了SSYNC后,调试还是收不到数据. 我在每句Memory-mapped Registers操作的语句后面都加了SSYNC语句.调试,还是不行.不知道为什么. 单步到while(*pDMA6_IRQ_STATUS&0x8);  通过串口给blackfin输入10个字符后,就能跳出这个while循环,按理应该收到了数据才对.但是读那个数组,却全都是0.不知道为什么. 请大家给点意见啊~  谢谢~ ------------------------------------------------------------------------------- VDSP里面有UART通信的例子的 在安装目录的samples里面,听听ADI的那个视频教程 -------------------------------------------------------------------------------  我搜了一下,在我的安装路径下面找不到你说的例子程序.有两个samples文件夹,但是不是blackfin处理器的.我也进去看了一下.里面的代码没有设计到UART.  

   我的VisualDSP的版本是4.0的.不知道是不是我们的版本不一样.所以没有找到呢?

    我试过把UART配置成DMA发送的模式,通过串口打印.就可以实现.但是用UART来接收数据,却总是零. 还是没有找到什么地方出现问题了.郁闷~~
  ------------------------------------------------------------------------------- 配置DMA没必要加ssync();
你的DMA应该是配置成AUTOBUFFER模式的吧?既然使能了中断为什么还用
while(*pDMA6_IRQ_STATUS&0x8);呢?
程序好像有点乱,建议搭建一个正规的框架,DMA中断加不加无所谓,使能DMA一次后就不用再使能了,使能UART前先使能DMA
------------------------------------------------------------------------------- VDSP里面确实没有c语言的DMA模式UART范例,还是我来给你吧
/*Headerfile declarations*/
#include
#include
#include
#include
#include
/* Input CLK frequency */
#define CLKIN 27000000 // 27 MHz
/* UART Baud Rate Selection */
#define BAUD_RATE 115200 // 115.2 Kbps
//#define BAUD_RATE 921600 // 921.6 Kbps
typedef signed char int8_t;
typedef short int16_t;
typedef long int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
#define TXLEN 256 #define RXLEN 2560 #define ssync() asm("ssync;") EX_INTERRUPT_HANDLER(Uart_Dma_Isr_Tx);
EX_INTERRUPT_HANDLER(Uart_Dma_Isr_Rx);
void Init_Interrupts();
void Init_Dma_Tx();
void Init_Dma_Rx();
void Init_Uart();
/*Buffers*/
unsigned char AutobufferTx[TXLEN]={
#include"data.dat"
};
unsigned char AutobufferRx[RXLEN];

void main()
{
Init_Interrupts();
Init_Dma_Tx();
Init_Dma_Rx();
Init_Uart();
while(1)
{
asm("nop;");
}
}
void Init_Interrupts()
{
*pSIC_IAR1 = 0x34666666;//DMA6(uartrx),
//DMA7(uarttx)
ssync();
register_handler(ik_ivg10, Uart_Dma_Isr_Tx);
register_handler(ik_ivg11,Uart_Dma_Isr_Rx);
*pSIC_IMASK = 0x0000c000;//DMA6(uartrx) & DMA7(uarttx)
ssync();
}
/*Transmit isr*/
EX_INTERRUPT_HANDLER(Uart_Dma_Isr_Tx)
{
/* Clear Transmit Interrupt */
*pDMA7_IRQ_STATUS = 0x3;
ssync();
}
/*Receive isr*/
EX_INTERRUPT_HANDLER(Uart_Dma_Isr_Rx)
{
/* Clear Receive Interrupt */
*pDMA6_IRQ_STATUS = 0x3;
ssync();
}
/*Uart Tx init*/
void Init_Dma_Tx()
{
int Ttemp;
*pDMA7_CONFIG=0x1080; /* Ena autobuff,linear block,8bit,Source */
ssync();
*pDMA7_PERIPHERAL_MAP=0x7000;/*UART-TX*/
ssync();
*pDMA7_X_COUNT = TXLEN;
ssync();
*pDMA7_X_MODIFY = 1;/*Linear*/
ssync();
*pDMA7_Y_COUNT = 0;
ssync();
*pDMA7_Y_MODIFY = 0;
ssync();
/* enable sport0_dma_start_hi_addr */
*pDMA7_START_ADDR = AutobufferTx;
ssync();
Ttemp = *pDMA7_CONFIG;
*pDMA7_CONFIG=(Ttemp|0x01);/*Enable DMA*/
//*pDMA7_CONFIG=0x1081;
ssync();
}
/*Uart rx init*/
void Init_Dma_Rx()
{
int Ttemp;
*pDMA6_CONFIG=0x1082; /* Ena autobuff,linear block,8bit,Destination */
//*pDMA6_CONFIG=0x1052;testing
ssync(); *pDMA6_PERIPHERAL_MAP=0x6000;/*UART-RX*/
ssync();
*pDMA6_X_COUNT = RXLEN;//LEN;
ssync();
*pDMA6_X_MODIFY = 1;/*Linear*/
ssync();
*pDMA6_Y_COUNT = 0;
ssync();
*pDMA6_Y_MODIFY = 0;
ssync();
/* enable sport0_dma_start_hi_addr */
*pDMA6_START_ADDR = AutobufferRx;
ssync();
Ttemp = *pDMA6_CONFIG;
*pDMA6_CONFIG=(Ttemp|0x01);/*Enable DMA*/
//*pDMA7_CONFIG=0x1083;
ssync();
}
 
/*Uart driver initialization*/
void Init_Uart()
{
uint32_t divisor; // Uses to hold the calculated divisor value
uint8_t msel; // Multiplier MSEL[5:0] of PLL_CTL register[14:9]
uint8_t ssel; // Divisor SSEL[3:0] of PLL_DIV register[3:0]
/* Line Control Setup : 8-bit data, no parity, 1 stop bit */
*pUART_LCR = 0x0083;

/* Read the MSEL from PLL_CTL register */ msel = (*pPLL_CTL)>>9; // Read MSEL[5:0] from PLL_CTL
msel &= 0x3F; // Clear all bits except msel[5:0]
/* Read SSEL from PLL_DIV register */
ssel = *pPLL_DIV;
ssel &= 0x0F; // Clear all bits except ssel[3:0]
/* divisor calculation:
* SCLK = (msel * CLKIN)/ssel if DF = 0
* SCLK = (msel * CLKIN/2)/ssel if DF = 1
* divisor = SCLK/(16 * BAUD_RATE)
*/
divisor = ((msel * CLKIN)/(ssel * 16 * BAUD_RATE));
if(*pPLL_CTL & 0x1) // If DF = 1, CLKIN/2 is going to PLL
{
divisor /= 2; // Divide by 2
}
/* Baud Rate Setup: 115.2 Kbps */
*pUART_LCR |= DLAB; // Enable Divisor Latch Access
*pUART_DLL = divisor;
ssync();
*pUART_DLH = (divisor>>8);
ssync();
*pUART_LCR &= ~DLAB;// Disable Divisor Latch Access
ssync();
*pUART_IER =0x3;//Enable interrupts for receive & transmit //*pUART_IER =0x2;//Enable interrupts for transmit //*pUART_IER =0x1;//Enable interrupts for receive ssync();
*pUART_GCTL = UCEN;/*UART Clock enable*/
ssync();
} ------------------------------------------------------------------------------- 非常感谢楼上各位的指导,在调试了oppop的代码后,坚信硬件没有问题后,对比了一下oppop的代码.原来我把DMA的方向设置反了.晕.....非常感谢各位的帮助