MSP430與TDC-GP2脈沖式激光測距中的例程代碼
下面是用C 語言編寫的MSP430F135 系列單片機對于gp2 控制的一些控制函數(shù)的例程代碼+注釋,其中描述了一些對gp2 功能上的控制,通信為單片機用普通io 口模擬spi通信操作,僅供參考:
//============端口設(shè)置程序================//
void port_init(void) //端口初始化
{
P5DIR |=BIT1;//EN_STOP
P5DIR |=BIT2;//START
P5DIR |=BIT3;//ENSTART
P5DIR &=~(BIT4);//INTN
P6DIR |=BIT5;//RSTN
P5OUT &=~(BIT1);
P5OUT &=~(BIT2);
P5OUT &=~(BIT3);
P5OUT &=~(BIT0);//stop
P6DIR |=BIT0;//SCK-輸出方向
P6DIR |=BIT1;//SSN-輸出方向
P6DIR &=~(BIT2);//SO-輸入方向
P6DIR |=BIT3;//SI-輸出方向
P6OUT &=~(BIT0);//SCK-空閑時低平,spi 時鐘極性為0。
P6OUT |=BIT1;//SSN-片選在沒有通信情況下置高
}
void spi_enable(void) //開啟spi 通信,將ssn 置低
{
P6OUT &=~(BIT1);//ssn 置低
_NOP();
return;
}
void spi_disable(void) //關(guān)閉spi 通信,將ssn 置高
{
P6OUT |=BIT1;//ssn 置高
_NOP();
return;
}
void send_zero(void) //發(fā)送0
{
P6OUT |=BIT0;//SCK 高電平
_NOP();
P6OUT &=~(BIT3);//SI-輸出一個低平
_NOP();
P6OUT &=~(BIT0);//SCK 低平
_NOP();
return;
}
void send_on
{
P6OUT |=BIT0;//SCK 高電平
_NOP();
P6OUT |=BIT3;//SI-輸出一個高平
_NOP();
P6OUT &=~(BIT0);//SCK 低平
_NOP();
return;
}
//============================================//
//=====================SPI 寫數(shù)據(jù)=====================//
void spi_write8(unsigned char wbuf8) // spi 寫入8 位數(shù)據(jù)
{
unsigned char cnt,tmp=0x80;
spi_enable();
for(cnt=8;cnt>0;cnt--)
{
if((wbuf8&tmp)>0)
send_on
else
send_zero();//發(fā)送0
tmp /=2; //tmp 右移一位
} //沒有spi 關(guān)閉命令,測試程序中代碼關(guān)閉!
return;
}
void spi_write16(unsigned int wbuf16) // spi 寫16 位數(shù)據(jù)
{
unsigned char cnt;
unsigned int tmp=0x8000;
spi_enable();
for(cnt=16;cnt>0;cnt--)
{
if((wbuf16&tmp)>0)
send_on
else
send_zero();//發(fā)送0
tmp /=2; //tmp 右移一位
}
_NOP();
spi_disable();
return;
}
void spi_write32(unsigned long wbuf32) // spi 寫32 位數(shù)據(jù)
{
unsigned char cnt;
unsigned long tmp=0x80000000;
spi_enable();
for(cnt=32;cnt>0;cnt--)
{
if((wbuf32&tmp)>0)
send_on
else
send_zero();//發(fā)送0
tmp /=2; //tmp 右移一位
}
_NOP();
spi_disable();
return;
}
//============================================//
//=====================SPI 讀數(shù)據(jù)=====================//
unsigned long spi_read32()
{
unsigned char cnt;
unsigned long tmp=0x80000000;
unsigned long int rbuf32=0x00000000;
spi_enable();
for(cnt=32;cnt>0;cnt--)
{
P6OUT |=BIT0;//SCK
_NOP();
if((P6IN &0X04)>0X00)//P6.2 SO
rbuf32 |=tmp;
tmp /=2;
P6OUT &=~(BIT0);// SCK
_NOP();
}
_NOP();
spi_disable();
return(rbuf32);
}
//============================================//
//===========GP2 上電復(fù)位程序==================//
void GP2_RESET(void)
{
P6DIR |=BIT5; //設(shè)置p6.5 輸出方向
P6OUT |=BIT5; //輸出高平
_NOP();
P6OUT &=~(BIT5); //輸出低平
_NOP();
P6OUT |=BIT5; //輸出高平
_NOP();
}//給gp2RSTN 管腳一個Reset 的方波
//============================================//
//===========GP2 寄存器配置程序====================//
void GP2_init(void)
{
unsigned long REG0,REG1,REG2, REG3, REG4,REG5;
unsigned char PU=0X50;
unsigned char init=0x70;
REG0=0X80008420;//校準(zhǔn)陶瓷晶振時間為8 個32k 周期,244.14us.
//設(shè)置高速晶振上電后一直起振.設(shè)置測量范圍1,自動校準(zhǔn),上升沿敏感
REG1=0X81014100;//預(yù)期stop1 脈沖數(shù)1 個.計算第一個stop1-start
REG2=0X82E00000;//開啟所有中斷源
REG3=0x83080000;//
REG4=0x84200000;//
REG5=0X85080000;//
spi_write8(PU);//上電復(fù)位
_NOP();
spi_disable();
spi_write32(REG0);
_NOP();
spi_write32(REG1);
_NOP();
spi_write32(REG2);
_NOP();
spi_write32(REG3);
_NOP();
spi_write32(REG4);
_NOP();
spi_write32(REG5);
_NOP();
return;
}
//=============================================//
//===========GP2 時鐘校準(zhǔn)程序===================//
void GP2_cal(void)
{
unsigned char cal_start=0x03;
unsigned char read_reg0=0xb0;
unsigned long int CAL;
float CAL_f;
P5OUT |=(BIT3);//EN_START
spi_write8(cal_start);//啟動校準(zhǔn)
_NOP();
spi_disable();
while((P5IN&0x10)==0x10)//判斷中斷置位否
_NOP();
spi_write8(read_reg0); //讀校準(zhǔn)的時間數(shù)據(jù)
_NOP();
CAL=spi_read32();//通過計算校準(zhǔn)系數(shù)為244.146/(float(CAL)/65536*0.250))
_NOP();
return;
}
//=============================================//
//=========時間測量狀態(tài)寄存器判斷程序==========//
void GP2_TMSTAT()
{
unsigned char stat=0xb4;
unsigned long a;
unsigned int b;
while((P5IN&0x10)==0x10)//判斷中斷置位否
_NOP();
spi_write8(stat);
_NOP();
a=spi_read32();
b=(a>>16);
if((b&0x0600)==0)
BZ1 &=0XFE;
else
BZ1 |=0X01;//置溢出預(yù)計數(shù)器或溢出TDC 標(biāo)志
}
//===========================================//
//=============用單片機口產(chǎn)生START 信號==========//
void GP2_START(void)
{
P5OUT &=~(BIT2);//START
_NOP();
P5OUT |=(BIT2);
_NOP();
P5OUT &=~(BIT2);
_NOP();
return;
//===========================================//
//============通訊測試===============//
void testcomunication(void)
{
unsigned long int REG1;
unsigned char cnt;
unsigned char tmp=0x80;
unsigned char test_reg=0xb5; //讀結(jié)果寄存器5,反映寄存器1 的高8 位
unsigned char test_reg0=0x00;
REG1=0x81112233; //寫寄存器1,隨便輸入,然后從結(jié)果寄存器5 讀高8 位
spi_wriet32(REG1) ;
_NOP();
spi_write8(test_reg);
_NOP();
for(cnt=8;cnt>0;cnt--)
{
P6OUT |=BIT0;//SCL
_NOP();
if((P6IN &0X04)>0X00)//P6.2 SO
test_reg0 |=tmp;
tmp /=2;
P6OUT &=~(BIT0);//SCL
_NOP();
}
spi_disable();
}
//===================================//
//==========測試fire 脈沖產(chǎn)生測試=============//
void fire(void)
{
unsigned char TDC_init=0x70;
unsigned char start_cycle=0x01;
P5OUT |=(BIT3);//EN_START 開啟
spi_write8(TDC_init); //初始化TDC
_NOP();
spi_disable();
spi_write8(start_cycle); //發(fā)送fire 脈沖
_NOP();
spi_disable();
GP2_START(); //給start 信號,否則fire 信號只能發(fā)送一次,系統(tǒng)將會掛起
}
//===================================//
//======時間測量測試=========//
void timemeasurement(void)
{
unsigned long int M;
spi_write8(TDC_init); //初始化TDC
_NOP();
spi_disable();
P5OUT |=(BIT3);//EN_START
P5OUT |=(BIT1);//EN_STOP
GP2_START();//給start 信號
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();//延遲
P5OUT |=BIT0;//給STOP 信號
_NOP();
while((P5IN&0x10)==0x10)//判斷中斷置位否
_NOP();
GP2_TMSTAT(); //GP2 狀態(tài)讀取
_NOP();
spi_write8(read_reg0); //讀時間測量數(shù)據(jù)
_NOP();
M=spi_read32();
_NOP();
}
評論