不接地,为了减小焊盘占地面积把他们掰掉都行,我就是这么干的..
以下是我写的软件时序,用了一年没问题,用的是STM32F103C8T6,可以参考参考..
注意M之前已经配置成用TIM2产生4MHz的方波,进入函数时用GPIOB->CRH &= 0xfffff3ff;这个语句将M管脚切换到软件控制,退出时再切回4MHz方波
do..while那个循环的时序是用示波器一点一点调出来的,为了使M的波形尽量接近方波,所以把控制ADC读ADC都分成了若干个步骤
#define ICG PAout(1)
#define M PBout(10)
#define SH PAout(2)
#define M_H M=1
#define M_L M=0
//为了加快时钟M的速度,用GPIO的BSRR寄存器进行修改M的电平
//如果改了M的管脚,千万记得把这也改了!
#define M_H_FAST GPIOB->BSRR = 1<<10//M=1
#define M_L_FAST GPIOB->BSRR = 1<<(10+16)//M=0
#define ICG_L ICG=0
#define ICG_H ICG=1
#define SH_L SH=0
#define SH_H SH=1
void __inline delay(int n)
{
while(n--);
}
//-------------------------------------------------------------------
//从TCD1304中读取一帧
//注意第一个值是错误的,即pFrame[0]无效,pFrame[3694]缺失
//入口lExposeTime, *pFrame,是否开激光
//-------------------------------------------------------------------
void TCD1304GetFrame (int lExposeTime, short* pFrame, unsigned int u32NumOFPixel, int lIfLaser)
{
int u16Tmp;
if(lExposeTime<0)
lExposeTime = 0;
if(lIfLaser)//判断是否允许开激光
GPIOA->BSRR = 0x0100;//开激光
delay( 10 );//等待激光亮
ICG_H;//拉高ICG
M_H;//拉高M
SH_L;//拉低SH开始曝光
delay( lExposeTime );//延时一段时间
ICG_L;ICG_L;ICG_L;ICG_L;ICG_L;//关ICG,那么多次是为了延时
SH_H;//拉高SH,开始转移
delay( lExposeTime );//再延时一段曝光时间
SH_L;//拉低SH关曝光
GPIOA->BRR = 0x0100;//关激光 //当前激光亮灯时间 = 0.2498 * lExposeTime + 3.11 us
delay( T1 );
GPIOB->CRH &= 0xfffff3ff;//将M设置成通用推挽
ICG_H;//ICG拉高
do //用do..while循环,这样的话1000时会采1001次,但第一次的没用,所以正好1000个像素点
{
M_L_FAST;
*pFrame = u16Tmp;//将ADC数据存入帧内存
M_H_FAST;
u16Tmp = (u32)(&ADC1->CR2);//取得ADC控制寄存器的内存地址
M_L_FAST;
*(u32*)(u16Tmp) |= ((uint32_t)0x00500000);//启动转换
M_H_FAST;
u16Tmp = (u32)(&ADC1->DR);//取得AD转换结果地址
M_L_FAST;
u16Tmp = *(u32*)(u16Tmp);//取得AD转换结果
M_H_FAST;
pFrame++;//帧内存地址增1
__nop();
__nop();
M_L_FAST;
u32NumOFPixel--;//循环次数减1
__nop();
__nop();
M_H_FAST;
}
while(u32NumOFPixel);
SH_H;
GPIOB->CRH &= 0xfffff0ff;
GPIOB->CRH |= 0x00000b00;//设置恢复用推挽以输出4MHz波
}