痞酷網_PIGOO

 找回密碼
 立即註冊
!!! [系統偵測到廣告阻擋軟體] !!!

如果您覺得痞酷網對您有些許幫助,或者您認同痞酷網的理想,

那麼希望您將痞酷網設定為白名單.

並請在上論壇的時候,動動您的手指,用行動支持我們.

謝謝!
123
返回列表 發新帖
樓主: antlu

求助:雕刻機馬達PWM驅動電路之後續問題

[複製鏈接]
 樓主| 發表於 2016-7-3 01:27:06 | 顯示全部樓層
本文章最後由 antlu 於 2016-7-3 01:28 AM 編輯
  1. //----- 20160702  取消一次 15個數量的數位濾波  改成累進方式
  2. //-------20160701 改回原程式 因為中斷會造成控制不良 為無中斷模式
  3. //-------20160622 VV--------------------- 非常重要使用中斷 TIM4  main.c 最後要加一些宣告!!
  4. //----20160630 修改啟動程序 先顯示後驅動
  5. #include "stm8s.h"
  6. #include "stm8s_tim1.h"
  7. #include "stm8s_tim4.h"
  8. #include "stm8s_clk.h"
  9. #include "stm8s_delay.h"
  10. #include "stm8s_adc1.h"
  11. #define VR_Channel ADC1_CHANNEL_0// stm8s103k3 pin 16
  12. #define LG12002PORT GPIOC//GPIOC
  13. #define DIN GPIO_PIN_7  //new PIN_4 old version PIN_1
  14. #define Clk GPIO_PIN_6  //new PIN_3 old version PIN_2
  15. #define STB GPIO_PIN_5  //new PIN_1 old version PIN_4
  16. #define Motor_port GPIOC
  17. #define Motor_out GPIO_PIN_1  //PC1 pwm motor driver
  18. u8 a,b,c,d;
  19. u16 VR_data =0;
  20. u8 AD_read_count;//0~3 輪流read out AD count
  21. u8 adc_update_flag;//ADC 更新1次的旗標
  22. u16 pwmwidth = 1;
  23. //u16 ADCValue[15]={0};//電壓值平均用減少誤差雜訊
  24. u16 ADCValueA;
  25. u16 DataADC=0;//最後的電壓值
  26. u8 display_2table[20]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
  27. u16 prev_VR_data;//previous VR data
  28. u8 inc_flag;//prev_VR_data < VR_data
  29. u16 dif_PWM;//prev_VR_data - VR_data
  30. u16 motor_base = 200;//motor PWM base
  31. u32 ADCtemp=0;
  32. u8 display_time;
  33. void GPIOinit(void)
  34. {
  35.         GPIO_Init(Motor_port,Motor_out,GPIO_MODE_OUT_PP_HIGH_FAST);//motor drive
  36.         GPIO_Init(LG12002PORT,DIN|STB|Clk,GPIO_MODE_OUT_PP_HIGH_FAST);//for pt6961 driver
  37. }

  38. void tim4init(void)
  39. {
  40.         TIM4_TimeBaseInit(TIM4_PRESCALER_32,250);//4.05ms TIM4_PRESCALER_32
  41.         TIM4_SetCounter(250);
  42.         TIM4_ITConfig(TIM4_IT_UPDATE,ENABLE);//2Mhz/32/250=4ms
  43.         TIM4_Cmd(ENABLE);
  44. }



  45. void Delay_us(u16 ust)//uS Delay
  46. {
  47.         while(ust !=0)
  48.         {
  49.                 ust--;
  50.         }
  51. }

  52. void DelayMs(u16 mst)//mS delay
  53. {
  54.         while( mst !=0)
  55.         {
  56.                 Delay_us(400);
  57.                 mst--;
  58.         }
  59. }

  60. void Send6961_Data(u8 Dat)
  61. {
  62.           u8 i;
  63.         GPIO_WriteLow(LG12002PORT,STB);
  64.       
  65.                  for (i=0;i<8;i++)
  66.                  {
  67.                           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
  68.                 {
  69.                  GPIO_WriteHigh(LG12002PORT,DIN);
  70.                   }
  71.                 else
  72.                 {
  73.                 GPIO_WriteLow(LG12002PORT,DIN);
  74.                 }
  75.                   Dat>>=1;
  76.                   GPIO_WriteLow(LG12002PORT,Clk);//  GPIO_WriteLow(LEDPORT,Clk);
  77.                   GPIO_WriteHigh(LG12002PORT,Clk);
  78.                  }       
  79.         GPIO_WriteLow(LG12002PORT,STB);  
  80. }

  81. /*
  82.    20141116 send command byte
  83. */

  84. void Send6961_Cmd(u8 Dat)
  85. {
  86.   u8 i;
  87.     GPIO_WriteHigh(LG12002PORT,STB);
  88.    GPIO_WriteLow(LG12002PORT,STB);
  89.       
  90.      for (i=0;i<8;i++)
  91.          {
  92.           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
  93.         {
  94.          GPIO_WriteHigh(LG12002PORT,DIN);
  95.           }
  96.         else
  97.         {
  98.         GPIO_WriteLow(LG12002PORT,DIN);
  99.         }
  100.           Dat>>=1;
  101.           GPIO_WriteLow(LG12002PORT,Clk);// Clk=0;
  102.           GPIO_WriteHigh(LG12002PORT,Clk);
  103.          }
  104.         GPIO_WriteHigh(LG12002PORT,STB);
  105. }

  106. void PT6961_Init(void) // 8bit mode
  107. {
  108.         DelayMs(200);
  109.         Send6961_Cmd(0x40);//CMD 2 fix address normal mode
  110.         Send6961_Cmd(0xc0);//CMD 3 address=0
  111.         Send6961_Data(0x0);
  112.         Send6961_Data(0x00);
  113.         Send6961_Data(0x00);
  114.         Send6961_Data(0x00);       
  115.         Send6961_Cmd(0x02);//CMD 1 6digit 12segment
  116.         Send6961_Cmd(0x89);//CMD 4 display control bright 14/16
  117.         DelayMs(1);       
  118. }


  119. void LGC12002_display(void)
  120. {
  121. Send6961_Cmd(0x40);//CMD 2 fix address normal mode
  122. Send6961_Cmd(0xc0);//CMD 3 address=0
  123. Send6961_Data(0xf0);//空白
  124. Send6961_Data(display_2table[a]);//5
  125. Send6961_Data(0xf0);//空白
  126. Send6961_Data(display_2table[b]);//5
  127. Send6961_Data(0xf0);//空白
  128. Send6961_Data(display_2table[c]);//2
  129. Send6961_Data(0xf0);//空白
  130. Send6961_Data(display_2table[d]);//4
  131. Send6961_Cmd(0x02);//CMD 1 6digit 12segment
  132. Send6961_Cmd(0x89);//CMD 4 display control bright 14/16                       
  133. DelayMs(1);       
  134. }

  135. void TransData(void)// VR_data>> a b c d
  136. {
  137.         u16 result;
  138.         result = VR_data;
  139.          if (result >= 1000)
  140.    {
  141.           a=1;b=0;c=0;d=0;
  142.    }
  143.         else
  144.    {
  145.           a=0;
  146.           b= result/100;
  147.           c= (result%100)/10;
  148.           d= result %10;
  149.    }
  150. }



  151. //-------20160622 ^^----------------
  152. void ADConvert(void)//轉換類比信號成為數位信號
  153. {
  154.         unsigned char ADCcount =0;
  155.         ADC1->CR1|=0x02;
  156.         ADC1_StartConversion();
  157.         /*
  158.         while(ADCcount<15)//10>>13
  159.         {
  160.                 while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
  161.                 ADC1_ClearFlag(ADC1_FLAG_AWS0);
  162.                 ADCValue[ADCcount]=ADC1_GetConversionValue();
  163.                 ADCcount++;
  164.         }
  165.         */
  166.          //new change VVVVV
  167.                 while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
  168.                 ADC1_ClearFlag(ADC1_FLAG_AWS0);
  169.                 ADCValueA = ADC1_GetConversionValue();
  170.    //new change ^^^^
  171.         ADC1->CR1 &= ~0x02;
  172. }

  173. //------ newADCfilter with digital filter 2016 0630

  174. void newDigitalFiltering(void)//把類比信號的10組資料作中間的6組平均
  175. {       
  176. //        u8 i=0;
  177. //        ADCtemp=0;
  178. //  for(i=0; i<15;i++)
  179.         {
  180. //                ADCtemp = ADCtemp-(ADCtemp/4)+ADCValue[i];
  181.     ADCtemp = ADCtemp-(ADCtemp/4)+ADCValueA;
  182.                 DataADC = (ADCtemp/4);
  183.          }
  184. }




  185. /*

  186. void DigitalFiltering(void)//把類比信號的10組資料作中間的6組平均
  187. {
  188.         unsigned char i,j;
  189.         unsigned char cptemp;       
  190.         for(i=10;i>=1;i--)
  191.         {
  192.                 for(j-0;j<(i-1);j++)
  193.                 {
  194.                         if(ADCValue[j]>ADCValue[j+1])
  195.                         {
  196.                                 cptemp=ADCValue[j];
  197.                                 ADCValue[j]=ADCValue[j+1];
  198.                                 ADCValue[j+1]=cptemp;
  199.                         }
  200.                 }
  201.         }
  202.         DataADC=0;
  203.         for(i=2;i<=7;i++)
  204.         {
  205.                 DataADC +=ADCValue[i];
  206.         }
  207.         DataADC /=6;       
  208. }

  209. */

  210. unsigned int ADC1Set(ADC1_Channel_TypeDef ADC_Channel)//讀取不同的AD通道經過類比轉成數位再經過10取6平均送出結果
  211. {
  212. u16 ADresult;
  213. {
  214. ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,ADC_Channel,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);
  215. ADConvert();
  216. newDigitalFiltering();
  217. //DigitalFiltering();
  218. ADresult=DataADC;
  219. DataADC=0;
  220. adc_update_flag=0;
  221. }
  222. return ADresult;
  223. }



  224. void update_TIM1_Config(u8 sw)
  225. {
  226.         switch(sw)
  227.         {
  228.         case 0:
  229.                 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);
  230.         break;

  231.         case 1:
  232.                 TIM1_OC2Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,pwmwidth,TIM1_OCPOLARITY_LOW,TIM1_OCNPOLARITY_HIGH,TIM1_OCIDLESTATE_SET,TIM1_OCNIDLESTATE_RESET);
  233.         break;

  234.         case 2:
  235.                 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);
  236.         break;
  237.         }
  238.         TIM1_Cmd(ENABLE);
  239.         TIM1_CtrlPWMOutputs(ENABLE);
  240. }

  241. void CLK_Config(void)
  242. {
  243.         CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
  244. }

  245. void tim4svc(void)
  246. {

  247. display_time++;
  248. if(display_time==60)//240ms
  249. {       
  250.                 VR_data = ADC1Set(VR_Channel);//channel 0 pin16       
  251.                 TransData();
  252.                 LGC12002_display();       
  253.            display_time=0;
  254.   }               

  255. TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
  256. }


  257. main()
  258. {
  259.         /*
  260. 一開始要關閉pwm輸出
  261. 接下來要把馬達的輸出設為60% 這樣啟動才不會有問題
  262. 馬達的PWM輸出不能過小必須有基本的電壓目前先定20%
  263. PWM 0%電壓為2V 100%為10V 因此輸出電壓平均為2V~10V
  264. 調整VR的%顯示應該放在不會受影響的程式裡考慮  放在中斷裡作顯示

  265.         */
  266.         GPIOinit();
  267.         GPIO_WriteLow(Motor_port,Motor_out);//  防止一通電就馬達暴衝  
  268.         TIM1_DeInit();
  269.         TIM1_TimeBaseInit(1,TIM1_COUNTERMODE_UP,1400,0);        //1400 full range from 200~1200 total 1.4ms
  270. //  tim4init();
  271.         CLK_Config();
  272.   PT6961_Init();//LGC12002 initial               
  273.         prev_VR_data = 200;//set initial VR data;
  274.         pwmwidth = 240;//initial motor drive set 60% power and keep 2秒
  275.        
  276. //        rim();
  277.         VR_data = ADC1Set(VR_Channel);//先顯示VR值再啟動馬達240+200=440的速度若VR=0則會回到最低速200
  278.         TransData();
  279.         LGC12002_display();               
  280.        
  281.         update_TIM1_Config(0);
  282.         DelayMs(2000);
  283.         while (1)       
  284.         {

  285.         VR_data = ADC1Set(VR_Channel);//channel 0 pin16       
  286.                 TransData();
  287.                 LGC12002_display();               

  288.                 if(prev_VR_data >= VR_data)//inc_flag =0 ---prev_VR_data >= VR_data 要減少pwm
  289.                 {
  290.                         inc_flag = 0;
  291.                         dif_PWM = (prev_VR_data - VR_data);                       
  292.                 }
  293.                 else
  294.                 {
  295.                  inc_flag =1;
  296.                  dif_PWM = (VR_data - prev_VR_data);
  297.           }
  298.                
  299.                 if( dif_PWM > 5)// excute PWM change
  300.                 {
  301.                         while(dif_PWM)
  302.                         {
  303.                                 if(inc_flag)
  304.                                         {
  305.                                                 pwmwidth = prev_VR_data+1;
  306.                                         }
  307.                                 else
  308.                                         {
  309.                                                 pwmwidth = prev_VR_data-1;
  310.                                         }
  311.                          update_TIM1_Config(0);
  312.                          DelayMs(5);//加速度
  313.                          dif_PWM -=1;
  314.                   }
  315.                         prev_VR_data = VR_data;//加減速完成更新速度設定
  316.                 }
  317.                 else
  318.                 {
  319.                         pwmwidth = VR_data;
  320.                         update_TIM1_Config(0);
  321.                 }                 
  322.         }
  323. }


  324. @far @interrupt void TIM4_OVF_IRQ(void)
  325. {
  326.         tim4svc();
  327. }




  328. #ifdef USE_FULL_ASSERT

  329. /**
  330.   * @brief  Reports the name of the source file and the source line number
  331.   *   where the assert_param error has occurred.
  332.   * @param file: pointer to the source file name
  333.   * @param line: assert_param error line source number
  334.   * @retval : None
  335.   */
  336. void assert_failed(u8* file, u32 line)
  337. {
  338.   /* User can add his own implementation to report the file name and line number,
  339.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  340.   /* Infinite loop */
  341.   while (1)
  342.   {
  343.   }
  344. }
  345. #endif

  346. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
複製代碼
xiaolaba 發表於 2016-7-2 09:36 PM
LU大 ADC讀取不是由你的主程序自己主動要求的嗎

你的程序裡面好像也是這樣寫, 269行,while (1) {readadc. ...


xiaolaba 大:
    謝謝,DIGITAL FILTER 我改好了,驗證也OK了!!
    後續要試試 中斷的問題!! 再次感謝!!
發表於 2016-7-3 11:21:08 | 顯示全部樓層
本文章最後由 xiaolaba 於 2016-7-3 11:48 AM 編輯
antlu 發表於 2016-7-3 01:27 AM
xiaolaba 大:
    謝謝,DIGITAL FILTER 我改好了,驗證也OK了!!
    後續要試試 中斷的問題!! 再次感謝!! ...



  1. //讀取不同的AD通道經過類比轉成數位再經過10取6平均送出結果
  2. unsigned int ADC1Set(ADC1_Channel_TypeDef ADC_Channel) {

  3.         u16 ADresult;
  4.         {
  5. ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,ADC_Channel,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE); //這個應該是初始化ADC, 應該不用每次都用在ADC轉換的開頭, 開機設定一次就夠, 除非每次轉換設定不同參數或者不同CHANNEL設定不同, 不過看來參數都是常數, 沒有變動.
  6.         ADConvert(); //這個實際執行ADC轉換, 等待2.3us
  7.         newDigitalFiltering(); //ADC完畢, 濾波輸出值存在, DataADC, 現在的tempDAC 不動, 也不需要變動, 留著下一次用
  8. //DigitalFiltering();
  9.         ADresult=DataADC;
  10.         DataADC=0; // 注釋掉這行, 執行OK 嗎, 如果可以就不用這個,  開機設定一次就夠. 因為你每次調用ADC, 輸出控制 PWM, 讀值後然後馬上把結果資料清零, 其實作用不大, 不確定想的對不對. 實機實驗最簡單.
  11.         adc_update_flag=0;
  12.         }
  13.         return ADresult;
  14. }
複製代碼

 樓主| 發表於 2016-7-3 13:03:39 | 顯示全部樓層

xiaolaba 大:
    我把DataADC=0 取消了,結果好像也沒變,目前我就先這樣了!! 謝謝!!
    我把中斷加進去 旗標計數做定期顯示用 卻發現每隔 377us 會有 9us的下降脈衝...

VR=0
screenshot0.png

VR=50
screenshot50.png

VR=50放大
screenshot50elg.png

VR=210
screenshot210.png

VR=700
screenshot700.png

VR=850 之前
screenshot855.png

VR=850 目前
850now.png


VR=1000
screenshot1000.png


評分

1

查看全部評分

 樓主| 發表於 2016-7-3 13:19:17 | 顯示全部樓層
目前測試結果加減速度很不錯,感謝 xiaolaba 大一直不斷的指導和協助修改程式,受益良多!!  感恩!!

  1. //------20160703  嘗試再使用中斷顯示
  2. //----- 20160702  取消一次 15個數量的數位濾波  改成累進方式
  3. //-------20160701 改回原程式 因為中斷會造成控制不良 為無中斷模式
  4. //-------20160622 VV--------------------- 非常重要使用中斷 TIM4  main.c 最後要加一些宣告!!
  5. //----20160630 修改啟動程序 先顯示後驅動
  6. #include "stm8s.h"
  7. #include "stm8s_tim1.h"
  8. #include "stm8s_tim4.h"
  9. #include "stm8s_clk.h"
  10. #include "stm8s_delay.h"
  11. #include "stm8s_adc1.h"
  12. #define VR_Channel ADC1_CHANNEL_0// stm8s103k3 pin 16
  13. #define LG12002PORT GPIOC//GPIOC
  14. #define DIN GPIO_PIN_7  //new PIN_4 old version PIN_1
  15. #define Clk GPIO_PIN_6  //new PIN_3 old version PIN_2
  16. #define STB GPIO_PIN_5  //new PIN_1 old version PIN_4
  17. #define Motor_port GPIOC
  18. #define Motor_out GPIO_PIN_1  //PC1 pwm motor driver
  19. u8 a,b,c,d;
  20. u16 VR_data =0;
  21. u8 AD_read_count;//0~3 輪流read out AD count
  22. u8 adc_update_flag;//ADC 更新1次的旗標
  23. u16 pwmwidth = 1;

  24. u16 ADCValueA;
  25. u16 DataADC=0;//最後的電壓值
  26. u8 display_2table[20]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
  27. u16 prev_VR_data;//previous VR data
  28. u8 inc_flag;//prev_VR_data < VR_data
  29. u16 dif_PWM;//prev_VR_data - VR_data
  30. u16 motor_base = 200;//motor PWM base
  31. u32 ADCtemp=0;
  32. u8 display_time;//中斷顯示用_計時器
  33. u8 display_flag;//中斷產生的顯示旗標
  34. void GPIOinit(void)
  35. {
  36.         GPIO_Init(Motor_port,Motor_out,GPIO_MODE_OUT_PP_HIGH_FAST);//motor drive
  37.         GPIO_Init(LG12002PORT,DIN|STB|Clk,GPIO_MODE_OUT_PP_HIGH_FAST);//for pt6961 driver
  38. }

  39. void tim4init(void)
  40. {
  41.         TIM4_TimeBaseInit(TIM4_PRESCALER_32,250);//4.05ms TIM4_PRESCALER_32
  42.         TIM4_SetCounter(250);
  43.         TIM4_ITConfig(TIM4_IT_UPDATE,ENABLE);//2Mhz/32/250=4ms
  44.         TIM4_Cmd(ENABLE);
  45. }



  46. void Delay_us(u16 ust)//uS Delay
  47. {
  48.         while(ust !=0)
  49.         {
  50.                 ust--;
  51.         }
  52. }

  53. void DelayMs(u16 mst)//mS delay
  54. {
  55.         while( mst !=0)
  56.         {
  57.                 Delay_us(400);
  58.                 mst--;
  59.         }
  60. }

  61. void Send6961_Data(u8 Dat)
  62. {
  63.           u8 i;
  64.         GPIO_WriteLow(LG12002PORT,STB);
  65.       
  66.                  for (i=0;i<8;i++)
  67.                  {
  68.                           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
  69.                 {
  70.                  GPIO_WriteHigh(LG12002PORT,DIN);
  71.                   }
  72.                 else
  73.                 {
  74.                 GPIO_WriteLow(LG12002PORT,DIN);
  75.                 }
  76.                   Dat>>=1;
  77.                   GPIO_WriteLow(LG12002PORT,Clk);//  GPIO_WriteLow(LEDPORT,Clk);
  78.                   GPIO_WriteHigh(LG12002PORT,Clk);
  79.                  }       
  80.         GPIO_WriteLow(LG12002PORT,STB);  
  81. }

  82. /*
  83.    20141116 send command byte
  84. */

  85. void Send6961_Cmd(u8 Dat)
  86. {
  87.   u8 i;
  88.     GPIO_WriteHigh(LG12002PORT,STB);
  89.    GPIO_WriteLow(LG12002PORT,STB);
  90.       
  91.      for (i=0;i<8;i++)
  92.          {
  93.           if((Dat & 0x01)!=0)// SER=Dat & 0x80;
  94.         {
  95.          GPIO_WriteHigh(LG12002PORT,DIN);
  96.           }
  97.         else
  98.         {
  99.         GPIO_WriteLow(LG12002PORT,DIN);
  100.         }
  101.           Dat>>=1;
  102.           GPIO_WriteLow(LG12002PORT,Clk);// Clk=0;
  103.           GPIO_WriteHigh(LG12002PORT,Clk);
  104.          }
  105.         GPIO_WriteHigh(LG12002PORT,STB);
  106. }

  107. void PT6961_Init(void) // 8bit mode
  108. {
  109.         DelayMs(200);
  110.         Send6961_Cmd(0x40);//CMD 2 fix address normal mode
  111.         Send6961_Cmd(0xc0);//CMD 3 address=0
  112.         Send6961_Data(0x0);
  113.         Send6961_Data(0x00);
  114.         Send6961_Data(0x00);
  115.         Send6961_Data(0x00);       
  116.         Send6961_Cmd(0x02);//CMD 1 6digit 12segment
  117.         Send6961_Cmd(0x89);//CMD 4 display control bright 14/16
  118.         DelayMs(1);       
  119. }


  120. void LGC12002_display(void)
  121. {
  122. Send6961_Cmd(0x40);//CMD 2 fix address normal mode
  123. Send6961_Cmd(0xc0);//CMD 3 address=0
  124. Send6961_Data(0xf0);//空白
  125. Send6961_Data(display_2table[a]);//5
  126. Send6961_Data(0xf0);//空白
  127. Send6961_Data(display_2table[b]);//5
  128. Send6961_Data(0xf0);//空白
  129. Send6961_Data(display_2table[c]);//2
  130. Send6961_Data(0xf0);//空白
  131. Send6961_Data(display_2table[d]);//4
  132. Send6961_Cmd(0x02);//CMD 1 6digit 12segment
  133. Send6961_Cmd(0x89);//CMD 4 display control bright 14/16                       
  134. DelayMs(1);       
  135. }

  136. void TransData(void)// VR_data>> a b c d
  137. {
  138.         u16 result;
  139.         result = VR_data;
  140.          if (result >= 1000)
  141.    {
  142.           a=1;b=0;c=0;d=0;
  143.    }
  144.         else
  145.    {
  146.           a=0;
  147.           b= result/100;
  148.           c= (result%100)/10;
  149.           d= result %10;
  150.    }
  151. }



  152. //-------20160622 ^^----------------
  153. void ADConvert(void)//轉換類比信號成為數位信號
  154. {
  155.         unsigned char ADCcount =0;
  156.         ADC1->CR1|=0x02;
  157.         ADC1_StartConversion();

  158.          //new change VVVVV
  159.                 while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
  160.                 ADC1_ClearFlag(ADC1_FLAG_AWS0);
  161.                 ADCValueA = ADC1_GetConversionValue();
  162.    //new change ^^^^
  163.         ADC1->CR1 &= ~0x02;
  164. }

  165. //------ newADCfilter with digital filter 2016 0630

  166. void newDigitalFiltering(void)//把類比信號的10組資料作中間的6組平均
  167. {       
  168.         {
  169.     ADCtemp = ADCtemp-(ADCtemp/4)+ADCValueA;
  170.                 DataADC = (ADCtemp/4);
  171.          }
  172. }






  173. unsigned int ADC1Set(ADC1_Channel_TypeDef ADC_Channel)//讀取不同的AD通道經過類比轉成數位再經過10取6平均送出結果
  174. {
  175. u16 ADresult;
  176. {
  177. ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,ADC_Channel,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);
  178. ADConvert();
  179. newDigitalFiltering();
  180. ADresult=DataADC;
  181. adc_update_flag=0;
  182. }
  183. return ADresult;
  184. }



  185. void update_TIM1_Config(u8 sw)
  186. {
  187.         switch(sw)
  188.         {
  189.         case 0:
  190.                 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);
  191.         break;

  192.         case 1:
  193.                 TIM1_OC2Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,pwmwidth,TIM1_OCPOLARITY_LOW,TIM1_OCNPOLARITY_HIGH,TIM1_OCIDLESTATE_SET,TIM1_OCNIDLESTATE_RESET);
  194.         break;

  195.         case 2:
  196.                 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);
  197.         break;
  198.         }
  199.         TIM1_Cmd(ENABLE);
  200.         TIM1_CtrlPWMOutputs(ENABLE);
  201. }

  202. void CLK_Config(void)
  203. {
  204.         CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
  205. }

  206. void tim4svc(void)
  207. {

  208. display_time++;
  209. if(display_time==60)//240ms
  210. display_flag=1;
  211. TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
  212. }


  213. main()
  214. {
  215.         /*
  216. 一開始要關閉pwm輸出
  217. 接下來要把馬達的輸出設為60% 這樣啟動才不會有問題
  218. 馬達的PWM輸出不能過小必須有基本的電壓目前先定20%
  219. PWM 0%電壓為2V 100%為10V 因此輸出電壓平均為2V~10V
  220. 調整VR的%顯示應該放在不會受影響的程式裡考慮  放在中斷裡作顯示

  221.         */
  222.         GPIOinit();
  223.         GPIO_WriteLow(Motor_port,Motor_out);//  防止一通電就馬達暴衝  
  224.         TIM1_DeInit();
  225.         TIM1_TimeBaseInit(1,TIM1_COUNTERMODE_UP,1400,0);        //1400 full range from 200~1200 total 1.4ms
  226.   tim4init();
  227.         CLK_Config();
  228.   PT6961_Init();//LGC12002 initial               
  229.         prev_VR_data = 200;//set initial VR data;
  230.         pwmwidth = 240;//initial motor drive set 60% power and keep 2秒
  231.        
  232.         rim();
  233.         VR_data = ADC1Set(VR_Channel);//先顯示VR值再啟動馬達240+200=440的速度若VR=0則會回到最低速200
  234.         TransData();
  235.         LGC12002_display();               
  236.        
  237.         update_TIM1_Config(0);
  238.         DelayMs(2000);
  239.         while (1)       
  240.         {

  241.           VR_data = ADC1Set(VR_Channel);//channel 0 pin16       
  242.                 if(display_flag==1)//當中斷旗標成立時後才顯示並且清除 中斷旗標和再次計時  
  243.                 {
  244.                 TransData();
  245.                 LGC12002_display();       
  246.                 display_flag=0;
  247.            display_time=0;
  248.                 }

  249.                 if(prev_VR_data >= VR_data)//inc_flag =0 ---prev_VR_data >= VR_data 要減少pwm
  250.                 {
  251.                         inc_flag = 0;
  252.                         dif_PWM = (prev_VR_data - VR_data);                       
  253.                 }
  254.                 else
  255.                 {
  256.                  inc_flag =1;
  257.                  dif_PWM = (VR_data - prev_VR_data);
  258.           }
  259.                
  260.                 if( dif_PWM > 5)// excute PWM change
  261.                 {
  262.                         while(dif_PWM)
  263.                         {
  264.                                 if(inc_flag)
  265.                                         {
  266.                                                 pwmwidth = prev_VR_data+1;
  267.                                         }
  268.                                 else
  269.                                         {
  270.                                                 pwmwidth = prev_VR_data-1;
  271.                                         }
  272.                          update_TIM1_Config(0);
  273.                          DelayMs(5);//加速度
  274.                          dif_PWM -=1;
  275.                   }
  276.                         prev_VR_data = VR_data;//加減速完成更新速度設定
  277.                 }
  278.                 else
  279.                 {
  280.                         pwmwidth = VR_data;
  281.                         update_TIM1_Config(0);
  282.                 }                 
  283.         }
  284. }


  285. @far @interrupt void TIM4_OVF_IRQ(void)
  286. {
  287.         tim4svc();
  288. }




  289. #ifdef USE_FULL_ASSERT

  290. /**
  291.   * @brief  Reports the name of the source file and the source line number
  292.   *   where the assert_param error has occurred.
  293.   * @param file: pointer to the source file name
  294.   * @param line: assert_param error line source number
  295.   * @retval : None
  296.   */
  297. void assert_failed(u8* file, u32 line)
  298. {
  299.   /* User can add his own implementation to report the file name and line number,
  300.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  301.   /* Infinite loop */
  302.   while (1)
  303.   {
  304.   }
  305. }
  306. #endif

  307. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
複製代碼
您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

關閉

站長小叮嚀上一條 /1 下一條

禁閉室|手機版|連繫我們|痞酷網電子技術論壇

GMT+8, 2024-4-24 10:44 PM , Processed in 0.056029 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.