|
上次發文推動硬碟三相馬達雖然會轉,但是轉的非常"無力",信心也大受打擊,原來電動機的運轉是一個高深的學問,不是像我這樣甚麼都想玩的人可以勝任的!! 先進們提出許多驅動電路,也提供寶貴的 伺服機驅動模式PWM 1ms~2ms 50HZ ,還有 arduino 的pwm 電路和程式,所以就試著做看看這電路,發現電路好像不是那麼難,倒是程式比較複雜,還好書上有一些參考,所以,就這樣邊參考邊修改的把雛型給弄出來了...
選擇按鈕 選擇 PWM1 PWM2 PWM3 的輸出改變 並且由LED顯示,VR 1M歐姆調整電位輸入到 STM8 的 類比輸入 把0~5V 轉成 0~1023 並送給 TIM1 作為 PWM 的改變,1023 = 1.023ms 加上 1000的 offset 使得 PWM寬度為 1.0ms~2.023ms ...
MODE 目前沒有作用,預計要給 數位式伺服機使用..
電路圖 因為找不到STM8S103K3的圖庫 所以用 32接腳取代
使用 QFP32轉版
ARTCAM 電路板
ARTCAM 面板鑽孔標定
測試的波形 因為STM8S103裡面有腳有問題(內部短路?)所以波形有重複
線上微調程式並且確認功能
雕刻機的PCB 部分的線路需要雕刻2次位移0.05mm這樣再和接的時候才比較不會橋接
外殼使用雕刻機定位出 4枝銅柱以及 三個LED 開關的位置,再使用鑽床開孔,因為對雕刻機還沒有信心,用鑽床比較快!!
- // 20160613 for PWM out 3 channel
- #include "stm8s.h"
- #include "stm8s_tim1.h"
- #include "stm8s_clk.h"
- #include "stm8s_delay.h"
- #include "stm8s_adc1.h"
- #define VR_Channel ADC1_CHANNEL_0// stm8s103k3 pin 16
- u16 VR_data;
- u8 AD_read_count;//0~3 輪流read out AD count
- void AD_Data_Update(void);
- u16 ADCValue[10]={0};//電壓值平均用減少誤差雜訊
- u16 DataADC=0;//最後的電壓值
- u8 adc_update_flag;//ADC 更新1次的旗標
- u16 pwmwidth = 1;
- #define inputPORT GPIOA //PB1--mode, PB 2--select sw
- #define outputPORT GPIOC //led Pb5 Pb6 Pb7 11 10 9
- #define LED1 GPIO_PIN_5
- #define LED2 GPIO_PIN_6
- #define LED3 GPIO_PIN_7
- #define MODE_SW GPIO_PIN_1
- #define Select_SW GPIO_PIN_2
- u8 Select_SW_data = 0;
- u8 Key_pressed_flag = 0;
- u8 check_select_SW_count=0;
- u8 select_sw=0;
- void ADConvert(void)//轉換類比信號成為數位信號
- {
- unsigned char ADCcount =0;
- ADC1->CR1|=0x02;
- ADC1_StartConversion();
- while(ADCcount<10)
- {
- while(ADC1_GetFlagStatus(ADC1_FLAG_EOC)==RESET);
- ADC1_ClearFlag(ADC1_FLAG_AWS0);
- ADCValue[ADCcount]=ADC1_GetConversionValue();
- ADCcount++;
- }
- ADC1->CR1 &= ~0x02;
- }
- 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();
- DigitalFiltering();
- ADresult=DataADC;
- DataADC=0;
- adc_update_flag=0;
- }
- return ADresult;
- }
- //---------------------------------------------------------------------
- void Read_select_SW(void)//每按下一次按鍵開關數加一以選擇 通道PWM設定用並且作為LED顯示
- //變數Select_SW_data Key_pressed_flag
- {
- if(GPIO_ReadInputPin(inputPORT,Select_SW)==0)//Select sw be pressed
- {
- //GPIO_WriteHigh(outputPORT,LED2);
- delay(500);
-
- if(GPIO_ReadInputPin(inputPORT,Select_SW)==0)
- {
- // select_sw = GPIO_ReadInputPin(inputPORT,Select_SW);
- while(GPIO_ReadInputPin(inputPORT,Select_SW)==0);
-
- // check_select_SW_count++;
- Select_SW_data++;
- if(Select_SW_data > 2)
- {
- Select_SW_data=0;
- }
- Key_pressed_flag = 1;
- }
- }
- }
-
- void LED_OUT(u8 SW_data)//點亮相關led
- {
- switch(SW_data)
- {
- case 0:
- GPIO_WriteLow(outputPORT,LED1);
- GPIO_WriteHigh(outputPORT,LED2);
- GPIO_WriteHigh(outputPORT,LED3);
- break;
-
- case 1:
- GPIO_WriteHigh(outputPORT,LED1);
- GPIO_WriteLow(outputPORT,LED2);
- GPIO_WriteHigh(outputPORT,LED3);
- break;
- case 2:
- GPIO_WriteHigh(outputPORT,LED1);
- GPIO_WriteHigh(outputPORT,LED2);
- GPIO_WriteLow(outputPORT,LED3);
- break;
- }
-
- }
-
- void GPIOinit(void)//basic i/o setting
- {
- GPIO_Init(inputPORT,Select_SW,GPIO_MODE_IN_PU_NO_IT);//PA1 PA2
- GPIO_Init(outputPORT,(LED1|LED2|LED3),GPIO_MODE_OUT_OD_LOW_FAST);//PC5 PC6 PC7
- }
-
- void update_TIM1_Config(u8 sw)
- {
- switch(sw)
- {
- case 0:
- TIM1_OC1Init(TIM1_OCMODE_PWM2,TIM1_OUTPUTSTATE_ENABLE,TIM1_OUTPUTNSTATE_ENABLE,pwmwidth,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);
- }
- main()
- {
- GPIOinit();
- TIM1_DeInit();
- TIM1_TimeBaseInit(1,TIM1_COUNTERMODE_UP,20000,0); //20ms 1pulse 1us
- CLK_Config();
-
- //test io
- GPIO_WriteHigh(outputPORT,LED3);
- GPIO_WriteLow(outputPORT,LED2);
- GPIO_WriteLow(outputPORT,LED1);
-
- while (1)
-
- {
- Read_select_SW();//每按下一次按鍵開關數加一以選擇 通道PWM設定用並且作為LED顯示 Select_SW_data
-
- if(Key_pressed_flag == 1)
- {
- LED_OUT(Select_SW_data);//點亮相關led
- Key_pressed_flag = 0;
- }
- //read PWM VR data
- VR_data = ADC1Set(VR_Channel);//channel 0 pin16
- //put to PWM pwmwidth parameter
- pwmwidth = VR_data+1000;
-
- update_TIM1_Config(Select_SW_data);
- }
- }
複製代碼
|
評分
-
7
查看全部評分
-
|