首页 > 代码库 > 基于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;
}
假设通信线上无数据时,即常态为低电平,即单总线以 下拉电阻将总线拉为低电平,其中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调制的红外遥控器的设计
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。