本来对PIC单片机不熟悉,但当时因为PIC有6脚很小封装的,所以就学习用了一下。近期用到315和433的用PT2262编码发送的遥控器,如果用PT2272来解码当然完全没有问题,但因体积原因,只能用单片机身兼数职代替2272解码。在网上收集来了不少资料,找到一个51系列的可用的程序,于是移植到了pic上面。在此对原作者表示感谢。本人对C语言也是才学,对付着写了一下,程序不长,付在下面,供有兴趣的朋友探讨参考。
//pic16f1828_DECODE_2272
/************* PIC16F1828单片机程序 ******************/
/***************************************************************/
/*****File Function : pic828软解码PT2272 **********/
/*****MCU : PIC16F1828 内部振荡 *****/
/*****Compile Date : 2014/10/09 ******/
/*****Edition Info : V0.0 ******/
//**************************************************************/
/***************************************************************/
#include <pic.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
//---------------------------------------------------------
uint8 ma1,jmz1,jmz2,jmz3;
//----------------------------------------------------------
void delayms(uint16 count);
void PortInit(void);
//------------------------------------------------------------------------
#define p2262 LATB6 //11脚 RB6 模拟2262发码,控制315(433)发射信号
#define p2272 RA2 //17脚 RA2 2272信号进,软解码2272信号进口
//------------------------------------------------------------------------
#define led LATB5 //12脚 RB5 红色 低电平亮
#define b_yong1 RB7 //10脚,备用1
#define b_yong2 RC7 // 9脚,备用2
#define key RB7
//------------------------------------------------------------------------
#define _asm{"nop"} NOP()
//------------------------------------------------------------------------
//========================================================================
void PortInit(void) {
TRISA=0b11001111; //A口:RA2=p2272(输入)
TRISB=0b10011111; //B口:RB5=led(输出),RB6=PL2262(输出),
TRISC=0b11011110; //C口:
ANSC0=0; //禁止RC0口的模拟功能20120729
ANSC1=0; //禁止RC1口的模拟功能20120729
ANSC2=0; //禁止RC2口的模拟功能20120729
ANSC3=0; //禁止RC3口的模拟功能20120729
ANSC6=0; //禁止RC6口的模拟功能
ANSC7=0; //禁止RC7口的模拟功能
WPUA =0b11111111; //使能A口上拉电阻
WPUB =0b11111111; //使能B口上拉电阻
WPUC =0b11111111; //使能C口上拉电阻
ANSA0=0; //禁止RA0口的模拟功能20120719
ANSA1=0; //禁止RA1口的模拟功能20120719
ANSA2=0; //禁止RA2口的模拟功能
ANSB7=0; //禁止RB7口的模拟功能20120729
ANSELB=0; //B口配置为数字功能
ANSELC=0; //C口配置为数字功能
//OSCCON=0b01011000; //1MHZ
//OSCCON=0b01100000; //2MHZ
//OSCCON=0b01101000; //4MHZ 振荡器控制(6-3位=1101 4MHz)
OSCCON=0b01110000; //8MHZ
//OSCCON=0b01111000; //16MHZ
INTCON =0b11010000; //.7=GIE:全局中断;.6=PEIE:外设中断允许;.5=TMR0IE t0; .4=INTE:INT外部中断允许位;
//.3=电平变化中断(1:允许电平变化,0:不允许); .2=TMR0IF:t0中断标志位;
//.1=INTF:INT外部中断标志位; .0=IOCIE:电平变化中断标志
T1CON = 0b00111000; //T1时钟源为指令时钟,1:8预分频; .3=1使能专用的T1振荡器,.0=0暂不使能(暂停计时)
T1GCON = 0b00000000; //T1门控功能不要
PIE1 = 0b00000001; //.0=T1中断允许位
OPTION_REG =0b00000111;//111; .7位=0,使能弱上拉
led=1; //led=0 -->亮
}
//==============================================================
static void interrupt isr(void){
uint8 i,tl,th;
uint16 l,m;
//--------------------------------------------------------------
if(INTE&&INTF){ //判断外部中断
INTF=0;
INTE=0; //INT禁止(关外部中断)
TMR1ON=1; //T1开始计时
i=0;
//==============================================================
while(i<24)
{
while(p2272==0); //等待高电平到来
tl=TMR1L; //tl=TL1;
th=TMR1H; //th=TH1;
TMR1H=TMR1L=0; //记录低电平长度并初始化高电平头
l=th;
l=((l<<8)+tl);
if(i==0){ //处理低电平
if(l>2360)
{ //确认是引导头
m=l/31;
}
else //不符合规则(出错)
{
i=0;
TMR1ON=0; //T1暂停计时
TMR1H=TMR1L=0;
break;
}
}
else
{
if(((l<m-m/4)&&(l>m+m/4))||((l<m*3-m/2)&&(l>m*3+m/2)))//判断窄电平与宽电平的宽度是否合格
{
i=0;
TMR1ON=0; //T1暂停计时
TMR1H=TMR1L=0;
break;
}
}
//==============================================================
while(p2272==1); //等待低电平到来
th=TMR1H; //th=TH1;
tl=TMR1L; //tl=TL1;
TMR1H=TMR1L=0; //TH1=TL1=0;
l=th;
l=((l<<8)+tl);
if(((l>(m-m/4))&&(l<(m+m/4)))) //判断窄电平是否合格
{
i++;
ma1<<=1; //高低位相反问题
}
else if((l>(m*2-m/2))&&(l<(m*4+m/2))) //判断宽电平是否合格
{
i++;
ma1<<=1; //高低位相反问题
ma1+=1; //高低位相反问题
}
else //不符合规则出错
{
i=0;
TMR1ON=0; //T1暂停计时
TMR1H=TMR1L=0;
break;
}
//==============================================================
if(i==8) {jmz3=(ma1); }
if(i==16) {jmz2=(ma1); }
if(i==24) //解码成功结束
{ jmz1=ma1;
if(jmz1==0xc0)
{led=0;delayms(39000);led=1;}
if(jmz1==0x30)
{led=0;delayms(3000);led=1;}
if(jmz1==0x0c)
{led=0;delayms(1000);led=1;}
if(jmz1==0x03)
{led=0; }
}
}
TMR1ON=0; //T1暂停计时
TMR1H=TMR1L=0;
INTE=1; //INT允许
}
//--------------------------------------------------------------
if(TMR1IE&&TMR1IF){ //判TMR1中断
TMR1IF=0; //清除TMR1中断标志
}
//--------------------------------------------------------------
if(TMR0IE&&TMR0IF){ //判TMR0中断
TMR0IF=0; //清除TMR0中断标志
}
}
//===============================================================
void main(void) {
uint16 k,j;
uint8 i;
PortInit();
while(1);
}
//=======================================================================
void delayms(uint16 count){
uint16 i;
for(i=count;i>0;i--){
NOP();
}}
//========================================================================
//########################################################################
//数据jmz1) 0=00, 1=03, 2=0c, 3=0f, 4=30, 5=33, 6=3c, 7=3f,
// 8=c0, 9=c3,10=cc,11=cf,12=f0,13=f3,14=fc,15=ff,
// 16=00, 17=03,18=0c, 19=0f, 20=30, 21=33, 22=3c, 23=3f
//
// 0 1 2 3 4 5 6 7
// 10 10 10 10 10 10 10 10 <--全部悬空 =aaaa
// 01 01 01 01 01 01 01 01 <--全部接高电平 =5555
// 00 00 00 00 00 00 00 00 <--全部接低电平 =0000
// -------------- --------------
// jmz2 jmz3
//########################################################################
转载
|