本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
在网上找了很多类似,测试好像不行,和工作频率有关,还有一些程序的算法非常差。
于是自己动手写了一个比较好的算法,可以应用在C51,STC等单片机上,只需要修改一下参数
if(tcpStart>9000)即可,9000是计数器的引导头9ms最小记数量, 将其修改小后可以适合多种频率下。另32位码的需要将 if(indataxp>33).,如下只是一个测试程序,程序主要在void int_0() 中断中处理,接收命令完成后,通过串口发给PC检看结果。
对于正在研究这块的人来说是一个非常好的参考。
#include<reg52.h>
#include "intrins.h"
#include "string.h"
#define INBUF_LEN 4 //数据长度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag= 0 ;
#define uchar unsigned char
#define uint unsigned int
sfr WDT_CONTR=0xc1; //看门狗
sfr CLK_DIV=0x97; //CPU分频
sbit led1 = P2^0;
sbit led2 = P2^1;
sbit led34 =P3^4;
sbit led35 =P3^5;
sbit indata=P3^2;
//PanHui
//2010-10-1
//ph_layout@126.com
//***********类型定义******************
//将定时器中的高低8位转成INT型
union h8l8type{
int hl;
char cdata[2];
};
union h8l8type hl88;
//***********变量定义***********************
//遥控器
uchar tcp01=0;
uchar indataxp=0;
uint tcpStart=0,tcp3,tcp1;
uchar indata48[6]={0,0,0,0,0,0};
uchar indata8;
//晶体频率
//函数声明
void int_0(void);
void delayms(uint xms);
void delay1ms(uint xms);
void init_serialcomm( void );
void send_char_com( unsigned char ch) ;
void rs232();
//延时程序
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
{
for(j=110;j>0;j--);
}
}
//内部时钟,1毫秒定时 xms = 660
void delay1ms(uint xms)
{
uint dms;
for(dms=0;dms<xms;dms++)_nop_();
}
///////////////////////////////////////////////////////
//主程序
//////////////////////////////////////////////////////
void main()
{
uchar i;
//test
//********是否为看门狗复?****
//*********初始化*************
EX0 = 0; //关INT0的中断
EA = 0;
//中断INT0
//CLK_DIV = 0x01;
//*******遥控器中断设置*************
//定时计数器0设置
TMOD=0x21;
ET0=0;
TH0=0;
TL0=0;
IT0=1; //1->0下降沿中断事件
EX0=1; //打开中断
EA=1; //开总中断
//WDT_CONTR = 0x35;
//串口
rs232();
while(1)
{
//WDT_CONTR = 0x35;
for(i=6;i<=5;i++)
{
//P2=~i;
send_char_com(indata48[0]);
send_char_com(indata48[1]);
send_char_com(indata48[2]);
send_char_com(indata48[3]);
send_char_com(indata48[4]);
send_char_com(indata48[5]);
//P1=~indata48[i];
delayms(220000);
delayms(220000);
}
}
}
//**************************************************
//**************************************************
/* 遥控器输入P3.2 INT0中断,解码程序*/
//**************************************************
//**************************************************
void int_0() interrupt 0 using 0
{
uchar inxp;
//采用TCP查询法
EA=0; //关中断
hl88.cdata[0] = TH0;
hl88.cdata[1] = TL0;
TH0=0;
TL0=0;
TR0=1;
if(tcp01==1)
{
//引导头
tcpStart = hl88.hl;
if(tcpStart>9000)
{
tcp01=3;
tcp3=(tcpStart/16)*3;
//P1=~hl88.cdata[1];;
//P2=~hl88.cdata[0];
indata48[0]=0;
indata48[1]=0;
indata48[2]=0;
indata48[3]=0;
indata48[4]=0;
indata48[5]=0;
//while(1);
}
}
else
{
if(tcp01 == 3)
{
//数据中断
indataxp++;
if(indataxp>49)
{
tcp01=0;
//保存指令
//P1=~indata48[4];
//P2=~indata48[5];
indataxp=0;
send_char_com(indata48[0]);
send_char_com(indata48[1]);
send_char_com(indata48[2]);
send_char_com(indata48[3]);
send_char_com(indata48[4]);
send_char_com(indata48[5]);
}
else
{
inxp = indataxp/8;
if(tcp3 > hl88.hl)
{
indata48[inxp]= indata48[inxp]<<1|0x01;
}
else
{
indata48[inxp]=indata48[inxp]<<1;
}
}
}
}
if(tcp01==0)tcp01=1;
EA=1; //打开中断
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////// 串口调试程式 ////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
void init_serialcomm( void )
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x21 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80 ; //SMOD=1;
TH1 = 0xFb; //Baud:9600 fosc=11.0592MHz
IE |= 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
// TI=1;
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
SBUF=ch;
while (TI== 0 );
TI= 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do
{
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
if (RI)
{
unsigned char ch;
RI = 0 ;
ch=SBUF;
if (ch> 127 )
{
count3= 0 ;
inbuf1[count3]=ch;
checksum= ch- 128 ;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if ( (count3==(INBUF_LEN- 1 )) && (!checksum) )
{
read_flag= 1 ; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}
void rs232()
{
init_serialcomm(); //初始化串口 |