DMA转发OV7670二值化后的数据

2019-08-14 17:46发布

     小白最近要参加电赛弄OV7670好几天了,因为用的是mini板帧率非常低,所以不能直接用串口发送数据,想用DMA发送,但是发送的时候什么都发送不出来,但是用串口的printf函数能发送
#include "DMA.h"
#include "delay.h"

u16 DMA_Length=0;

void MYDMA_Init(DMA_Channel_TypeDef* DMA_CHx,u32 CPAR,u32 CMAR,u16 LEN)
{
        RCC->AHBENR|=1<<0;
        delay_ms(10);
        DMA_CHx->CPAR=(u32)CPAR;
        DMA_CHx->CMAR=(u32)CMAR;
        DMA_Length=LEN;
        DMA_CHx->CNDTR=DMA_Length;
        DMA_CHx->CCR=0x00000000;
        DMA_CHx->CCR|=1<<12;                                                                //优先级中
        DMA_CHx->CCR|=1<<7;                                                                        //指针增量递增
        DMA_CHx->CCR|=1<<4;                                                                                //初始化
//        DMA_CHx->CCR&=0<<0;
}

void MYDMA_EN(DMA_Channel_TypeDef* DMA_CHx)
{
        DMA_CHx->CCR&=0<<0;
        DMA_CHx->CNDTR=DMA_Length;
        DMA_CHx->CCR|=1<<0;        
}
这是配置函数


#include "sys.h"
#include "usart.h"               
#include "delay.h"       
#include "led.h"   
#include "lcd.h"
#include "ov7670.h"
#include "exti.h"
#include "cal_per_t.h"
#include "DMA.h"




extern u8 Pic_buf[H][V];                        //V=80 H=60


u16 BUF_LEN=sizeof(Pic_buf);
u8 YUV_Y,YUV_UV;
extern u8 postion;
extern u8 ov_sta;        //在exit.c里面定义
void camera_refresh(void)
{
        u8 x,y;
        if(ov_sta==2)
        {
                LCD_Scan_Dir(U2D_L2R);                //从上到下,从左到右
                LCD_SetCursor(0x00,0x0000);        //设置光标位置
                LCD_WriteRAM_Prepare();     //开始写入GRAM       
                OV7670_CS=0;         
                OV7670_RRST=0;                                //开始复位读指针
                OV7670_RCK=0;
                OV7670_RCK=1;
                OV7670_RCK=0;
                OV7670_RRST=1;                                //复位读指针结束
                OV7670_RCK=1;   
                for(x=0;x<120;x++)
                {
                        for(y=0;y<160;y++)
                        {
                                GPIOB->CRL=0X88888888;                  
                                OV7670_RCK=0;
                                YUV_Y=OV7670_DATA;                //读数据
                                OV7670_RCK=1;                                                   
                                OV7670_RCK=0;
                                YUV_UV=OV7670_DATA;                //读数据                  
                                OV7670_RCK=1;
                                GPIOB->CRL=0X33333333;
                                if((x%2)&&(y%2))
                                {
                                        if(((y/2)>14)&&((y/2)<65))
                                        {
                                                if(YUV_Y>L_THRESHOLD)
                                                {
                                                        LCD_WR_DATA(0xffff);       
                                                        Pic_buf[x/2][y/2]=0xff;                        //白
                                                }
                                                else
                                                {
                                                        LCD_WR_DATA(0x0000);
                                                        Pic_buf[x/2][y/2]=0x00;                        //黑
                                                }
                                        }
                                        else
                                        {
                                                LCD_WR_DATA(0xffff);
                                                Pic_buf[x/2][y/2]=0xff;       
                                        }
                                }
                                else
                                        LCD_WR_DATA(0x8430);
                        }
                }
                OV7670_CS=1;                                                          
                OV7670_RCK=0;
                OV7670_RCK=1;
                EXTI->PR=1<<15;                     //清除LINE8上的中断标志位
                ov_sta=0;                                        //开始下一次采集
                LCD_Scan_Dir(DFT_SCAN_DIR);        //恢复默认扫描方向                                                     
        }
}          
int main(void)
{       
        u8 i,j;       
        u16 pro=0;
  Stm32_Clock_Init(9);        //系统时钟设置
        uart_init(72,9600);                 //串口初始化为9600
        delay_init(72);                            //延时初始化
        LCD_Init();                                   //初始化LCD
        lcddev.width=120;
        lcddev.height=160;               
        while(OV7670_Init())//初始化OV7670
        {
          LCD_Fill(60,150,239,166,WHITE);
                delay_ms(200);
        }
        delay_ms(2000);                                                                                                        
        EXTI15_Init();                                                //使能定时器捕获
  OV7670_CS=0;       
                MYDMA_Init(DMA1_Channel4,(u32)&USART1->DR,(u32)Pic_buf,BUF_LEN);
        while(1)
        {       
                camera_refresh();        //更新显示       
                median_filter();                //中值滤波
                Get_black_line();                //寻黑线
                USART1->CR3|=1<<7;
                MYDMA_EN(DMA1_Channel4);
                switch (aut_choose_mod())
                {
                        case 0:{u8 i=go_stra();if(i)start_end_point2(i);}break;
                        case 1:start_end_point1(postion);break;
                        case 2:change_dir();break;
                }
                postion=0;
        }          
}

这是主函数,所有的配置都是按例程来的不知道为什么不行;



还有就是我接了摄像头以后烧进DMA例程以后,把PC5(KEY0的IO)的线拔 了以后摁KEY0的时候,DMA也不会发数据到串口,拔所有的线(除了摄像头的数据线D0-D7)以后,烧进去才可以,把例程改成在循环里不断执行也可以,但是复制到我的程序里就不行了。
用debug调试我写的程序的时候,发现DMA1_Channel4->CPAR,DMA1_Channel4->CMAR地址都是正确的,DMA1_Channel4->CNTDR寄存器初始化的时候赋值是正确的,但是在读取DMA1_Channel4->CNTDR的时候数值不太对,要么是4799,要么是4797,要么是0,(总量为4800)。另外USART1->DR寄存器的值一直为0,但是用printf函数能正常发送。查了半天数据手册也没发现什么不太对劲的地方,也不知道是有占用(我也把通道优先级调到最高过,也是没用,定时中断也没用,只有摄影头有个帧中断是外部中断PA15)还是怎么回事。


求大神指点一下。@正点原子
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。