| 
 | 
 
 樓主 |
發表於 2016-7-3 01:27:06
|
顯示全部樓層
 
 
 
 本文章最後由 antlu 於 2016-7-3 01:28 AM 編輯  
- //----- 20160702  取消一次 15個數量的數位濾波  改成累進方式
 
 - //-------20160701 改回原程式 因為中斷會造成控制不良 為無中斷模式
 
 - //-------20160622 VV--------------------- 非常重要使用中斷 TIM4  main.c 最後要加一些宣告!!
 
 - //----20160630 修改啟動程序 先顯示後驅動
 
 - #include "stm8s.h"
 
 - #include "stm8s_tim1.h"
 
 - #include "stm8s_tim4.h"
 
 - #include "stm8s_clk.h"
 
 - #include "stm8s_delay.h"
 
 - #include "stm8s_adc1.h"
 
 - #define VR_Channel ADC1_CHANNEL_0// stm8s103k3 pin 16
 
 - #define LG12002PORT GPIOC//GPIOC
 
 - #define DIN GPIO_PIN_7  //new PIN_4 old version PIN_1
 
 - #define Clk GPIO_PIN_6  //new PIN_3 old version PIN_2
 
 - #define STB GPIO_PIN_5  //new PIN_1 old version PIN_4
 
 - #define Motor_port GPIOC
 
 - #define Motor_out GPIO_PIN_1  //PC1 pwm motor driver
 
 - u8 a,b,c,d;
 
 - u16 VR_data =0;
 
 - u8 AD_read_count;//0~3 輪流read out AD count
 
 - u8 adc_update_flag;//ADC 更新1次的旗標
 
 - u16 pwmwidth = 1;
 
 - //u16 ADCValue[15]={0};//電壓值平均用減少誤差雜訊
 
 - u16 ADCValueA;
 
 - u16 DataADC=0;//最後的電壓值
 
 - u8 display_2table[20]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
 
 - u16 prev_VR_data;//previous VR data
 
 - u8 inc_flag;//prev_VR_data < VR_data
 
 - u16 dif_PWM;//prev_VR_data - VR_data
 
 - u16 motor_base = 200;//motor PWM base
 
 - u32 ADCtemp=0;
 
 - u8 display_time;
 
 - void GPIOinit(void)
 
 - {
 
 -         GPIO_Init(Motor_port,Motor_out,GPIO_MODE_OUT_PP_HIGH_FAST);//motor drive 
 
 -         GPIO_Init(LG12002PORT,DIN|STB|Clk,GPIO_MODE_OUT_PP_HIGH_FAST);//for pt6961 driver
 
 - }
 
  
- void tim4init(void)
 
 - {
 
 -         TIM4_TimeBaseInit(TIM4_PRESCALER_32,250);//4.05ms TIM4_PRESCALER_32 
 
 -         TIM4_SetCounter(250);
 
 -         TIM4_ITConfig(TIM4_IT_UPDATE,ENABLE);//2Mhz/32/250=4ms
 
 -         TIM4_Cmd(ENABLE);
 
 - }
 
  
 
 
- void Delay_us(u16 ust)//uS Delay
 
 - {
 
 -         while(ust !=0)
 
 -         {
 
 -                 ust--;
 
 -         }
 
 - }
 
  
- void DelayMs(u16 mst)//mS delay
 
 - {
 
 -         while( mst !=0)
 
 -         {
 
 -                 Delay_us(400);
 
 -                 mst--;
 
 -         }
 
 - }
 
  
- void Send6961_Data(u8 Dat) 
 
 - {
 
 -           u8 i;
 
 -         GPIO_WriteLow(LG12002PORT,STB);
 
 -        
 
 -                  for (i=0;i<8;i++)
 
 -                  {
 
 -                           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
 
 -                 {
 
 -                  GPIO_WriteHigh(LG12002PORT,DIN);
 
 -                   }
 
 -                 else
 
 -                 {
 
 -                 GPIO_WriteLow(LG12002PORT,DIN);
 
 -                 }
 
 -                   Dat>>=1;
 
 -                   GPIO_WriteLow(LG12002PORT,Clk);//  GPIO_WriteLow(LEDPORT,Clk);
 
 -                   GPIO_WriteHigh(LG12002PORT,Clk); 
 
 -                  }        
 
 -         GPIO_WriteLow(LG12002PORT,STB);  
 
 - }
 
  
- /*
 
 -    20141116 send command byte
 
 - */
 
  
- void Send6961_Cmd(u8 Dat) 
 
 - {
 
 -   u8 i;
 
 -     GPIO_WriteHigh(LG12002PORT,STB);
 
 -    GPIO_WriteLow(LG12002PORT,STB);
 
 -        
 
 -      for (i=0;i<8;i++)
 
 -          {
 
 -           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
 
 -         {
 
 -          GPIO_WriteHigh(LG12002PORT,DIN);
 
 -           }
 
 -         else
 
 -         {
 
 -         GPIO_WriteLow(LG12002PORT,DIN);
 
 -         }
 
 -           Dat>>=1;
 
 -           GPIO_WriteLow(LG12002PORT,Clk);// Clk=0;
 
 -           GPIO_WriteHigh(LG12002PORT,Clk); 
 
 -          } 
 
 -         GPIO_WriteHigh(LG12002PORT,STB);
 
 - }
 
  
- void PT6961_Init(void) // 8bit mode 
 
 - {
 
 -         DelayMs(200);
 
 -         Send6961_Cmd(0x40);//CMD 2 fix address normal mode
 
 -         Send6961_Cmd(0xc0);//CMD 3 address=0
 
 -         Send6961_Data(0x0);
 
 -         Send6961_Data(0x00);
 
 -         Send6961_Data(0x00);
 
 -         Send6961_Data(0x00);        
 
 -         Send6961_Cmd(0x02);//CMD 1 6digit 12segment 
 
 -         Send6961_Cmd(0x89);//CMD 4 display control bright 14/16
 
 -         DelayMs(1);        
 
 - }
 
  
 
- void LGC12002_display(void)
 
 - {
 
 - Send6961_Cmd(0x40);//CMD 2 fix address normal mode
 
 - Send6961_Cmd(0xc0);//CMD 3 address=0
 
 - Send6961_Data(0xf0);//空白
 
 - Send6961_Data(display_2table[a]);//5
 
 - Send6961_Data(0xf0);//空白
 
 - Send6961_Data(display_2table[b]);//5
 
 - Send6961_Data(0xf0);//空白
 
 - Send6961_Data(display_2table[c]);//2
 
 - Send6961_Data(0xf0);//空白
 
 - Send6961_Data(display_2table[d]);//4
 
 - Send6961_Cmd(0x02);//CMD 1 6digit 12segment 
 
 - Send6961_Cmd(0x89);//CMD 4 display control bright 14/16                        
 
 - DelayMs(1);        
 
 - }
 
  
- void TransData(void)// VR_data>> a b c d 
 
 -  {
 
 -         u16 result;
 
 -         result = VR_data;
 
 -          if (result >= 1000)
 
 -    {
 
 -           a=1;b=0;c=0;d=0;
 
 -    }
 
 -         else
 
 -    {
 
 -           a=0;
 
 -           b= result/100;
 
 -           c= (result%100)/10;
 
 -           d= result %10;
 
 -    }
 
 - }
 
  
 
 
- //-------20160622 ^^----------------
 
 - void ADConvert(void)//轉換類比信號成為數位信號
 
 - {
 
 -         unsigned char ADCcount =0;
 
 -         ADC1->CR1|=0x02;
 
 -         ADC1_StartConversion();
 
 -         /*
 
 -         while(ADCcount<15)//10>>13
 
 -         {
 
 -                 while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
 
 -                 ADC1_ClearFlag(ADC1_FLAG_AWS0);
 
 -                 ADCValue[ADCcount]=ADC1_GetConversionValue();
 
 -                 ADCcount++;
 
 -         }
 
 -         */
 
 -          //new change VVVVV
 
 -                 while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
 
 -                 ADC1_ClearFlag(ADC1_FLAG_AWS0);
 
 -                 ADCValueA = ADC1_GetConversionValue();
 
 -    //new change ^^^^
 
 -         ADC1->CR1 &= ~0x02;
 
 - }
 
  
- //------ newADCfilter with digital filter 2016 0630
 
  
- void newDigitalFiltering(void)//把類比信號的10組資料作中間的6組平均
 
 - {        
 
 - //        u8 i=0;
 
 - //        ADCtemp=0;
 
 - //  for(i=0; i<15;i++)
 
 -         {
 
 - //                ADCtemp = ADCtemp-(ADCtemp/4)+ADCValue[i];
 
 -     ADCtemp = ADCtemp-(ADCtemp/4)+ADCValueA;
 
 -                 DataADC = (ADCtemp/4);
 
 -          }
 
 - }
 
  
 
 
 
- /*
 
  
- void DigitalFiltering(void)//把類比信號的10組資料作中間的6組平均
 
 - {
 
 -         unsigned char i,j;
 
 -         unsigned char cptemp;        
 
 -         for(i=10;i>=1;i--)
 
 -         {
 
 -                 for(j-0;j<(i-1);j++)
 
 -                 {
 
 -                         if(ADCValue[j]>ADCValue[j+1])
 
 -                         {
 
 -                                 cptemp=ADCValue[j];
 
 -                                 ADCValue[j]=ADCValue[j+1];
 
 -                                 ADCValue[j+1]=cptemp;
 
 -                         }
 
 -                 }
 
 -         }
 
 -         DataADC=0;
 
 -         for(i=2;i<=7;i++)
 
 -         {
 
 -                 DataADC +=ADCValue[i];
 
 -         }
 
 -         DataADC /=6;        
 
 - }
 
  
- */
 
  
- unsigned int ADC1Set(ADC1_Channel_TypeDef ADC_Channel)//讀取不同的AD通道經過類比轉成數位再經過10取6平均送出結果
 
 - { 
 
 - u16 ADresult;
 
 - {
 
 - ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,ADC_Channel,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);
 
 -  ADConvert();
 
 -  newDigitalFiltering();
 
 - //DigitalFiltering();
 
 -  ADresult=DataADC;
 
 -  DataADC=0;
 
 -  adc_update_flag=0;
 
 -  }
 
 -  return ADresult;
 
 - }
 
  
 
 
-  void update_TIM1_Config(u8 sw)
 
 - {
 
 -         switch(sw)
 
 -         {
 
 -         case 0:
 
 -                 TIM1_OC1Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,(pwmwidth+motor_base),TIM1_OCPOLARITY_LOW,TIM1_OCNPOLARITY_HIGH,TIM1_OCIDLESTATE_SET,TIM1_OCNIDLESTATE_RESET);
 
 -         break;
 
  
-         case 1:
 
 -                 TIM1_OC2Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,pwmwidth,TIM1_OCPOLARITY_LOW,TIM1_OCNPOLARITY_HIGH,TIM1_OCIDLESTATE_SET,TIM1_OCNIDLESTATE_RESET);
 
 -         break;
 
  
-         case 2:
 
 -                 TIM1_OC3Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,pwmwidth+20,TIM1_OCPOLARITY_LOW,TIM1_OCNPOLARITY_HIGH,TIM1_OCIDLESTATE_SET,TIM1_OCNIDLESTATE_RESET);
 
 -         break; 
 
 -         }
 
 -         TIM1_Cmd(ENABLE);
 
 -         TIM1_CtrlPWMOutputs(ENABLE);
 
 - }
 
  
-  void CLK_Config(void)
 
 - {
 
 -         CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
 
 - }
 
  
- void tim4svc(void)
 
 - {
 
  
-  display_time++;
 
 -  if(display_time==60)//240ms
 
 -  {        
 
 -                 VR_data = ADC1Set(VR_Channel);//channel 0 pin16        
 
 -                 TransData();
 
 -                 LGC12002_display();        
 
 -            display_time=0;
 
 -   }                
 
  
-  TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
 
 - }
 
  
 
- main()
 
 - {
 
 -         /*
 
 -  一開始要關閉pwm輸出
 
 -  接下來要把馬達的輸出設為60% 這樣啟動才不會有問題
 
 -  馬達的PWM輸出不能過小必須有基本的電壓目前先定20%
 
 -  PWM 0%電壓為2V 100%為10V 因此輸出電壓平均為2V~10V
 
 -  調整VR的%顯示應該放在不會受影響的程式裡考慮  放在中斷裡作顯示
 
 -  
 
 -          */
 
 -         GPIOinit();
 
 -         GPIO_WriteLow(Motor_port,Motor_out);//  防止一通電就馬達暴衝  
 
 -         TIM1_DeInit();
 
 -         TIM1_TimeBaseInit(1,TIM1_COUNTERMODE_UP,1400,0);        //1400 full range from 200~1200 total 1.4ms
 
 - //  tim4init();
 
 -         CLK_Config();
 
 -   PT6961_Init();//LGC12002 initial                
 
 -         prev_VR_data = 200;//set initial VR data;
 
 -         pwmwidth = 240;//initial motor drive set 60% power and keep 2秒
 
 -         
 
 - //        rim();
 
 -         VR_data = ADC1Set(VR_Channel);//先顯示VR值再啟動馬達240+200=440的速度若VR=0則會回到最低速200
 
 -         TransData();
 
 -         LGC12002_display();                
 
 -         
 
 -         update_TIM1_Config(0);
 
 -         DelayMs(2000);
 
 -         while (1)        
 
 -         {
 
  
-         VR_data = ADC1Set(VR_Channel);//channel 0 pin16        
 
 -                 TransData();
 
 -                 LGC12002_display();                
 
  
-                 if(prev_VR_data >= VR_data)//inc_flag =0 ---prev_VR_data >= VR_data 要減少pwm
 
 -                 {
 
 -                         inc_flag = 0;
 
 -                         dif_PWM = (prev_VR_data - VR_data);                        
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                  inc_flag =1;
 
 -                  dif_PWM = (VR_data - prev_VR_data);
 
 -           }
 
 -                 
 
 -                 if( dif_PWM > 5)// excute PWM change
 
 -                 {
 
 -                         while(dif_PWM)
 
 -                         {
 
 -                                 if(inc_flag)
 
 -                                         {
 
 -                                                 pwmwidth = prev_VR_data+1;
 
 -                                         }
 
 -                                 else
 
 -                                         {
 
 -                                                 pwmwidth = prev_VR_data-1;
 
 -                                         }
 
 -                          update_TIM1_Config(0);
 
 -                          DelayMs(5);//加速度
 
 -                          dif_PWM -=1;
 
 -                   }
 
 -                         prev_VR_data = VR_data;//加減速完成更新速度設定
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         pwmwidth = VR_data;
 
 -                         update_TIM1_Config(0);
 
 -                 }                 
 
 -         }
 
 - }
 
  
 
- @far @interrupt void TIM4_OVF_IRQ(void)
 
 - {
 
 -         tim4svc();
 
 - }
 
  
 
 
 
- #ifdef USE_FULL_ASSERT
 
  
- /**
 
 -   * @brief  Reports the name of the source file and the source line number
 
 -   *   where the assert_param error has occurred.
 
 -   * @param file: pointer to the source file name
 
 -   * @param line: assert_param error line source number
 
 -   * @retval : None
 
 -   */
 
 - void assert_failed(u8* file, u32 line)
 
 - { 
 
 -   /* User can add his own implementation to report the file name and line number,
 
 -      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  
-   /* Infinite loop */
 
 -   while (1)
 
 -   {
 
 -   }
 
 - }
 
 - #endif
 
  
- /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
 
 
  複製代碼 
 
xiaolaba 大: 
    謝謝,DIGITAL FILTER 我改好了,驗證也OK了!! 
    後續要試試 中斷的問題!! 再次感謝!! |   
 
 
 
 |