金牌会员
- 积分
- 1404
- 威望
- 656
- 贡献
- 612
- 兑换币
- 12
- 注册时间
- 2011-3-1
- 在线时间
- 68 小时
|
首先我采用的是摄像头的PCLK信号作为DMA的触发信号。
然后发现这个信号触发不了,用示波器一看,发现PCLK出来的是个三角波,而且周期是74ns.
所以触发不了,也是很正常的。
然后我就直接将HREF行中断信号作为触发DMA的请求信号。因为来一个行中断,这个时候就应该用DMA传送一行数据了。
结果我发现还是不行。因为还要使能通道:DMA_ERQ|=DMA_ERQ_ERQ0_MASK;//使能通道0硬件DMA请求
这就有问题了,因为一个是DMA的中断触发,和这个使能是个什么样的关系呢。
为了采到数据,我直接在主函数中先执行DMA_ERQ|=DMA_ERQ_ERQ0_MASK;
然后我始终只能采回来一行数据。
求解,该怎么做?
附上代码吧
/*
* ImageAcquisition.h
*
* Created on: 2012-3-27
* Author: damon
*/
#ifndef IMAGE_ACQUISITION_H
#define IMAGE_ACQUISITION_H
#include "derivative.h" /* include peripheral declarations */
#define ENDROW 240 //OV7620,每场240行
#define H 27
#define V 160
typedef unsigned char uint8; /* 8 bits */
typedef unsigned short int uint16; /* 16 bits */
typedef unsigned long int uint32; /* 32 bits */
typedef char int8; /* 8 bits */
typedef short int int16; /* 16 bits */
typedef long int int32; /* 32 bits */
unsigned int row=0;//摄像头行计数,最大240
uint8 video[H][V];//存放数据数组
unsigned int imagerow=0;//采集行计数,最大H
unsigned int const data_table[H]={46,53,68,83,97,109,120,130,139,147,
155,163,170,178,186,192,197,202,206,210,
214,218,222,225,228,231,234};//需采集数据的行,2cm一行实际测得
void caiji_IO_init()
{
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK ;
PORTA_PCR4= PORT_PCR_MUX(1)|PORT_PCR_IRQC(9); //A4引脚设置为GPIO模式,上升沿中断,行中断
PORTB_PCR10= PORT_PCR_MUX(1)|PORT_PCR_IRQC(10); //B10引脚设置为GPIO模式,下降沿中断,场中断
PORTA_PCR5=PORT_PCR_MUX(1)|PORT_PCR_IRQC(1); //A5引脚设置为GPIO模式,上升沿触发DMA请求
/*PTD0-PTD7 as GPIO input*/
PORTD_PCR0 = PORT_PCR_MUX(1); //PTD0 as open drain input
PORTD_PCR1 = PORT_PCR_MUX(1); //PTD1 as open drain input
PORTD_PCR2 = PORT_PCR_MUX(1); //PTD2 as open drain input
PORTD_PCR3 = PORT_PCR_MUX(1); //PTD3 as open drain input
PORTD_PCR4 = PORT_PCR_MUX(1); //PTD4 as open drain input
PORTD_PCR5 = PORT_PCR_MUX(1); //PTD5 as open drain input
PORTD_PCR6 = PORT_PCR_MUX(1); //PTD6 as open drain input
PORTD_PCR7 = PORT_PCR_MUX(1); //PTD7 as open drain input
GPIOD_PDDR = 0x0; //PTD0-PED7 as GPIO input;
}
void DMA0_Init(void)
{
SIM_SCGC6|=SIM_SCGC6_DMAMUX_MASK;//打开DMA多路复用器时钟
SIM_SCGC7|=SIM_SCGC7_DMA_MASK;//打开DMA模块时钟
DMAMUX_CHCFG0=DMAMUX_CHCFG_SOURCE(49);//DMA通道0对应49号DMA请求,即PORTA
DMA_TCD0_CITER_ELINKNO=DMA_CITER_ELINKNO_CITER(V);//当前主循环次数,采集点数
DMA_TCD0_BITER_ELINKNO=DMA_BITER_ELINKNO_BITER(V);//起始主循环次数,采集点数
DMA_TCD0_SADDR=(uint32)&GPIOD_PDIR;//设置源地址GPIO口,PORTD
DMA_TCD0_SOFF=0;//每次传送源地址不变
//DMA_TCD1_NBYTES_MLOFFYES=DMA_NBYTES_MLOFFYES_NBYTES(1)+DMA_NBYTES_MLOFFNO_SMLOE_MASK+DMA_NBYTES_MLOFFYES_MLOFF(-4);//传送4字节
DMA_TCD0_NBYTES_MLNO=DMA_NBYTES_MLNO_NBYTES(1);//每次读取一字节
DMA_TCD0_SLAST=0;//主循环结束后源地址0回写tcd
DMA_TCD0_DLASTSGA=0;//主循环结束后目的地址0回写tcd
DMA_TCD0_DADDR=(uint32)video;//设置目的地址,video数组第一个元素
DMA_TCD0_DOFF=1;//每次写目的地址加1
DMA_TCD0_ATTR=DMA_ATTR_SSIZE(0)+DMA_ATTR_DSIZE(0);//源数据宽度8bit,目的数据宽度8bit
DMA_TCD0_CSR=DMA_CSR_DREQ_MASK;//DMA通道0主循环结束后停止硬件请求
DMA_TCD0_CSR|=DMA_CSR_INTMAJOR_MASK;//使能DMA0中断
DMAMUX_CHCFG0|=DMAMUX_CHCFG_ENBL_MASK;//DMA通道0使能
DMA_ERQ|=DMA_ERQ_ERQ0_MASK;//使能通道0硬件DMA请求 (我在初如化的时候来开启,这样才进了中断,不然不能进中断。因为我用HREF来触发DMA,而又要在DMA中才来开启使能,所以进不了中断。我想这应该是原因)
}
void DMA_CHO_ISR(void)
{
DMA_INT|=DMA_INT_INT0_MASK;//清除通道0中断
row_F[imagerow]=1;//采集完成标志
imagerow++;
}
void enable_irq (int irq)
{
int div;
if (irq > 91) irq=91;//确定irq号为有效的irq号
div = irq/32;//确定对应的寄存器号
switch (div)
{
case 0x0:
NVICICPR0 = 1 << (irq%32);
NVICISER0 = 1 << (irq%32);
break;
case 0x1:
NVICICPR1 = 1 << (irq%32);
NVICISER1 = 1 << (irq%32);
break;
case 0x2:
NVICICPR2 = 1 << (irq%32);
NVICISER2 = 1 << (irq%32);
break;
}
}
//-------------------------------------------------------------------------*
//函数名: disable_irq *
//功 能: 禁止irq中断 *
//参 数: irq:irq号 *
//返 回: 无 *
//说 明: irq号不是中断向量号 *
//-------------------------------------------------------------------------*
void disable_irq (int irq)
{
int div;
//确定irq号为有效的irq号
if (irq > 91) irq=91;
//确定对应的NVICISER
div = irq/32;
switch (div)
{
case 0x0:
NVICICER0 = 1 << (irq%32);
break;
case 0x1:
NVICICER1 = 1 << (irq%32);
break;
case 0x2:
NVICICER2 = 1 << (irq%32);
break;
}
}
void PORTB_ISR(void)//场中断,B10,下降沿中断
{
PORTA_PCR5|=PORT_PCR_ISF_MASK;//清除中断标志
DMA0_Init();
enable_irq(0);//使能DMA通道0完成中断
row=0;//初始化行
imagerow=0;//初始化采集行
enable_irq (87);//使能A口中断 ,A4行中断
}
void PORTA_ISR(void)
{
PORTA_PCR4|=PORT_PCR_ISF_MASK;//清除中断标志位
row++; //行计数
if(row==data_table[imagerow])//如果当前行数据应该采集
{
DMA_ERQ|=DMA_ERQ_ERQ0_MASK;//使能通道0硬件DMA请求
}
else if(row>=ENDROW) //一场完成,关闭行中断
{
disable_irq (87);
}
}
void Delay(unsigned int count)
{
unsigned int i;
for(;count > 0;count--)
for(i = 0;i < 50000;i++);
}
#endif
//这个程序只能采集一行数据,求解解决方法
|
|