- //PPM 解码程序
- //用INT0接PPM信号
- //T0计数,用来测量脉宽
- //注意,这个不是标准的PPM信号,刚好和PPM信号相位相反
- //测得的PPM信号在LCD上显示
- //PPM信号取自天地飞6A接收机
- # include <stc.h>
- # include <intrins.h>
- # define DataPort P0
- sbit RS=P2^4;
- sbit RW=P2^5;
- sbit EN=P2^6;
- unsigned char channel=0,i=0;
- unsigned int xdata PPM_channel1[10],PPM_channel2[10],PPM_channel3[10],PPM_channel4[10],PPM_channel5[10],PPM_channel6[10];
- bit Timer0_OverFlowFlag=0;//定时器0的溢出标志,如果溢出,则有问题;
- unsigned char qian,bai,shi,ge;
- # define RS_CLR RS=0;
- # define RS_SET RS=1;
- # define RW_SET RW=1;
- # define RW_CLR RW=0;
- # define EN_CLR EN=0;
- # define EN_SET EN=1;
- //和LCD显示有关的函数定义
- void LCD_Check_Busy(void); //查忙函数
- void LCD_Clear(void);//清屏函数
- void LCD_Init(void);//lcd初始化函数
- void LCD_Write_Com(unsigned char com);//控制字写入函数
- void LCD_Write_Data(unsigned char Data);//数据写入函数
- void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);//写入单个字符
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);//写入字符串
- unsigned int filter(unsigned int *s);//中值平局滤波;
- void DepartNum(unsigned int temp);//用于分解要显示的数据
- void DelayUs2x(unsigned char t);
- void DelayMs(unsigned int t);
- void main(void)
- {
- unsigned char *InitIform;
- unsigned int temp;
- InitIform="Init_is_OK";
- LCD_Init();
- DelayMs(10);
- LCD_Write_String(3,0,InitIform);
- //初始化Timer0
- TMOD=0x01;//timer0 方式1
- ET0=1;//允许timer0中断
- //初始化INT0
- IT0=1;//负跳变触发中断;
- EX0=1;
- EA=1;
-
- DelayMs(10000);
- while(1)
- {
- temp=filter(PPM_channel1);
- DepartNum(temp);
- LCD_Write_Char(0,0,'A');
- LCD_Write_Char(1,0,qian);
- LCD_Write_Char(2,0,bai);
- LCD_Write_Char(3,0,shi);
- LCD_Write_Char(4,0,ge);
- temp=filter(PPM_channel2);
- DepartNum(temp);
- LCD_Write_Char(5,0,'B');
- LCD_Write_Char(6,0,qian);
- LCD_Write_Char(7,0,bai);
- LCD_Write_Char(8,0,shi);
- LCD_Write_Char(9,0,ge);
- temp=filter(PPM_channel3);
- DepartNum(temp);
- LCD_Write_Char(10,0,'C');
- LCD_Write_Char(11,0,qian);
- LCD_Write_Char(12,0,bai);
- LCD_Write_Char(13,0,shi);
- LCD_Write_Char(14,0,ge);
- temp=filter(PPM_channel4);
- DepartNum(temp);
- LCD_Write_Char(0,1,'D');
- LCD_Write_Char(1,1,qian);
- LCD_Write_Char(2,1,bai);
- LCD_Write_Char(3,1,shi);
- LCD_Write_Char(4,1,ge);
-
- temp=filter(PPM_channel5);
- DepartNum(temp);
- LCD_Write_Char(5,1,'E');
- LCD_Write_Char(6,1,qian);
- LCD_Write_Char(7,1,bai);
- LCD_Write_Char(8,1,shi);
- LCD_Write_Char(9,1,ge);
- temp=filter(PPM_channel6);
- DepartNum(temp);
- LCD_Write_Char(10,1,'F');
- LCD_Write_Char(11,1,qian);
- LCD_Write_Char(12,1,bai);
- LCD_Write_Char(13,1,shi);
- LCD_Write_Char(14,1,ge);
- // DelayMs(1000);
- }
-
- }
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- void DelayMs(unsigned int t)
- {
-
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- //查忙函数
- void LCD_Check_Busy(void)
- {
- unsigned char i=255;
- DataPort= 0xff;
- RS_CLR;
- RW_SET;
- EN_SET;
- while(i--&&(DataPort&0x80));
- EN_CLR;
- }
- //控制字写入函数,入口参数是控制字
- void LCD_Write_Com(unsigned char com)
- {
- LCD_Check_Busy();
- RS_CLR;
- RW_CLR;
- DataPort=com;
- EN_SET;
- _nop_();
- EN_CLR;
- }
- //写入数据,入口参数是要写入的数据
- void LCD_Write_Data(unsigned char Data)
- {
- LCD_Check_Busy();
- RS_SET;
- RW_CLR;
- DataPort=Data;
- EN_SET;
- _nop_();
- EN_CLR;
- }
- //清屏函数
- void LCD_Clear(void )
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- //LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),*S显示的字符串
- void LCD_Write_String(unsigned char x,unsigned char y, unsigned char *s)
- {
- if(y==0) LCD_Write_Com(0x80+x);
- else LCD_Write_Com(0xc0+x);
- while(*s)
- {
- LCD_Write_Data(*s);
- s++;
- }
- }
- //LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),Data显示的字符
- void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
- {
- if(y==0) LCD_Write_Com(0x80+x);
- else LCD_Write_Com(0xc0+x);
- DelayMs(1);//a little delay for simulation
- LCD_Write_Data(Data);
- }
- //lcd初始化函数
- void LCD_Init(void)
- {
- LCD_Write_Com(0x38);// set the display model
- DelayMs(5);
- LCD_Write_Com(0x08);//turn down the display
- //LCD_Write_Com(0x01);//clear the display
- LCD_Clear();
- LCD_Write_Com(0x06);//set the 光标 moving model
- DelayMs(5);
- LCD_Write_Com(0x0c);//显示开和光标设置
- }
- /****************************************
- 用于显示的数位分解函数,把数据转化为ASCII码
- 入口参数是要显示的数据
- ****************************************/
- void DepartNum(unsigned int temp)
- {
- qian=temp/1000+0x30;
- bai=temp%1000/100+0x30;
- shi=temp%100/10+0x30;
- ge= temp%10+0x30;
- }
- void ISIR_INT0(void) interrupt 0
- {
- unsigned int PPM_temp;
- if(TR0)
- {
- TR0=0;//停止计数;
- PPM_temp=TH0;
- PPM_temp=(PPM_temp<<8)|TL0;
- TH0=0;
- TL0=0;
- TR0=1;//给TH0和TL0赋初值后重新启动定时器
- }
- else
- {
- TH0=0;//如果是第一次启动中断,则启动timer0
- TL0=0;
- TR0=1;
- }
- if(PPM_temp>3000|| Timer0_OverFlowFlag)//判断引导区
- {
- channel=0;
- Timer0_OverFlowFlag=0;
- i++;
- if(i==10) i=0;
- }
- switch(channel)
- {
- case 1: PPM_channel1[i]=PPM_temp; break;
- case 2: PPM_channel2[i]=PPM_temp; break;
- case 3: PPM_channel3[i]=PPM_temp; break;
- case 4: PPM_channel4[i]=PPM_temp; break;
- case 5: PPM_channel5[i]=PPM_temp; break;
- case 6: PPM_channel6[i]=PPM_temp; break;
- case 7: break;
- case 8: break;
- default:break;
- }
- channel++;
- }
- void ISIR_Timer0(void) interrupt 1
- {
- Timer0_OverFlowFlag=1;
- }
- unsigned int filter(unsigned int *s)
- {
- unsigned char k,j;
- unsigned int sum=0;
- unsigned int temp;
- for(k=0;k<9;k++)
- for(j=k+1;j<10;j++)
- if(s[k]>s[j])
- {
- temp=s[k];
- s[k]=s[j];
- s[j]=temp;
- }
- for(k=1;k<9;k++)
- sum+=s[k];
- sum=sum/8;
- return sum;
- }
复制代码 |