OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11136|回复: 8

基于STM32的CCD调试

[复制链接]

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-5-8
在线时间
8 小时
发表于 2015-5-8 14:49:37 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]各位大侠 新手报到第一次发帖求助多多关照[/mw_shl_code] [mw_shl_code=c,true]最近在做线性CCD 各种程序模块还有程序流程都是按照蓝宙的示例改的[/mw_shl_code] [mw_shl_code=c,true]但是使用蓝宙的上位机一直没有出现数据,都快搞死了,求助啊,[/mw_shl_code] [mw_shl_code=c,true]
[mw_shl_code=c,true]////////////////////////////////////////////////////////////////////////////////// [/mw_shl_code] [mw_shl_code=c,true] [mw_shl_code=c,true]【main.c】[/mw_shl_code] [mw_shl_code=c,true]
[mw_shl_code=c,true]int main(void) { u8 i=0; delay_init(); //延时函数初始化 LED_Init(); CCD_Init(); TIM3_Int_Init(9,7199); NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(9600); //串口初始化为9600 while(1) { if (Time50_Flag==1) { i++; if(i==20){ LED1=!LED1;i=0;} Calculate_Exposure_Time(); //每50ms计算一次曝光时间 CCD_Get(); //图像采集 Send_Data(); Time50_Flag=0; } } }[/mw_shl_code] 这里有一点特别奇怪,把LED的程序放在定时器中断里面 LED就不会发生变化

///////////////////////////////////////////////////////////////////////////////[/mw_shl_code] [mw_shl_code=c,true]【time.c】[/mw_shl_code] [mw_shl_code=c,true]//定时器3中断服务程序 void TIM3_IRQHandler(void)   //TIM3中断 {    //static u8 Exposure_Count=0,Exposure_Point;                      //计数//曝光点                              Exposure_Count++;    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否 {      Exposure_Point =50 - Exposure_Time;                        // 根据曝光时间计算50ms周期内的曝光点         if (Exposure_Point >= 1)   { if (Exposure_Point == Exposure_Count)          //等待曝光点 {   CCD_Prepare();                               //曝光开始 }   }  if (Exposure_Count== 50) {       Time50_Flag=1;Exposure_Count = 0;      }   TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志    } } [/mw_shl_code] [mw_shl_code=c,true] [/mw_shl_code] [mw_shl_code=c,true]//////////////////////////////////////////////////////////////////////////////// [/mw_shl_code] 【 CCD.c 】 //CCD IO初始化 void CCD_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx|RCC_APB2Periph_ADC1,ENABLE ); //使能ADC1通道时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CLK|GPIO_Pin_SI; //端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOX, &GPIO_InitStructure); //根据设定参数初始化 //PA1 作为模拟通道输入引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_AO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚 GPIO_Init(GPIOX, &GPIO_InitStructure); ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 } //获得ADC值 //ch:通道值 0~3 u16 Get_Adc(void) { //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果 } //第一个周期不采集,相当于准备工作, void CCD_Prepare(void) { u16 n; SI=1; delay_us(2); // CLK=1; delay_us(2); //ccd的每个AO采集时间不可低于0.125us,这里SI,CLK周期统一使用2us SI=0; delay_us(2); CLK=0; for(n=0;n<127;n++) { delay_us(2); CLK=1; delay_us(2); CLK=0; } delay_us(2); CLK=1; delay_us(2); CLK=0; } u16 CCD_Pixel[128]={0}; //CCD巡线函数:控制CCD工作并返回检测到的黑线中心像素坐标 void CCD_Get(void) { u16 i; SI=1; delay_us(2); CLK=1; delay_us(2); //ccd的每个AO采集时间不可低于0.125us,这里SI,CLK周期统一使用2us SI=0; delay_us(2); // for(i=0;i<10;i++) //稍做延时,等待采取第一个数据 决定图形平滑程度 // { //其实没多大作用 // delay_us(2); // } CCD_Pixel[0]=Get_Adc(); CCD_Pixel[0]=CCD_Pixel[0]/16; CLK=0; for(i=1;i<128;i++) { delay_us(2); CLK=1; delay_us(2); CCD_Pixel=Get_Adc(); CCD_Pixel[0]=CCD_Pixel[0]/16; CLK=0; } delay_us(2); CLK=1; delay_us(2); CLK=0; } //求像素的平均值 float CCD_Pixel_Average(void) { u8 i,sum; for(i=8;i<128;i++) //不要前八个点 { sum = sum + CCD_Pixel; } return ((float)sum/120); } /**************************************************************** * 函数名称:Calculate_Exposure_Time * 功能说明:计算曝光时间 ****************************************************************/ u8 Exposure_Time=10; void Calculate_Exposure_Time(void) { float Pixel_Average_Value; /* 128个像素点的平均AD值 */ float Pixel_Average_Voltage; /* 128个像素点的平均电压值*/ float Target_Pixel_Average_Voltage = 1.65; /* 设定目标平均电压值 */ float Delta_Pixel_Average_Voltage = 0; /* 设定目标平均电压值与实际值的偏差*/ float Allowed_Delta_Pixel_Average_Voltage =0.1; /* 设定目标平均电压值允许的偏差*/ Pixel_Average_Value =CCD_Pixel_Average(); /* 计算128个像素点的平均AD值 */ Pixel_Average_Voltage = Pixel_Average_Value *(3.3/256); /* 计算128个像素点的平均电压值 */ Delta_Pixel_Average_Voltage = Target_Pixel_Average_Voltage - Pixel_Average_Voltage; if(Delta_Pixel_Average_Voltage < -Allowed_Delta_Pixel_Average_Voltage) { Delta_Pixel_Average_Voltage = -Delta_Pixel_Average_Voltage; Exposure_Time = (unsigned char)(Exposure_Time - Delta_Pixel_Average_Voltage); } if(Delta_Pixel_Average_Voltage>Allowed_Delta_Pixel_Average_Voltage) { Exposure_Time = (unsigned char)(Exposure_Time + Delta_Pixel_Average_Voltage); } if(Exposure_Time <= 1) Exposure_Time = 1; if(Exposure_Time >= 50) //将曝光时间限制在50ms内 Exposure_Time = 50; }[/mw_shl_code]


[/mw_shl_code] [mw_shl_code=c,true]/************************************************** 函数名称 :Send_Data 功能说明:将数据发送到上位机 ***************************************************/ void Send_Data(void) { unsigned char i,temp; unsigned char crc = 0; USART_SendData(USART1,'*'); USART_SendData(USART1,'L'); USART_SendData(USART1,'D'); SendHex(0); SendHex(132); SendHex(0); SendHex(0); SendHex(0); SendHex(0); for(i=0; i<128; i++) // { temp=CCD_Pixel; SendHex(temp); // USART_SendData(USART1,CCD_Pixel); } SendHex(crc); USART_SendData(USART1,'#'); } /*************************************************** 函数名称:SendHex 功能说明:上位机接口程序 ***************************************************/ void SendHex(unsigned char hex) { unsigned char temp; temp = hex>>4; if(temp < 10) { USART_SendData(USART1,temp + '0'); } else { USART_SendData(USART1,temp - 10 + 'A'); } temp = hex & 0x0F; if(temp < 10) { USART_SendData(USART1,temp + '0'); } else { USART_SendData(USART1,temp - 10 + 'A'); } }[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

额 4年后才再次登录,问题已经解决。记得当时好像是因为存数据的最好用指针的类型,用数组就回出错,具体什么原理一直没搞懂。 对于调试CCD,其实用法很简单,官方提供的代码一般就可以直接用。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-5-8
在线时间
8 小时
 楼主| 发表于 2015-5-8 14:49:38 | 显示全部楼层
额 4年后才再次登录,问题已经解决。记得当时好像是因为存数据的最好用指针的类型,用数组就回出错,具体什么原理一直没搞懂。
对于调试CCD,其实用法很简单,官方提供的代码一般就可以直接用。
回复

使用道具 举报

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2013-9-11
在线时间
6 小时
发表于 2015-5-8 16:27:52 | 显示全部楼层
把LED放在定时器中断中,不发生变化,还是变化的太快你看不出来,如果进入调试模式,LED应该发生变化。
还有就是串口是正常工作不,看看系统时钟是多少?
回复

使用道具 举报

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-5-8
在线时间
8 小时
 楼主| 发表于 2015-5-8 23:38:05 | 显示全部楼层
回复【2楼】yediezeus:
---------------------------------
我的LED是 50ms*20=1秒  闪烁一次的
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2016-8-11
在线时间
9 小时
发表于 2017-2-24 17:35:00 | 显示全部楼层
楼主问题解决了吗??
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2016-8-11
在线时间
9 小时
发表于 2017-2-24 17:35:43 | 显示全部楼层
能不能分享一下代码
回复

使用道具 举报

4

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2016-10-27
在线时间
47 小时
发表于 2017-3-6 18:27:36 | 显示全部楼层
你好。我也在研究TCD1209线阵CCD,你的驱动时序调试好了吗
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-1-20
在线时间
3 小时
发表于 2017-8-15 22:14:14 | 显示全部楼层
用蓝宙stm32f103ZET6 CCD程序移植到 stm32f103c8t6,移植后运行没有问题,可以调试,但是ccd显示图像出现固定数据,都是同一个系列的,72M的主频,请教下大家是什么原因,附件中有移植后的程序。
        ccd显示固定帧如附件中图片;
ps:其中每个模块都测试过都是可以正常工作的,定时器中断,ADC转换,滴答定时,串口等等。没有用示波器细看,没有示波器!
回复

使用道具 举报

17

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
456
金钱
456
注册时间
2021-9-6
在线时间
59 小时
发表于 2021-10-12 14:40:22 | 显示全部楼层
yanghexin1990 发表于 2017-8-15 22:14
用蓝宙stm32f103ZET6 CCD程序移植到 stm32f103c8t6,移植后运行没有问题,可以调试,但是ccd显示图像出现固 ...

兄弟可以分享一下源码吗

回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 18:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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