|
菜鸟求助:用LPC932A1单片机测量20us左右的低脉冲宽度
[复制链接]
我的设计要求是:20us低脉冲表示位0; 60us低脉冲宽度表示位1; 我采用的单片机的捕获功能检测,不知道是不是我的程序有问题,检测不出20us的低脉冲,下面是我的程序,采用外部晶振6MHz,求各位下指教:
#include"Philips/REG932.h"
unsigned char Cap1=0,Cap2=0; //第一,二次捕获标志
unsigned char Temp,Temp1;
unsigned int CapBuff[4];
unsigned char ByteBuff[64]={0};
unsigned char Cap2Flag=0; //第二次捕获完成标志
unsigned char TempBit,TempBit0;
unsigned char TimerCount=0,CapCount=0;
unsigned char SendPusleEndFlag;
unsigned char CaptureEndFlag;
unsigned char CapSuccessFlag;
unsigned char testcount=0;
sbit TestPusleP01 = P0^1;
sbit TestJude = P2^4;
sbit InPusle = P2^7;
sbit OutPusle=P0^4;
void delayns(unsigned int n0)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<10000;j++);
}
void delayus(unsigned int n)
{
unsigned int i,j=2;
for(i=0;i
for(j=0;j<2;j++);
}
void Test()
{
TestJude=1; //OutPusle
delayus(20);
TestJude=0; //OutPusle
delayus(20);
}
void TestPusle()
{
TestPusleP01=0;
delayus(10);
TestPusleP01=1;
delayus(10);
}
void Sys_Init(void)
{
P0M1 = 0x00;
P0M2 = 0x00;
P1M1 = 0x00;
P1M2 = 0x00;
P2M1 = 0x80; //ICA引脚仅为输入
P2M2 = 0x00;
P3M1 = 0x00;
P3M2 = 0x00;
EA = 1;
// InPusle =1;
OutPusle = 0;
}
void CCU_Init(void)
{
TPCR2H = 0x00; //定时器分频系数,周期为1MHz
TPCR2L = 0x06;
TOR2H = 0x00; //设置CCU重装值
TOR2L = 0x00;
TH2 = 0x00;
TL2 = 0x00;
TICR2 = 0x01; //定时器溢出中断,捕获A中断使能
CCCRA = 0x00; //下降沿触发捕获
ECCU = 1; //开CCU中断
TCR20 = 0x01; //CCU控制寄存器配置,递增计数
}
void Timer0_Init(void)
{
TH0=0xFF;
TL0=0xE2; //初值30(10us)
TMOD=0x01; //定时器0工作模式为1,用作定时器
ET0=1; //开定时器中断
TR0=1; //打开定时器0
}
void SendBit(unsigned char sendbit); //发送字节脉冲
void ReceiverByte(); //接收字节脉冲
void Startup(void); //检测开始通信并且发送Tin宽度
void main()
{
unsigned char i=0;
unsigned char count1=0;
CapSuccessFlag=0;
CaptureEndFlag=0;
testcount=0;
CapCount=0;
for(i=0;i<4;i++)
CapBuff=0;
Sys_Init();
///////////////////////////////////////////////////////////
delayns(200);
Startup(); //用于检测通信是否开始
ReceiverByte(); //根据检测发送的脉冲宽度来表示位0或1;20us的低脉冲表示0;60us的低脉冲表示1;
//主机发送64字节的数据,检测数据每个位的脉冲宽度,如果在20us左右则为0,60us左右则为1;
/////////////////////////下面用于测试;主机一直发送010101....///////////////////////////////
if(ByteBuff[3]==0xAA) //字节为10101010
{
while(1)
Test();
}
if(ByteBuff[3]==0x55) //字节为01010101
{
while(1)
TestPusle();
}
while(1)
{
SendBit(0x85);
}
//////////////////////////////////////////////////////////////////////
}
void CCU_ISR() interrupt 11 //捕获中断
{
EA=0;
Temp=TISE2;
Temp&=0x07;
if(Temp==0x06)
{
Cap1=1;
if(Cap2==1) //第二次记录,上升沿触发
{
CapBuff[2]=ICRAL;
CapBuff[3]=ICRAH;
CCCRA=0x00; //下降沿触发
Cap1=0;
Cap2=0;
CaptureEndFlag=1;
}
if(Cap1==1) //第一次记录,下降沿触发
{
CapBuff[0]=ICRAL;
CapBuff[1]=ICRAH;
TH2=0x00; //重新放置CCU定时器初值
TL2=0x00;
CCCRA=0x01; //上升沿触发
Cap2=1;
}
}
TIFR2=0; //CCU中断清零
EA=1;
}
void Timer0_ISR() interrupt 1 //定时器中断;每10中断一次
{
TH0=0xFF;
TL0=0xE2;
TimerCount++;
}
void ReceiverByte() //接收数据;把数据的脉冲转换为字节; //测试有问题
{
unsigned int PusleWidth;
unsigned char a,b;
a=0x00;
CCU_Init(); //捕获初始化
while(1)
{
while(1) //等待产生一次低电平捕获
{
if(CaptureEndFlag==1)
{
CaptureEndFlag=0;
CapSuccessFlag=0;
break;
}
}
//捕获之后,计算脉冲宽度
PusleWidth=(CapBuff[3]*256+CapBuff[2])- (CapBuff[1]*256+CapBuff[0]); //计算脉冲宽度
if((PusleWidth>10)&&(PusleWidth<30)) //!! //20us左右低脉冲宽度表示0;
{
b=0x00;
CapCount++;
CapSuccessFlag=1;
}
else if((PusleWidth>45)&&(PusleWidth<70)) //!! //60us左右低脉冲宽度表示1;
{
b=0x80;
CapCount++;
CapSuccessFlag=1;
}
if(CapSuccessFlag==1)
{
a=a>>1;
a=a|b;
if(CapCount==8) //完成一个字节的捕获
{
ByteBuff[testcount]=a;
a=0x00;
CapCount=0;
testcount++;
}
}
if(testcount==64)
{
testcount=0;
break;
}
}
ECCU=0;
}
void SendBit(unsigned char sendbit) //发送字节脉冲 //测试正常
{
unsigned char i;
Timer0_Init();
TimerCount=0;
TestPusleP01=1;
for(i=0;i<8;i++)
{
TempBit=(sendbit>>i)&1;
switch(TempBit)
{
case 0:
{
while(1)
{
if(TimerCount==24) //占空比为17/16 表示发送0
{
TestPusleP01=0;
}
if(TimerCount==26)
{
TestPusleP01=1;
SendPusleEndFlag=1;
TimerCount=0;
}
if(SendPusleEndFlag==1)
break;
}
SendPusleEndFlag=0;
break;
}
case 1:
{
while(1)
{
if(TimerCount==24) //占空比为19/16 表示发送1
{
TestPusleP01=0;
}
if(TimerCount==28)
{
TestPusleP01=1;
SendPusleEndFlag=1;
TimerCount=0;
}
if(SendPusleEndFlag==1)
break;
}
SendPusleEndFlag=0;
break;
}
default :
{
TimerCount=0;
SendPusleEndFlag=0;
break;
}
}
}
ET0=0;
}
void Startup(void) //检测开始通信并且发送Tin宽度 //测试正常
{
///////////////////////////////////////////////////////////////接收其实脉冲
unsigned char count0=0;
CCU_Init();
CaptureEndFlag=0; //捕获结束标志
while(1) //捕获并检测2次低脉冲,
{
if(CaptureEndFlag==1)
{
count0++;
CaptureEndFlag=0;
}
if(count0==2)
break;
}
ECCU=0; //关闭捕获单元
//////////////////////////////////////////////////////////////////发送通信脉冲宽度
TimerCount=0;
Timer0_Init(); //初始化定时器0并开中断
OutPusle=1;
while(1) //发送Tin脉冲
{
if(TimerCount==32) //Tin脉冲宽度为320us(24);
{
OutPusle=0; //TestJude=1
TimerCount=0;
break;
}
}
ET0=0;
////////////////////////////////////////////////////////////////////
}
|
|