智能车制作

标题: 由于摄像头不小心烧掉了,心情比较黯淡......这是说好的源码。 [打印本页]

作者: liu_fanyi    时间: 2012-4-2 18:19
标题: 由于摄像头不小心烧掉了,心情比较黯淡......这是说好的源码。
ccd+ad+dma,已经成功出图像了。串口的那个函数我就不发了。不能直接下载到板子上,我就是挑有用的部分发上来了。函数太多,都发上来会混乱

主程序:
#include "common.h"
//#include "HAL_ADC.h"
#include "liu_adc.h"
#include "uart.h"
#include "HAL_GPIO.h"
#include "dma.h"
//函数定义
void init_pwm(void);
void delay(void);

//全局变量
uint16 dma_r_m=0;
uint8 video[21000];//[140][ROW];
//uint16 a[10000], *p=a, *q;
/********************************************************************/

void main (void)
{

   //初始化 ADC
  DisableInterrupts;
  LPLD_GPIO_Init(PORTA_BASE_PTR, 5, 0, 0, 0x9);
  LPLD_GPIO_Init(PORTE_BASE_PTR, 26, 0, 0, 0x9);
  LIU_ADC_Init(ADC0_BASE_PTR, MODE_8, 0);
  //使能中断
  enable_irq(91); //GPIOE 向量号为 107. IRQ# is 107-16=91
  EnableInterrupts;
  while(1){
   
  }
}

dma.h:
#ifndef __DMA_H__
#define __DMA_H__
#include "common.h"
#include "dma_channels.h"
#define ROW 160
/********************************************************************/

void dma_init ();
/********************************************************************/

#endif /* __DMA_H__ */

dma.c:
#include "dma.h"


extern uint8 video[21000];//video[140][ROW];
void dma_init(){
  SIM_SCGC6|=SIM_SCGC6_DMAMUX_MASK;//打开DMA多路复用器时钟
  SIM_SCGC7|=SIM_SCGC7_DMA_MASK;//打开DMA模块时钟
  DMAMUX_CHCFG0=DMAMUX_CHCFG_SOURCE(40);//DMA通道0对应40号DMA请求,即ADC0
  DMA_TCD0_SADDR = (uint32_t)&(ADC_R_REG(ADC0_BASE_PTR, 0));
  
  DMA_TCD0_SOFF = 0;//每次传送源地址不变
  DMA_TCD0_CITER_ELINKNO=DMA_CITER_ELINKNO_CITER(ROW);//当前主循环次数,采集点数
  DMA_TCD0_BITER_ELINKNO=DMA_BITER_ELINKNO_BITER(ROW);//起始主循环次数,采集点数
  DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0);//源数据宽度8bit,目的数据宽度8bit
  DMA_TCD0_NBYTES_MLNO = DMA_NBYTES_MLNO_NBYTES(1);//每次读取一字节
  DMA_TCD0_SLAST = 0;//主循环结束后源地址0回写tcd
  DMA_TCD0_DLASTSGA = 0;
  DMA_TCD0_DADDR=(uint32)video;//设置目的地址,video数组第一个元素
  DMA_TCD0_DOFF=1;//每次写目的地址加1
  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_TCD0_CSR|=DMA_CSR_START_MASK;
}

liu_adc.c:
#include "common.h"
#include "liu_adc.h"

tADC_Config Adc0_Config;
tADC_Config Adc1_Config;

uint8_t LIU_ADC_Init(ADC_MemMapPtr adcmap,uint8_t mode, uint8_t diff){
  
  //开启ADC模块时钟
  if (adcmap == ADC0_BASE_PTR){
    SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK);//系统时钟门控制寄存器6,adc0标志位设为1
  }
  else  return 0;
  
  //校准
  ADC_Cal(adcmap);
  //初始化ADC
  //sc2
  ADC_SC2_REG(adcmap) &=  ~ADC_SC2_ADTRG_MASK;
  ADC_SC2_REG(adcmap) |= (ADTRG_SW | ACFE_DISABLED | ACFGT_LESS | ACREN_DISABLED | DMAEN_ENABLED | ADC_SC2_REFSEL(REFSEL_EXT));
  //sc3
  
  ADC_SC3_REG(adcmap) &= (~ADC_SC3_AVGE_MASK & ~ADC_SC3_AVGS_MASK);
  ADC_SC3_REG(adcmap) |=  CAL_OFF | ADC_SC3_ADCO_MASK;
  //sc1
  ADC_SC1_REG(adcmap,A) |= (AIEN_OFF | DIFF_SINGLE) ;
  ADC_SC1_REG(adcmap,B) |= (AIEN_OFF | DIFF_SINGLE) ;
  ADC_SC1_REG(adcmap,A) &= ~(ADC_SC1_ADCH_MASK);
  //cfg1
  ADC_CFG1_REG(adcmap) |= ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_1) | ADLSMP_SHORT | ADC_CFG1_ADICLK(ADICLK_BUS) | ADC_CFG1_MODE(MODE_8);
  //cfg2
  ADC_CFG2_REG(adcmap) |= MUXSEL_ADCA | ADACKEN_ENABLED | ADHSC_NORMAL;
  
  return 1;  
}

uint16_t LIU_ADC_SE_Get(ADC_MemMapPtr adcmap, uint8_t channel){

  if (channel>30)
    return 0;

  ADC_SC2_REG(adcmap) |= DMAEN_ENABLED;
  if (adcmap == ADC0_BASE_PTR){
    SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
    PORT_PCR_REG(PORTA_BASE_PTR, channel-3) = PORT_PCR_MUX(0);
  }

  ADC_SC1_REG(adcmap,A) |= ADC_SC1_ADCH(channel);
  
  return ADC_R_REG(adcmap, 0);
}


isr.c:
#include "isr.h"

extern uint8 video[21000];//140][ROW];
extern uint16 dma_r_m;
int i, j, na = 0, video2[9900], *p=video2;
uint16 row = 0, line = 0;

void AD0_isr(void){
  /*//int a= 30000;
  //int b= 200;
  //DisableInterrupts;
  //disable_irq (57);
  //uart_putchar (UART5_BASE_PTR, 'A');
  //ADC_SC1_REG(ADC0_BASE_PTR, A) &= ~(ADC_SC1_COCO_MASK);
  //ADC_SC1_REG(ADC0_BASE_PTR, A) &= ~(ADC_SC1_ADCH_MASK);
  //uart_putchar (UART5_BASE_PTR, result);
  //while(a--);
    //while(b--);
  result = ADC_R_REG(ADC0_BASE_PTR, 0);//获得结果寄存器里的结果
  //uart_putchar (UART5_BASE_PTR, result);//通过串口输出
  //if (result == '\n')
  //  result+=0x01;
  //if ((row >= 3 && row < 15) && (line >= 28 && line < 128)){
  if ((row >= 5 && row <50) && (line >=20 && line < 140)){
    *p=result;p++;}
  if (na == 1)
    row++;
  //}
  //else row++;
  //开启porta系统时钟使能
  //SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
  //PORT_PCR_REG(PORTA_BASE_PTR, 7) = PORT_PCR_MUX(0);
  ADC_SC1_REG(ADC0_BASE_PTR,A) |= ADC_SC1_ADCH(10);//对adce10进行转换
  // *p = result; p++;
  //LIU_ADC_SE_Get(ADC0_BASE_PTR, 10);
  
  //enable_irq(57);
  //EnableInterrupts;//开启adc中断*/
}

void DMA0_isr(void){
    DMA_INT|=DMA_INT_INT0_MASK;//清除通道0中断
        //uart_putchar(UART5_BASE_PTR, 0x80);
    //ADC_SC1_REG(ADC0_BASE_PTR,A) &= ~(ADC_SC1_ADCH_MASK);
    //row++;
    //uart_putchar(UART5_BASE_PTR,0xff);
    //for (i = 0;i < 55; i++)
      //*p++ = video[i];
   
    //  uart_putchar(UART5_BASE_PTR,video[i]);
    //uart_putchar(UART5_BASE_PTR,'\n');
    //disable_irq(91);
    //disable_irq(0);
    //for ( i = 0; i < 10; i++)
    //  for ( j = 0; j < ROW; j++)
    //    uart_putchar(UART5_BASE_PTR, video[i][j]);
}
void porta_isr(void){
  
  //disable_irq(57);
  PORTA_PCR5 |= PORT_PCR_ISF_MASK;
  //uart_putchar (UART5_BASE_PTR, ADC_R_REG(ADC0_BASE_PTR, 0));
  line++;
  if (line >= 20 && line < 90){
    //DMA_TCD0_CSR|=DMA_CSR_START_MASK;
    //dma_init();
    //DMA_TCD0_DADDR=(uint32)video;
    //DMA_TCD0_SADDR = (uint32_t)&(ADC_R_REG(ADC0_BASE_PTR, 0));
    //DMAMUX_CHCFG0=DMAMUX_CHCFG_SOURCE(40);
    //DMA_TCD0_CSR|=DMA_CSR_INTMAJOR_MASK;//使能DMA0中断
    //DMAMUX_CHCFG0|=DMAMUX_CHCFG_ENBL_MASK;//DMA通道0使能
   
    LIU_ADC_SE_Get(ADC0_BASE_PTR, 10);
    uart_putchar(UART5_BASE_PTR,ADC_R_REG(ADC0_BASE_PTR, 0));
    DMA_ERQ|=DMA_ERQ_ERQ0_MASK;

    //DMAMUX_CHCFG0|=DMAMUX_CHCFG_ENBL_MASK;
  }else if (line == 90){
    disable_irq(87);
  }
  /*na = 1;
    //na ^= 1;
  row = 0;
  line++;
    // *p = '\n'; p++;
    //LIU_ADC_SE_Get(ADC0_BASE_PTR, 10);
    //enable_irq(57);
  
  //else{
    //disable_irq(57);
    //na ^= 1;
    // *p= '\n'; p++;
   
    //n++;
  //}*/
}

void porte_isr(void){
  static int ne = 1;
  PORTE_PCR26 |= PORT_PCR_ISF_MASK;
  if(ne){
   ne^=1;
   dma_init();
   enable_irq(0);
   enable_irq (87);
   row = 0;
   line = 0;
   //LIU_ADC_SE_Get(ADC0_BASE_PTR, 10);
  }
  else{
    ne^=1;
    /*uart_putchar(UART5_BASE_PTR, 0x01);
    for (i = 0; i < 11200; i++){
      if (video[i] == 0x01)
        video[i] = 0x02;
      uart_putchar (UART5_BASE_PTR, video[i]);
    }
    uart_putchar(UART5_BASE_PTR, 0x01);*/
      //for (j = 0; j < 55; j++)
        //uart_putchar (UART5_BASE_PTR, video[i][j]);
    dma_r_m = 1;  
    uart_putchar (UART5_BASE_PTR, line);
    uart_putchar (UART5_BASE_PTR, row);
    disable_irq(91);
  }
}

isr.h:
#ifndef __ISR_H
#define __ISR_H

#include "common.h"
#include "liu_adc.h"
#include "uart.h"
#include "dma.h"

void AD0_isr(void);
void porta_isr(void);
void porte_isr(void);
void DMA0_isr(void);
#endif  //__ISR_H

/* End of "isr.h" */

程序还没整理,调试痕迹很重,大家先凑合看吧.....我再去整理整理程序的.....我可怜的ccd摄像头....................................................

作者: dongpinbo    时间: 2012-4-2 19:22

作者: 慕名凤姐而来    时间: 2012-4-2 19:22
沙发~
作者: 离傷    时间: 2012-4-3 13:43
请问楼主,你们摄像头接到单片机是几伏电压,K60貌似是3.3V的吧
作者: liu_fanyi    时间: 2012-4-4 07:12
离傷 发表于 2012-4-3 13:43
请问楼主,你们摄像头接到单片机是几伏电压,K60貌似是3.3V的吧

ccd摄像头输入12v,但是输出最多也就2.5v-3v,接在k60上无影响。我是自己拿示波器测的

作者: wayne11235    时间: 2012-4-4 15:57
顶一下
作者: lhx312126087    时间: 2012-4-12 22:40
楼主有k60关于那些关于寄存器设置的资料吗 发给我一下啊 就像设置pcr那些方法啊
作者: lhx312126087    时间: 2012-4-12 22:40
楼主有k60关于那些关于寄存器设置的资料吗 发给我一下啊 就像设置pcr那些方法啊
作者: liu_fanyi    时间: 2012-4-13 11:36
lhx312126087 发表于 2012-4-12 22:40
楼主有k60关于那些关于寄存器设置的资料吗 发给我一下啊 就像设置pcr那些方法啊

就是官方文档呀》。。。。。。。

作者: wukaijie    时间: 2012-4-13 13:58
为什么不用片外AD呀
作者: liu_fanyi    时间: 2012-4-14 03:58
wukaijie 发表于 2012-4-13 13:58
为什么不用片外AD呀

因为片内ad就够了....
作者: 568581185    时间: 2012-4-18 10:40
能不能加楼主QQ交流交流呢?我也用的CCD
没用外部AD

作者: liu_fanyi    时间: 2012-4-18 14:48
568581185 发表于 2012-4-18 10:40
能不能加楼主QQ交流交流呢?我也用的CCD
没用外部AD

这个....我的qq是公开的呀...1025766910
作者: 568581185    时间: 2012-4-18 16:43
liu_fanyi 发表于 2012-4-18 14:48
这个....我的qq是公开的呀...1025766910

已经加了 ,楼主貌似不在的撒?

作者: liu_fanyi    时间: 2012-4-18 20:04
568581185 发表于 2012-4-18 16:43
已经加了 ,楼主貌似不在的撒?

恩...基本只有晚上能上线,其他时间要不上课要不做车
作者: 568581185    时间: 2012-4-22 16:42
没有行消隐么??
作者: loucyin    时间: 2012-4-23 09:42
学习一下:P
作者: 月嘉愚生    时间: 2012-5-8 23:50
请问楼主是怎么触发DMA的啊,我知道有人用像素中断触发DMA,有人用PIT触发,我有点不知所措啊,特向楼主求助
作者: liu_fanyi    时间: 2012-5-9 19:54
月嘉愚生 发表于 2012-5-8 23:50
请问楼主是怎么触发DMA的啊,我知道有人用像素中断触发DMA,有人用PIT触发,我有点不知所措啊,特 ...

用ad内部有寄存器,ad对应的dma寄存器打开,ad就自动触发中断

作者: 月嘉愚生    时间: 2012-5-9 21:05
楼主太强大了,今天刚刚看到datasheet里面有点不明白,现在明白了!
作者: 月嘉愚生    时间: 2012-5-10 18:33
楼主,我用的片内AD,用的是ADC0,PB0,但是我在DMA_TCD0_SADDR = (uint32_t)&(ADC_R_REG(ADC0_BASE_PTR, 0));这一句里面读到的AD值为0;还请楼主赐教
作者: chengeng0910    时间: 2012-6-2 14:34
楼主好人啊  绝对要顶一下
作者: 大牙大    时间: 2012-6-2 16:00
顶了~~
作者: 冰水混合物    时间: 2012-6-20 14:26
辛苦你了~希望我也可以ok
作者: J-sir    时间: 2012-11-20 23:53
楼主你好,我看你设置的AD的是8位模式,你的摄像头数据线电压大约是什么范围啊?我用OV5116,数据线输出的电压有点低,用8位的话会不会精度太低?如果用16位的话会不会比较麻烦?比如上位机一般没有适用于16位的……
作者: liu_fanyi    时间: 2012-11-22 19:55
J-sir 发表于 2012-11-20 23:53
楼主你好,我看你设置的AD的是8位模式,你的摄像头数据线电压大约是什么范围啊?我用OV5116,数据线输出的电 ...

8位的精度够了...你做二值之后就2位精度了。
我的输出电压是2v左右,你是数字的,输出电压应该是5v,k60支持5v输入,没啥问题.....

作者: 崑峒龙镜    时间: 2013-3-16 10:22
楼主您好,有个问题请教下,您是怎么确定外设是多少号请求的?比如AD是40号请求,在手册上没找到
作者: 崑峒龙镜    时间: 2013-3-16 10:47
已经解决
作者: ╘记得↘→开朗    时间: 2013-3-16 12:11

作者: luyu    时间: 2013-10-27 20:30
要是用硬件二值化,那怎么配置那个引脚用什么方式触发DMA
作者: shuang    时间: 2015-2-2 10:03
赞一个
作者: shuang    时间: 2015-2-2 10:04
赞一个




欢迎光临 智能车制作 (http://111.231.132.190/) Powered by Discuz! X3.2