首页 > 代码库 > 基于PWM调制的红外遥控器的设计

基于PWM调制的红外遥控器的设计

 下面首先先简单介绍单总线通信的原理:
    假设通信线上无数据时,即常态为低电平,即单总线以 下拉电阻将总线拉为低电平,其中100K欧就是常态的下拉电阻。
                       这里以12V为高电平,以实现较远通信电路的设计
那么如何实现数字通信呢?
    现将3ms高电平,1ms低电平作为逻辑1;1ms高电平,1ms低电平作为逻辑0.(当然,只要高电平的时间有明显区分即可)

软件设计时,通常需要定时器配合,即设计一个0.5ms的定时中断,并定义一个中断次数计数器C,每发生一次中断,C加一。


软件包括发数据和接收数据两部分。
    (1)发数据程序设计方法
程序应设计两个函数,发逻辑1和发逻辑0两个函数。
发逻辑1是,首先将定时器重新初始化,并将C清0,将发送数据端口置1.之后一直查询计数器C,当C等于6时,发送端口立即给0.并将定时器重新初始化,且C清0;然后查询等待
当C等于2时,程序返回,即发送逻辑1结束。同理发逻辑0.

采用位域的方法定义输出为port_send,输入为prt_re.注意要初始化I/O属性
unsigned int ms_timing0;
void send_high()//3个1ms高电平和1个1ms低电平为传送逻辑1
{
 TimesInit();               //定时器重新0.5msc初始化,没有给出程序
 C_times=0; //计数器C清0
 while(C_times<6) port_send=1;  //3ms          1
 C_times=0;
 while(C_times<2) port_send=0;  //1ms          0
 
}
void send_low()//一个1ms高电平和1ms低电平为一个传送逻辑0
{
 TimesInit(0);//定时器重新0.5msc初始化
 C_times=0; //计数器C清0
 while(C_times<2) port_send=1;  //1ms          1
  C_times=0;
 while(C_times<2) port_send=0;  //1ms          0
 
}
下面是发一个字节数据的程序:
    void send(unsigned int  nc)
{
unsigned int i;
for(i=0;i<8;i++)
{
   if((nc&0x80)!=0) send_high();
else send_low();
nc<<=1;
}
}
(2)接收数据
接受数据需要一直查询接收数据端口,发现为高电平,即刻进入接收数据状态。
当出现高电平后,定时器重新初始化,且C清0,查询等待直到接收端口出现低电平,立即退出C的值。
  当1<<C<3,接收的是逻辑0;
  当5<<C<7,接收的是逻辑1.当然还要查询等待1ms左右,表示接收1个逻辑位结束。
 
软件设计时,要注意防止进入程序死区,在等待高或低电平时,同时也要查询计数器C的值,当C已经很大,比如10时,要考虑是否发生总线错误问题,该类情况要给予充分的重视。

下面是连续接收8个逻辑位的函数,当检测到高电平时,即刻进入此函数。
 unsigned int Re8()
 {
  unsigned int nc=0,i;
  TimesInit();            //定时器重新初始化
  for(i=0;i<8;i++)
  {
    C_times=0; //计数器C清0
while(port_re){ if(ms_timing>50) break;}
if((C_times>=1)&&(C_times<3)) nc<<=1;
if((C_times>=5)&&(C_times<7)) nc=(nc<<1)|0x01;
 C_times=0;
while(!port_re)
{
if(C_times>50) break;
}
 
  }
  return nc;
 }

基于PWM调制的红外遥控器的设计