2988|0

31

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

菜鸟求助:用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;
////////////////////////////////////////////////////////////////////
}
此帖出自单片机论坛
点赞 关注
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表