智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 11238|回复: 31
打印 上一主题 下一主题

由于摄像头不小心烧掉了,心情比较黯淡......这是说好的源码。

  [复制链接]

32

主题

195

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1814
QQ
威望
1068
贡献
342
兑换币
143
注册时间
2010-12-30
在线时间
202 小时
跳转到指定楼层
1#
发表于 2012-4-2 18:19:36 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
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摄像头....................................................

0

主题

15

帖子

0

精华

注册会员

Rank: 2

积分
168
威望
95
贡献
41
兑换币
52
注册时间
2014-11-10
在线时间
16 小时
毕业学校
广东技术师范学院
32#
发表于 2015-2-2 10:04:03 | 只看该作者
赞一个
回复 支持 反对

使用道具 举报

0

主题

15

帖子

0

精华

注册会员

Rank: 2

积分
168
威望
95
贡献
41
兑换币
52
注册时间
2014-11-10
在线时间
16 小时
毕业学校
广东技术师范学院
31#
发表于 2015-2-2 10:03:54 | 只看该作者
赞一个
回复 支持 反对

使用道具 举报

11

主题

224

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2958

优秀会员奖章活跃会员奖章

威望
1538
贡献
888
兑换币
848
注册时间
2013-3-19
在线时间
266 小时
30#
发表于 2013-10-27 20:30:10 | 只看该作者
要是用硬件二值化,那怎么配置那个引脚用什么方式触发DMA
回复 支持 反对

使用道具 举报

7

主题

404

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1477
威望
626
贡献
623
兑换币
309
注册时间
2013-3-8
在线时间
114 小时
29#
发表于 2013-3-16 12:11:18 | 只看该作者
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

高级会员

Rank: 4

积分
869
威望
446
贡献
221
兑换币
165
注册时间
2012-7-23
在线时间
101 小时
毕业学校
安徽师范大学
28#
发表于 2013-3-16 10:47:10 | 只看该作者
已经解决
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

高级会员

Rank: 4

积分
869
威望
446
贡献
221
兑换币
165
注册时间
2012-7-23
在线时间
101 小时
毕业学校
安徽师范大学
27#
发表于 2013-3-16 10:22:01 | 只看该作者
楼主您好,有个问题请教下,您是怎么确定外设是多少号请求的?比如AD是40号请求,在手册上没找到
回复 支持 反对

使用道具 举报

32

主题

195

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1814
QQ
威望
1068
贡献
342
兑换币
143
注册时间
2010-12-30
在线时间
202 小时
26#
 楼主| 发表于 2012-11-22 19:55:03 | 只看该作者
J-sir 发表于 2012-11-20 23:53
楼主你好,我看你设置的AD的是8位模式,你的摄像头数据线电压大约是什么范围啊?我用OV5116,数据线输出的电 ...

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

使用道具 举报

5

主题

150

帖子

0

精华

高级会员

Rank: 4

积分
730
QQ
威望
409
贡献
183
兑换币
139
注册时间
2012-9-12
在线时间
69 小时
25#
发表于 2012-11-20 23:53:19 | 只看该作者
楼主你好,我看你设置的AD的是8位模式,你的摄像头数据线电压大约是什么范围啊?我用OV5116,数据线输出的电压有点低,用8位的话会不会精度太低?如果用16位的话会不会比较麻烦?比如上位机一般没有适用于16位的……
回复 支持 反对

使用道具 举报

8

主题

126

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1417
QQ
威望
749
贡献
308
兑换币
100
注册时间
2011-3-7
在线时间
180 小时
24#
发表于 2012-6-20 14:26:05 | 只看该作者
辛苦你了~希望我也可以ok
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2025-1-4 12:41 , Processed in 0.075457 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表