找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4068|回复: 0
打印 上一主题 下一主题
收起左侧

6通道PPM转PWM信号解码单片机源程序

[复制链接]
跳转到指定楼层
楼主
ID:572103 发表于 2019-9-14 23:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. //PPM 解码程序
  2. //用INT0接PPM信号
  3. //T0计数,用来测量脉宽
  4. //注意,这个不是标准的PPM信号,刚好和PPM信号相位相反
  5. //测得的PPM信号在LCD上显示
  6. //PPM信号取自天地飞6A接收机
  7. # include <stc.h>
  8. # include <intrins.h>
  9. # define DataPort P0
  10. sbit RS=P2^4;
  11. sbit RW=P2^5;
  12. sbit EN=P2^6;
  13. unsigned char channel=0,i=0;
  14. unsigned int xdata PPM_channel1[10],PPM_channel2[10],PPM_channel3[10],PPM_channel4[10],PPM_channel5[10],PPM_channel6[10];
  15. bit Timer0_OverFlowFlag=0;//定时器0的溢出标志,如果溢出,则有问题;
  16. unsigned char qian,bai,shi,ge;
  17. # define RS_CLR RS=0;
  18. # define RS_SET RS=1;
  19. # define RW_SET RW=1;
  20. # define RW_CLR RW=0;
  21. # define EN_CLR EN=0;
  22. # define EN_SET EN=1;
  23. //和LCD显示有关的函数定义
  24. void LCD_Check_Busy(void); //查忙函数
  25. void LCD_Clear(void);//清屏函数
  26. void LCD_Init(void);//lcd初始化函数
  27. void LCD_Write_Com(unsigned char com);//控制字写入函数
  28. void LCD_Write_Data(unsigned char Data);//数据写入函数
  29. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);//写入单个字符
  30. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);//写入字符串
  31. unsigned int filter(unsigned int *s);//中值平局滤波;
  32. void DepartNum(unsigned int temp);//用于分解要显示的数据
  33. void DelayUs2x(unsigned char t);
  34. void DelayMs(unsigned int t);

  35. void main(void)
  36. {   
  37.     unsigned char *InitIform;
  38. unsigned int temp;
  39. InitIform="Init_is_OK";
  40. LCD_Init();
  41. DelayMs(10);
  42. LCD_Write_String(3,0,InitIform);

  43. //初始化Timer0
  44. TMOD=0x01;//timer0 方式1
  45. ET0=1;//允许timer0中断
  46. //初始化INT0
  47. IT0=1;//负跳变触发中断;
  48. EX0=1;
  49. EA=1;

  50. DelayMs(10000);
  51. while(1)
  52. {
  53.      temp=filter(PPM_channel1);
  54.   DepartNum(temp);
  55.   LCD_Write_Char(0,0,'A');
  56.   LCD_Write_Char(1,0,qian);
  57.   LCD_Write_Char(2,0,bai);
  58.   LCD_Write_Char(3,0,shi);
  59.   LCD_Write_Char(4,0,ge);
  60.      temp=filter(PPM_channel2);   
  61.   DepartNum(temp);
  62.   LCD_Write_Char(5,0,'B');
  63.   LCD_Write_Char(6,0,qian);
  64.   LCD_Write_Char(7,0,bai);
  65.   LCD_Write_Char(8,0,shi);
  66.   LCD_Write_Char(9,0,ge);
  67.      temp=filter(PPM_channel3);
  68.   DepartNum(temp);
  69.   LCD_Write_Char(10,0,'C');
  70.   LCD_Write_Char(11,0,qian);
  71.   LCD_Write_Char(12,0,bai);
  72.   LCD_Write_Char(13,0,shi);
  73.   LCD_Write_Char(14,0,ge);
  74.      temp=filter(PPM_channel4);
  75.   DepartNum(temp);
  76.   LCD_Write_Char(0,1,'D');
  77.   LCD_Write_Char(1,1,qian);
  78.   LCD_Write_Char(2,1,bai);
  79.   LCD_Write_Char(3,1,shi);
  80.   LCD_Write_Char(4,1,ge);
  81.   
  82.      temp=filter(PPM_channel5);
  83.   DepartNum(temp);
  84.   LCD_Write_Char(5,1,'E');
  85.   LCD_Write_Char(6,1,qian);
  86.   LCD_Write_Char(7,1,bai);
  87.   LCD_Write_Char(8,1,shi);
  88.   LCD_Write_Char(9,1,ge);
  89.      temp=filter(PPM_channel6);
  90.   DepartNum(temp);
  91.   LCD_Write_Char(10,1,'F');
  92.   LCD_Write_Char(11,1,qian);
  93.   LCD_Write_Char(12,1,bai);
  94.   LCD_Write_Char(13,1,shi);
  95.   LCD_Write_Char(14,1,ge);
  96. //  DelayMs(1000);
  97. }
  98.       
  99. }

  100. void DelayUs2x(unsigned char t)
  101. {   
  102. while(--t);
  103. }
  104. void DelayMs(unsigned int t)
  105. {
  106.      
  107. while(t--)
  108. {
  109.      //大致延时1mS
  110.      DelayUs2x(245);
  111.   DelayUs2x(245);
  112. }
  113. }
  114. //查忙函数
  115. void LCD_Check_Busy(void)
  116. {
  117. unsigned char i=255;
  118. DataPort= 0xff;
  119. RS_CLR;
  120. RW_SET;
  121. EN_SET;
  122. while(i--&&(DataPort&0x80));
  123. EN_CLR;
  124. }
  125. //控制字写入函数,入口参数是控制字
  126. void LCD_Write_Com(unsigned char com)
  127. {
  128. LCD_Check_Busy();
  129. RS_CLR;
  130. RW_CLR;
  131. DataPort=com;
  132. EN_SET;
  133. _nop_();
  134. EN_CLR;
  135. }
  136. //写入数据,入口参数是要写入的数据
  137. void LCD_Write_Data(unsigned char Data)
  138. {
  139. LCD_Check_Busy();
  140. RS_SET;
  141. RW_CLR;
  142. DataPort=Data;
  143. EN_SET;
  144. _nop_();
  145. EN_CLR;
  146. }
  147. //清屏函数
  148. void LCD_Clear(void )
  149. {
  150. LCD_Write_Com(0x01);
  151. DelayMs(5);  
  152. }
  153. //LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),*S显示的字符串
  154. void LCD_Write_String(unsigned char x,unsigned char y, unsigned char *s)
  155. {
  156. if(y==0) LCD_Write_Com(0x80+x);
  157. else LCD_Write_Com(0xc0+x);
  158. while(*s)
  159. {
  160.   LCD_Write_Data(*s);
  161.   s++;
  162. }
  163. }
  164. //LCD显示字符串,入口参数是 字符显示的位置X(0-15),显示的行数y(0,1 ),Data显示的字符
  165. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  166. {
  167.   if(y==0) LCD_Write_Com(0x80+x);
  168.   else LCD_Write_Com(0xc0+x);
  169.      DelayMs(1);//a little delay for simulation
  170.   LCD_Write_Data(Data);
  171. }

  172. //lcd初始化函数
  173. void LCD_Init(void)
  174. {
  175. LCD_Write_Com(0x38);// set the display model
  176. DelayMs(5);
  177. LCD_Write_Com(0x08);//turn down the display
  178. //LCD_Write_Com(0x01);//clear the display
  179. LCD_Clear();
  180. LCD_Write_Com(0x06);//set the 光标 moving model
  181. DelayMs(5);
  182. LCD_Write_Com(0x0c);//显示开和光标设置
  183. }
  184. /****************************************
  185. 用于显示的数位分解函数,把数据转化为ASCII码
  186. 入口参数是要显示的数据
  187. ****************************************/
  188. void DepartNum(unsigned int temp)
  189. {
  190. qian=temp/1000+0x30;
  191. bai=temp%1000/100+0x30;
  192. shi=temp%100/10+0x30;
  193. ge= temp%10+0x30;
  194. }
  195. void ISIR_INT0(void) interrupt 0
  196. {
  197. unsigned int PPM_temp;
  198. if(TR0)
  199. {
  200.   TR0=0;//停止计数;
  201.   PPM_temp=TH0;
  202.   PPM_temp=(PPM_temp<<8)|TL0;
  203.   TH0=0;
  204.   TL0=0;
  205.   TR0=1;//给TH0和TL0赋初值后重新启动定时器
  206. }
  207. else
  208. {
  209.   TH0=0;//如果是第一次启动中断,则启动timer0
  210.   TL0=0;
  211.   TR0=1;
  212. }
  213. if(PPM_temp>3000|| Timer0_OverFlowFlag)//判断引导区
  214. {
  215.   channel=0;
  216.   Timer0_OverFlowFlag=0;
  217.   i++;
  218.   if(i==10) i=0;
  219. }
  220. switch(channel)
  221. {
  222. case 1: PPM_channel1[i]=PPM_temp; break;
  223. case 2: PPM_channel2[i]=PPM_temp; break;
  224. case 3: PPM_channel3[i]=PPM_temp; break;
  225. case 4: PPM_channel4[i]=PPM_temp; break;
  226. case 5: PPM_channel5[i]=PPM_temp; break;
  227. case 6: PPM_channel6[i]=PPM_temp; break;
  228. case 7: break;
  229. case 8: break;
  230. default:break;
  231. }
  232. channel++;
  233. }
  234. void ISIR_Timer0(void) interrupt 1
  235. {
  236. Timer0_OverFlowFlag=1;
  237. }
  238. unsigned int filter(unsigned int *s)
  239. {
  240. unsigned char k,j;
  241. unsigned int sum=0;
  242. unsigned int temp;
  243. for(k=0;k<9;k++)
  244.   for(j=k+1;j<10;j++)   
  245.   if(s[k]>s[j])
  246.   {
  247.    temp=s[k];
  248.    s[k]=s[j];
  249.    s[j]=temp;
  250.   }
  251. for(k=1;k<9;k++)
  252. sum+=s[k];
  253. sum=sum/8;
  254. return sum;
  255. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表