找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于单片机软件滤波的方法,求大神

[复制链接]
跳转到指定楼层
楼主
ID:309126 发表于 2018-5-23 16:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个程序采用的滤波方法不好,我测量5V的电压是,电压会跳动,会调到10v,6V,7V,8V有时候还会调到0V,有什么方法吗

单片机源码:
  1. #include "12c5a.h"
  2. #include "intrins.h"
  3. #include "stdio.h"
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. //sfr ADC_LOW2  = 0XBE;
  7. #define ADC_POWER   0X80
  8. #define ADC_FLAG    0X10
  9. #define ADC_START   0X08                        
  10. #define ADC_SPEEDLL 0X00
  11. #define ADC_SPEEDL  0X20
  12. #define ADC_SPEEDH  0X40
  13. #define ADC_SPEEDHH 0X60
  14. #define N 12

  15. sbit PWM1=P2^0;
  16. sbit P3_1=P3^1;
  17. uchar time;
  18. uint Val=3;
  19. uint Serror,FError,MK=2;
  20. uchar Kp,Ti,Td;

  21. void delay(uint n)
  22. {
  23.         uint x;
  24.         while(n--)
  25.         {
  26.                 x=5000;
  27.                 while(x--);
  28.         }
  29. }

  30. /*---------------------------- 初始化ADC特殊功能寄存器 -------------------*/

  31. void InitADC( )
  32. {

  33.           P1ASF = P1 | 0x3f;                //Set  P1.0 - P1.5 as analog input port
  34.           ADC_RES  = 0;                  //Clear previous result
  35.           ADC_RESL = 0;
  36.           ADC_CONTR = ADC_POWER | ADC_SPEEDLL ;
  37.           delay(20);                      //ADC power-on delay and Start A/D conversion
  38. }
  39. unsigned int AD_get(unsigned char channel)                //ad取值
  40. {
  41.         ADC_CONTR=0x88|channel;   
  42.         _nop_(); _nop_(); _nop_(); _nop_();
  43.         while(!(ADC_CONTR&0x10));   
  44.                 ADC_CONTR&=0xe7;   
  45.         return(ADC_RES*4+ADC_RESL);  
  46. }
  47. float AD_work(unsigned char channel)                         //ad求平均值
  48. {
  49.         float AD_val;   
  50.         unsigned char i;
  51.         for(i=0;i<100;i++)
  52.         AD_val+=AD_get(channel);
  53.         AD_val/=100;
  54.         AD_val=AD_get(channel);
  55.         AD_val=AD_val*(5.0/1024);
  56.         return AD_val;
  57. }
  58. void UART_init()
  59. {
  60.         TMOD = 0x20;          //T1工作模式2  8位自动重装
  61.         TH1 = 0xfd;
  62.         TL1 = 0xfd;         //比特率9600
  63.         TR1 = 1;                //启动T1定时器
  64.         SM0 = 0;
  65.         SM1 = 1;                 //串口工作方式1 10位异步
  66.         REN = 1;                //串口允许接收
  67.         EA  = 1;                //开总中断
  68.         ES  = 1;                //串口中断打开
  69. }

  70. /*********************************************************

  71.   发送数据函数

  72. *********************************************************/
  73. void senddata(float dat)
  74. {
  75.          ES=0;
  76.          TI=1;
  77.      printf("%f \n",dat);
  78.      while(!TI);
  79.      TI = 0;
  80.          ES=1;
  81. }

  82. /*************PID初始化函数***************/
  83. void PID_init(void){
  84.         Serror=0;
  85.         FError=0;
  86.         Kp=2;
  87.         Ti=500;
  88.         Td=10;
  89.         }

  90. int PID_control(int Now_speed)
  91. {
  92.         int Error,Serror,result;
  93.         Error=Now_speed-Val;
  94.         Serror=Serror+Error;
  95.         MK=(Kp*Error+Kp*0.05/Ti*Serror+Kp*Td/0.05*(Error-FError));
  96.         FError=Error;
  97.         //对占空比进行限幅处理
  98.         if(MK<1)
  99.         {MK=1;}
  100.         else if(MK>9)
  101.         {result=9;}
  102.         return MK;
  103. }

  104. void key()
  105. {

  106. }


  107. void main()
  108. {      
  109.         UART_init();
  110.         InitADC( );
  111. //        TMOD=0x01;//定时器0工作方式1
  112. //        TH0=0xff;//(65536-10)/256;//赋初值定时
  113. //        TL0=0xf7;//(65536-10)%256;//0.01ms
  114. //        EA=1;//开总中断
  115. //        ET0=1;//开定时器0中断
  116. //        TR0=1;//启动定时器0
  117.         PID_init();
  118.         while(1)
  119.         {
  120.                 float k;
  121.       
  122.                 k=41*AD_work(0);
  123.                 PID_control(k);
  124.                 senddata(Val);
  125.                 delay(100);
  126.                         if(P3_1==0)
  127.         {
  128.                 Val++;
  129.         }
  130.                
  131.         }
  132. }


  133. //void tim0() interrupt 1
  134. //{
  135. //        TR0=0;//赋初值时,关闭定时器
  136. //        TH0=0xff;//(65536-10)/256;//赋初值定时
  137. //        TL0=0xf9;//(65536-10)%256;//0.01ms
  138. //        TR0=1;//打开定时器
  139. //        time++;
  140. //        if(time>=10) time=0;//1khz
  141. //        if(time>=MK) PWM1=0;//点空比%80
  142. //        else PWM1=1;
  143. //        PWM2=0;      
  144. //}
复制代码


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

使用道具 举报

沙发
ID:808700 发表于 2020-7-28 15:19 | 只看该作者
试试一阶滤波
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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