/*这是利用PCA模块解析PPM信号的代码,其中uart_send.h头文件是我之前编写的串口通信例程,现在-
利用串口通信将解析的PPM信号发送给PC端,而PCA模块解析代码的绝大部分我都是基于STC14F2K60S2
的用户手册的参考例程所编写,intrins.h文件是参考例程中所引用的文件,具体作用我并未进行了解
其中,我利用串口确实接收到了一批数据,但并未检验数据的正确性。我在下面也贴出了程序中所预编
译的文件,肯能会比较啰嗦,这是因为所包含的文件中还有其他功能的函数设置。*/
#include <uart_send.h>
#include <STC15F2K60S2.H>
#include <intrins.h>
//===========function statement===================
void IO_set();
void PAC_init();
void StarPCA();
unsigned char cnt;
unsigned long count0;
unsigned long count1;
unsigned long length;
bit busy=0;
void main()
{
IO_set();
PAC_init();
init();
Enable_Interrupt();
Staruart();
StarPCA();
while(1)
{
if(busy)
{
if(busy)
{
busy = 0;
if(length<65535) //CCAP寄存器最大值,数据时间小于这么多
{
tuart((unsigned char)(length)>>8);
tuart((unsigned char)length);
}
}
}
}
}
void PCA_Interrupt() interrupt 7
{
if(CF)
{
CF=0;
cnt++;
}
if(CCF0)
{
CCF0=0;
count0=count1;
((unsigned char *)&count1)[3]=CCAP0L;
((unsigned char *)&count1)[2]=CCAP0H;
((unsigned char *)&count1)[1]=cnt;
((unsigned char *)&count1)[0]=0;
length = count1-count0;
busy = 1;
}
}
void IO_set()
{
ACC = P_SW1;
ACC &= ~(0X10|0X20);
P_SW1 = ACC;
}
void PAC_init()
{
CCON = 0; //PCA Control Register setting & PCA Timer Stop & Clear CF &Clear Interrupt Flag
CL = 0; //reset PCA Register
CH = 0; //reset PCA Register
CCAP0L = 0; //reset PCA Register
CCAP0H = 0; //reset PCA Register
CMOD = 0X09; //set PCA system clock & enable PCA Timer overflow Interrupt
CCAPM0 = 0X21; //PCA--CCP16bitmode setting & rising edge mode & measure T
}
void StarPCA()
{
CR = 1;
}
#include <STC15F2K60S2.H>
void init();
void Staruart();
unsigned char ruart();
void tuart(unsigned char trdate);
void delay_ms(unsigned short i);
void Enable_Interrupt();
#define FOSC 24000000
//sfr P_SW1 = 0XA2; //外设功能切换寄存器1
sfr CCON = 0XD8; //PCA控制寄存器
//sbit CCF0 = CCON^0; //PCA模块0中断标志
//sbit CR = CCON^6; //PCA定时器运行控制位
//sbit CF = CCON^7; //PCA定时器溢出标志
//sfr CMOD = 0XD9; //PCA模式寄存器
//sfr CL = 0XE9; //PCA定时器低字节
//sfr CH = 0XF9; //PCA定时器高字节
//sfr CCAPM0 = 0XDA; //PCA模块0模式寄存器
//sfr CCAP0L = 0XEA; //PCA模块0捕获寄存器LOW
//sfr CCAP0H = 0XFA; //PCA模块0捕获寄存器HIGH
#include <uart_send.h>
//#define FOSC 12000000
#define BAUD1 9600
#define TIMEDATE (65536-120)
bit Tflag=0;
bit Rflag=0;
unsigned char channel0=0;
#define S2RI 0X01
sbit CHANNEL0=P2^0;
void init();
void Staruart();
unsigned char ruart();
void tuart(unsigned char trdate);
void delay_ms(unsigned short i);
void Enable_Interrupt();
sbit LED=P2^0;
unsigned char date[12];
//void main()
//{
// unsigned char count;
// init();
// delay_ms(10);
// Staruart();
// channel0=0;
// delay_ms(2000);
// channel0=0;
// delay_ms(2000);
// channel0=100;
// while(channel0--)
// {
// delay_ms(1000);
// }
// while(1)
// {
// if(date[11])
// {
// for(count=0;count<11;count++)
// {
// tuart(date[count]);
// }
// }
// }
//}
void uart2() interrupt 8
{
static i=0;
if(S2CON&S2RI)
{
S2CON&=~S2RI;
date[i++]=S2BUF;
if(date[0]!=0x55)
{
i=0;
date[11]=0;
}
else
{
date[11]=1;
}
if(i==11)
{
i=0;
}
}
}
void uart() interrupt 4
{
if(RI)
{
RI=0;
Rflag=1;
}
if(TI)
{
TI=0;
Tflag=1;
}
}
void PWM() interrupt 1
{
static i=0;
i++;
if(i<=(channel0+100))
{
CHANNEL0=1;
}
else
{
CHANNEL0=0;
}
if(i==2000)
{
i=0;
}
}
void delay_ms(unsigned short i)
{
unsigned short k;
while(i--)
for (k=0;k<100;k++);
}
void init()
{
SCON=0X50; //UART1 SETTING
ES=1; //UART1 INTERRUPT
S2CON=0X50; //UART2 SETTING
IE2=0X01; //UART2 INTERRUPT
AUXR=0X14; //UART1 AND UART2
AUXR|=0X01; //UART1 AND UART2
AUXR|=0X80; //TIME0 SETTING
T2L=(65536-(FOSC/4/BAUD1)); //BAUD SETTING
T2H=(65536-(FOSC/4/BAUD1))>>8;
delay_ms(10);
TMOD=0X00;
TL0=TIMEDATE;
TH0=TIMEDATE>>8;
TR0=1;
ET0=1;
CHANNEL0=0;
}
void Staruart()
{
unsigned char c;
c=0xff;
SBUF=c;
c=SBUF;
}
void Enable_Interrupt()
{
EA = 1;
}
unsigned char ruart()
{
unsigned char redate;
while(~Rflag);
if(Rflag)
{
Rflag=0;
redate=SBUF;
}
return redate;
}
void tuart(unsigned char trdate)
{
while(~Tflag);
if(Tflag)
{
Tflag=0;
SBUF=trdate;
}
}
PS:我之所以想到要解析PPM信号是因为我在使用内部时钟频率的STC15F2K60S2这一单片机解析SBUS协议信号时发现,无论我如何修改代码,似乎SBUF这个寄存器永远都没有接收到数据,一直是0X00,这就使我非常沮丧,而我暂时认为是单片机的性能不够。由于我最后的卑微的一丝丝倔强(没钱买32,还没学过32),我决定不更换单片机,当我知道还有这个PPM协议的时候,我顿时感觉豁然开朗。其实还有其他博主不是使用PCA模块的捕捉功能,也可以使用定时器延时之类的方式实现解析PPM。但是我认为,能够硬件完成的东西,我肯定不会用软件实现。有问题吗?没有问题!实际上是因为我太菜啦,软件方式搞来搞去,头都晕了,直接操作寄存器它不香吗。这个程序其实是第一次调成功的,其中必然还有很多很多的漏洞,但是作为一个乐观主义者,能接收到数据不就是一个巨大的成功了吗。总比我之前用SBUS接收一整个屏幕的零蛋好吧。