1、PWM程序 /*摘要: 功能:1. PA4\PA5指示端閃爍,指示系統(tǒng)處于工作狀態(tài)。 2. 上橋臂開關(guān)管PC1\PC2\PC3同時輸出占空比40%的PWM信號,即高電平占40%。 3. 下橋臂開關(guān)管PB0\PB1\PB2全部處于關(guān)斷狀態(tài),即為低電平。*/ #include "stm8s.h" #define STM8_FREQ_MHZ 16 #define PWM_FREQUENCY 16000 static const u16 hArrPwmVal = ((u16)((STM8_FREQ_MHZ* (u32)1000000)/PWM_FREQUENCY)); //PWM信號周期 //初始化按鍵,指示燈端口 void GPIO_int(void) { GPIOG->DDR=GPIOG->DDR&0x3f;//PG6,PG7按鍵配置為輸入模式 GPIOG->CR1=GPIOG->CR1|0xC0;//PG6,PG7按鍵配置為上拉輸入 GPIOA->DDR=GPIOA->DDR|0x30;//PA4,PA5指示燈配置為輸出模式 GPIOA->CR1=GPIOA->CR1|0x30;//PA4,PA5指示燈d配置為推挽模式 GPIOA->ODR|=0x30;//點亮指示燈 } //系統(tǒng)時鐘配置:內(nèi)部16M void Clock_init(void) { CLK->CKDIVR=0; } //換相電路開關(guān)管IO初始化 void PWM_IO_init(void) { //PB012 下橋臂1有效 GPIOB->DDR=GPIOB->DDR|0x7;//PB012配置為輸出模式 GPIOB->CR1=GPIOB->CR1|0x7;//PB012推挽模式 GPIOB->ODR&=0xf8;//關(guān)閉下橋臂開關(guān)管 //PC123上橋臂1有效 GPIOC->DDR=GPIOC->DDR|0x0E;//PC123配置為輸出模式 GPIOC->CR1=GPIOC->CR1|0x0E;//PC123推挽模式 GPIOC->ODR&=~(0x0E);//關(guān)閉上橋臂開關(guān)管 } //高級定時器初始化配置 void Tim1_init(void) { //計數(shù)器禁止、ARR預(yù)裝載禁止、邊沿對齊模式 TIM1->CR1= 0x04; TIM1->SMCR= 0;//禁止從模式 TIM1->IER= 0;//禁止所有中斷 TIM1->CCER1= 0; //禁止PWM輸出 TIM1->CCER2= 0; TIM1->CCMR1= 0x60; //PWM1模式,禁止預(yù)裝載 TIM1->CCMR2= 0x60; TIM1->CCMR3= 0x60; //prescale= div1 @ 16MHz -> 62.5ns/count, Full scale = 4.09ms TIM1->PSCRH= 0; TIM1->PSCRL= 0; TIM1->ARRH=hArrPwmVal/256;//PWM周期設(shè)定 TIM1->ARRL=hArrPwmVal%256; //disablerepetition counter TIM1->RCR= 0; TIM1->CCR1H=0;TIM1->CCR1L=0;//占空比輸出均為0 TIM1->CCR2H=0;TIM1->CCR1L=0; TIM1->CCR3H=0;TIM1->CCR1L=0; //使能定時計數(shù)器 TIM1->CR1|= 0x01; } main() { unsignedint tem_c=0; unsignedint outpwm; for(tem_c=0;tem_c<50000;tem_c++);//上電延時,等待系統(tǒng)穩(wěn)定 Clock_init();//時鐘配置 GPIO_int();//指示燈端口初始化 PWM_IO_init();//開關(guān)管控制端口初始化 Tim1_init();//高級定時器配置 outpwm=hArrPwmVal*0.4;//占空比輸出設(shè)為40% TIM1->CCR1H= (uint8_t)(outpwm >> 8); TIM1->CCR1L= (uint8_t)(outpwm); TIM1->CCR2H= (uint8_t)(outpwm >> 8); TIM1->CCR2L= (uint8_t)(outpwm); TIM1->CCR3H= (uint8_t)(outpwm >> 8); TIM1->CCR3L= (uint8_t)(outpwm); TIM1->CCER1=0x11;//CH1\CH2通道輸出PWM使能,高電平有效 TIM1->CCER2=0x1;//CH3通道輸出PWM使能,高電平有效 TIM1->BKR|=TIM1_BKR_MOE;//使能PWM輸出 while(1) { for(tem_c=0;tem_c<50000;tem_c++); GPIOA->ODR^=0x30;//PA4\PA5指示燈閃爍 } } 2、運轉(zhuǎn)程序 (1)hall.h #include "stm8s.h" #define H1_PORT GPIOD->IDR #define H1_PIN BIT4 #define H2_PORT GPIOD->IDR #define H2_PIN BIT3 #define H3_PORT GPIOD->IDR #define H3_PIN BIT2 extern unsigned int OutPwmValue; extern unsigned char bHallStartStep; #define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 //下橋臂開關(guān)控制端口定義 #define MCO0_PORT GPIOB #define MCO0_PIN GPIO_PIN_0 #define MCO2_PORT GPIOB #define MCO2_PIN GPIO_PIN_1 #define MCO4_PORT GPIOB #define MCO4_PIN GPIO_PIN_2 #define PWM_A_ON MCO0_PORT->ODR |= (u8)MCO0_PIN; #define PWM_B_ON MCO2_PORT->ODR |=(u8)MCO2_PIN; #define PWM_C_ON MCO4_PORT->ODR |=(u8)MCO4_PIN; #define PWM_A_OFF MCO0_PORT->ODR &=(u8)(~MCO0_PIN); #define PWM_B_OFF MCO2_PORT->ODR &=(u8)(~MCO2_PIN); #define PWM_C_OFF MCO2_PORT->ODR &= (u8)(~MCO4_PIN); void Init_TIM2(void); void TIM2_InitCapturePolarity(void); void ComHandler(void); (2)hall.c #include "hall.h" unsigned char bHallStartStep;//換相步序變量定義 //換相步序值0-5分別對應(yīng)AB\AC\BC\BA\CA\CB unsigned int OutPwmValue=0;//PWM輸出值變量定義 unsigned char bHallSteps[2][8]={ {7,5,3,4,1,0,2,7},//正轉(zhuǎn) {7,2,0,1,4,3,5,7}//反轉(zhuǎn) }; const unsigned charPWM_EN1_TAB[6]={0x01,0x01,0x10,0x10,0x00,0x00}; //六步法中,CH1\CH2通道極性及使能配置 const unsigned charPWM_EN2_TAB[6]={0x0,0x00,0x00,0x0,0x1,0x1}; //六步法中,CH3通道極性及使能配置 //初始化HALL捕獲輸入定義器 void Init_TIM2(void) { //計數(shù)器禁止、ARR預(yù)裝載禁止、向上計數(shù)、邊沿對齊模式 TIM2->CR1= BIT2; //禁止TIM2所有中斷 TIM2->IER= 0;//禁止中斷 TIM2->CCMR1= 0x01;//TIM2的CH1\CH2\CH3通道配置為輸入 TIM2->CCMR2= 0x01; TIM2->CCMR3= 0x01; #defineIC_FILTER (u8)(5 << 4) TIM2->CCMR1|= IC_FILTER; //輸入捕獲濾波器 TIM2->CCMR2|= IC_FILTER; TIM2->CCMR3|= IC_FILTER; //prescale= div3 @ 16MHz -> 0.5us/count * 24MHz -> 0.33us/count TIM2->PSCR= 0; TIM2->ARRH=0xff;//計數(shù)周期設(shè)為最大 TIM2->ARRL=0xff; TIM2->CCER1|= 0x01;//TIM2的CH1\CH2\CH3通道使能捕獲功能 TIM2->CCER1|= 0x10; TIM2->CCER2|= 0x01; TIM2->CR1|= 0x01;//使能TIM2定時器 } //根據(jù)HALL狀態(tài)換相,啟動電機(jī)運行 void TIM2_InitCapturePolarity(void) { u8bHStatus = 0; GPIOD->DDR&= (u8)(~(0x1c));//HALL端口模式配置 //Read status of H1 and set the expected polarity if(H1_PORT & H1_PIN) { TIM2->CCER1|= BIT1; bHStatus|= BIT2; } else { TIM2->CCER1&= (u8)(~(BIT1)); } //Read status of H2 and set the expected polarity if(H2_PORT & H2_PIN) { TIM2->CCER1|= BIT5; bHStatus|= BIT1; } else { TIM2->CCER1&= (u8)(~(BIT5)); } //Read status of H3 and set the expected polarity if(H3_PORT & H3_PIN) { TIM2->CCER2|= BIT1; bHStatus|= BIT0; } else { TIM2->CCER2&= (u8)(~(BIT1)); } bHallStartStep= bHallSteps[0][bHStatus];//得到換相步序 if(bHallStartStep == 7)//不該出現(xiàn)的HALL狀態(tài) { return; } TIM2->SR1=(u8)~(TIM2_IT_CC3|TIM2_IT_CC2|TIM2_IT_CC1); TIM2->IER= 0x0e;//使能輸入捕獲中斷 ComHandler();//輸出PWM信號,啟動電機(jī) } //捕獲中斷,即HALL狀態(tài)變化時,進(jìn)入此中斷 @near @interrupt @svlreg voidTIM2_CAP_COM_IRQHandler(void) { u8bHStatus = 0; //Read status of H1 and set the expected polarity if(H1_PORT & H1_PIN) { TIM2->CCER1|= BIT1; bHStatus|= BIT2; } else { TIM2->CCER1&= (u8)(~(BIT1)); } //Read status of H2 and set the expected polarity if(H2_PORT & H2_PIN) { TIM2->CCER1|= BIT5; bHStatus|= BIT1; } else { TIM2->CCER1&= (u8)(~(BIT5)); } //Read status of H3 and set the expected polarity if(H3_PORT & H3_PIN) { TIM2->CCER2|= BIT1; bHStatus|= BIT0; } else { TIM2->CCER2&= (u8)(~(BIT1)); } if(TIM2->SR1 & BIT2) { TIM2->SR1=(u8)(~TIM2_IT_CC2); } if(TIM2->SR1 & BIT1) { TIM2->SR1=(u8)(~TIM2_IT_CC1); } if(TIM2->SR1 & BIT3) { TIM2->SR1=(u8)(~TIM2_IT_CC3); } bHallStartStep= bHallSteps[0][bHStatus];//得到換相步序 if(bHallStartStep == 7) { //故障,停止輸出 TIM1->BKR&= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM輸出 PWM_A_OFF; PWM_B_OFF; PWM_C_OFF; return; } ComHandler(); //換相 return; } //換相子函數(shù) void ComHandler(void) { TIM1->BKR&= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM輸出 if(bHallStartStep!=3&&bHallStartStep!=4) PWM_A_OFF; if(bHallStartStep!=0&&bHallStartStep!=5) PWM_B_OFF; if(bHallStartStep!=1&&bHallStartStep!=2) PWM_C_OFF; //根據(jù)換相步序,打開不同的開關(guān)管,并施加正確的PWM信號 if(bHallStartStep==0)//AB { TIM1->CCR1H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR1L = (uint8_t)(OutPwmValue); PWM_B_ON; } elseif(bHallStartStep==1) //AC { TIM1->CCR1H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR1L = (uint8_t)(OutPwmValue); PWM_C_ON; } elseif(bHallStartStep==2) //BC { TIM1->CCR2H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR2L = (uint8_t)(OutPwmValue); PWM_C_ON; } elseif(bHallStartStep==3) //BA { TIM1->CCR2H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR2L = (uint8_t)(OutPwmValue); PWM_A_ON; } elseif(bHallStartStep==4)//CA { TIM1->CCR3H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR3L = (uint8_t)(OutPwmValue); PWM_A_ON; } elseif(bHallStartStep==5) //CB { TIM1->CCR3H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR3L = (uint8_t)(OutPwmValue); PWM_B_ON; } TIM1->CCER1=PWM_EN1_TAB[bHallStartStep]; TIM1->CCER2=PWM_EN2_TAB[bHallStartStep]; TIM1->BKR|=TIM1_BKR_MOE;//使能PWM輸出 } (3)mian.c /*摘要: 功能:1. PA4\PA5指示端閃爍,指示系統(tǒng)處于工作狀態(tài)。 2. 上橋臂開關(guān)管PC1\PC2\PC3輸出占空比20%的PWM信號,即高電平占20%。 3. 上電根據(jù)HALL狀態(tài)換相,并在輸出PWM信號后,電機(jī)會轉(zhuǎn)動,同時HALL信號不斷改變,然后進(jìn)入捕獲中斷,進(jìn)行及時換相。如此實現(xiàn)電機(jī)的運轉(zhuǎn)控制。*/ #include "stm8s.h" #include "hall.h" #define STM8_FREQ_MHZ 16 #define PWM_FREQUENCY 16000 static const u16 hArrPwmVal =((u16)((STM8_FREQ_MHZ * (u32)1000000)/PWM_FREQUENCY)); //PWM信號周期 //初始化按鍵,指示燈端口 void GPIO_int(void) { GPIOG->DDR=GPIOG->DDR&0x3f;//PG6,PG7按鍵配置為輸入模式 GPIOG->CR1=GPIOG->CR1|0xC0;//PG6,PG7按鍵配置為上拉輸入 GPIOA->DDR=GPIOA->DDR|0x30;//PA4,PA5指示燈配置為輸出模式 GPIOA->CR1=GPIOA->CR1|0x30;//PA4,PA5指示燈d配置為推挽模式 GPIOA->ODR|=0x30;//點亮指示燈 } //系統(tǒng)時鐘配置:內(nèi)部16M void Clock_init(void) { CLK->CKDIVR=0; } //換相電路開關(guān)管IO初始化 void PWM_IO_init(void) { //PB012 下橋臂1有效 GPIOB->DDR=GPIOB->DDR|0x7;//PB012配置為輸出模式 GPIOB->CR1=GPIOB->CR1|0x7;//PB012推挽模式 GPIOB->ODR&=0xf8;//關(guān)閉下橋臂開關(guān)管 //PC123上橋臂1有效 GPIOC->DDR=GPIOC->DDR|0x0E;//PC123配置為輸出模式 GPIOC->CR1=GPIOC->CR1|0x0E;//PC123推挽模式 GPIOC->ODR&=~(0x0E);//關(guān)閉上橋臂開關(guān)管 } //高級定時器初始化配置 void Tim1_init(void) { //計數(shù)器禁止、ARR預(yù)裝載禁止、邊沿對齊模式 TIM1->CR1= 0x04; TIM1->SMCR= 0;//禁止從模式 TIM1->IER= 0;//禁止所有中斷 TIM1->CCER1= 0; //禁止PWM輸出 TIM1->CCER2= 0; TIM1->CCMR1= 0x60; //PWM1模式,禁止預(yù)裝載 TIM1->CCMR2= 0x60; TIM1->CCMR3= 0x60; //prescale= div1 @ 16MHz -> 62.5ns/count, Full scale = 4.09ms TIM1->PSCRH= 0; TIM1->PSCRL= 0; TIM1->ARRH=hArrPwmVal/256;//PWM周期設(shè)定 TIM1->ARRL=hArrPwmVal%256; //disablerepetition counter TIM1->RCR= 0; TIM1->CCR1H=0;TIM1->CCR1L=0;//占空比輸出均為0 TIM1->CCR2H=0;TIM1->CCR1L=0; TIM1->CCR3H=0;TIM1->CCR1L=0; //使能定時計數(shù)器 TIM1->CR1|= 0x01; } main() { unsignedint tem_c=0; for(tem_c=0;tem_c<50000;tem_c++);//上電延時,等待系統(tǒng)穩(wěn)定 Clock_init();//時鐘配置 GPIO_int();//指示燈端口初始化 PWM_IO_init();//開關(guān)管控制端口初始化 Tim1_init();//高級定時器配置 Init_TIM2();//捕獲輸入定時器初始化配置 enableInterrupts(); OutPwmValue=hArrPwmVal*0.2;//固定20%占空比的PWM值 TIM2_InitCapturePolarity();//根據(jù)HALL狀態(tài)輸出PWM狀態(tài),啟動電機(jī)運行 while(1) { for(tem_c=0;tem_c<50000;tem_c++); GPIOA->ODR^=0x30;//PA4\PA5指示燈閃爍 } } 3、啟停和調(diào)速 (1)hall.h #include "stm8s.h" #define H1_PORT GPIOD->IDR #define H1_PIN BIT4 #define H2_PORT GPIOD->IDR #define H2_PIN BIT3 #define H3_PORT GPIOD->IDR #define H3_PIN BIT2 extern unsigned char St_F;//啟停變量 extern unsigned char FaultF;//故障標(biāo)志 extern unsigned char Run_dir;//運轉(zhuǎn)標(biāo)志 extern unsigned int OutPwmValue; extern unsigned char bHallStartStep; #define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 //下橋臂開關(guān)控制端口定義 #define MCO0_PORT GPIOB #define MCO0_PIN GPIO_PIN_0 #define MCO2_PORT GPIOB #define MCO2_PIN GPIO_PIN_1 #define MCO4_PORT GPIOB #define MCO4_PIN GPIO_PIN_2 #define PWM_A_ON MCO0_PORT->ODR |=(u8)MCO0_PIN; #define PWM_B_ON MCO2_PORT->ODR |=(u8)MCO2_PIN; #define PWM_C_ON MCO4_PORT->ODR |=(u8)MCO4_PIN; #define PWM_A_OFF MCO0_PORT->ODR &=(u8)(~MCO0_PIN); #define PWM_B_OFF MCO2_PORT->ODR &=(u8)(~MCO2_PIN); #define PWM_C_OFF MCO2_PORT->ODR &=(u8)(~MCO4_PIN); void Init_TIM2(void); void TIM2_InitCapturePolarity(void); void ComHandler(void); (2)hall.c #include "hall.h" unsigned char bHallStartStep;//換相步序變量定義 //換相步序值0-5分別對應(yīng)AB\AC\BC\BA\CA\CB unsigned int OutPwmValue=0;//PWM輸出值變量定義 unsigned char St_F=0;//啟停標(biāo)志,0時為停止,1時為啟動 unsigned char FaultF=0;//故障標(biāo)志 unsigned char Run_dir=0;//運轉(zhuǎn)方向,0-1對立 unsigned char bHallSteps[2][8]={ {7,5,3,4,1,0,2,7},//正轉(zhuǎn) {7,2,0,1,4,3,5,7}//反轉(zhuǎn) }; const unsigned charPWM_EN1_TAB[6]={0x01,0x01,0x10,0x10,0x00,0x00}; //六步法中,CH1\CH2通道極性及使能配置 const unsigned charPWM_EN2_TAB[6]={0x0,0x00,0x00,0x0,0x1,0x1}; //六步法中,CH3通道極性及使能配置 //初始化HALL捕獲輸入定義器 void Init_TIM2(void) { //計數(shù)器禁止、ARR預(yù)裝載禁止、向上計數(shù)、邊沿對齊模式 TIM2->CR1= BIT2; //禁止TIM2所有中斷 TIM2->IER= 0;//禁止中斷 TIM2->CCMR1= 0x01;//TIM2的CH1\CH2\CH3通道配置為輸入 TIM2->CCMR2= 0x01; TIM2->CCMR3= 0x01; #defineIC_FILTER (u8)(5 << 4) TIM2->CCMR1|= IC_FILTER; //輸入捕獲濾波器 TIM2->CCMR2|= IC_FILTER; TIM2->CCMR3|= IC_FILTER; //prescale= div3 @ 16MHz -> 0.5us/count * 24MHz -> 0.33us/count TIM2->PSCR= 0; TIM2->ARRH=0xff;//計數(shù)周期設(shè)為最大 TIM2->ARRL=0xff; TIM2->CCER1|= 0x01;//TIM2的CH1\CH2\CH3通道使能捕獲功能 TIM2->CCER1|= 0x10; TIM2->CCER2|= 0x01; TIM2->CR1|= 0x01;//使能TIM2定時器 } //根據(jù)HALL狀態(tài)換相,啟動電機(jī)運行 void TIM2_InitCapturePolarity(void) { u8bHStatus = 0; GPIOD->DDR&= (u8)(~(0x1c));//HALL端口模式配置 //Read status of H1 and set the expected polarity if(H1_PORT & H1_PIN) { TIM2->CCER1|= BIT1; bHStatus|= BIT2; } else { TIM2->CCER1&= (u8)(~(BIT1)); } //Read status of H2 and set the expected polarity if(H2_PORT & H2_PIN) { TIM2->CCER1|= BIT5; bHStatus|= BIT1; } else { TIM2->CCER1&= (u8)(~(BIT5)); } //Read status of H3 and set the expected polarity if(H3_PORT & H3_PIN) { TIM2->CCER2|= BIT1; bHStatus|= BIT0; } else { TIM2->CCER2&= (u8)(~(BIT1)); } bHallStartStep= bHallSteps[Run_dir][bHStatus];//得到換相步序 if(bHallStartStep == 7)//不該出現(xiàn)的HALL狀態(tài) { return; } TIM2->SR1=(u8)~(TIM2_IT_CC3|TIM2_IT_CC2|TIM2_IT_CC1); TIM2->IER= 0x0e;//使能輸入捕獲中斷 ComHandler();//輸出PWM信號,啟動電機(jī) } //捕獲中斷,即HALL狀態(tài)變化時,進(jìn)入此中斷 @near @interrupt @svlreg voidTIM2_CAP_COM_IRQHandler(void) { u8bHStatus = 0; //Read status of H1 and set the expected polarity if(H1_PORT & H1_PIN) { TIM2->CCER1|= BIT1; bHStatus|= BIT2; } else { TIM2->CCER1&= (u8)(~(BIT1)); } //Read status of H2 and set the expected polarity if(H2_PORT & H2_PIN) { TIM2->CCER1|= BIT5; bHStatus|= BIT1; } else { TIM2->CCER1&= (u8)(~(BIT5)); } //Read status of H3 and set the expected polarity if(H3_PORT & H3_PIN) { TIM2->CCER2|= BIT1; bHStatus|= BIT0; } else { TIM2->CCER2&= (u8)(~(BIT1)); } if(TIM2->SR1 & BIT2) { TIM2->SR1=(u8)(~TIM2_IT_CC2); } if(TIM2->SR1 & BIT1) { TIM2->SR1=(u8)(~TIM2_IT_CC1); } if(TIM2->SR1 & BIT3) { TIM2->SR1=(u8)(~TIM2_IT_CC3); } bHallStartStep= bHallSteps[Run_dir][bHStatus];//得到換相步序 if(bHallStartStep == 7) { //故障,停止輸出 TIM1->BKR&= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM輸出 PWM_A_OFF; PWM_B_OFF; PWM_C_OFF; return; } ComHandler(); //換相 return; } //換相子函數(shù) void ComHandler(void) { TIM1->BKR&= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM輸出 if(FaultF!=0||St_F==0) {PWM_A_OFF;PWM_B_OFF;PWM_C_OFF;return;} if(bHallStartStep!=3&&bHallStartStep!=4) PWM_A_OFF; if(bHallStartStep!=0&&bHallStartStep!=5) PWM_B_OFF; if(bHallStartStep!=1&&bHallStartStep!=2) PWM_C_OFF; //根據(jù)換相步序,打開不同的開關(guān)管,并施加正確的PWM信號 if(bHallStartStep==0)//AB { TIM1->CCR1H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR1L = (uint8_t)(OutPwmValue); PWM_B_ON; } elseif(bHallStartStep==1) //AC { TIM1->CCR1H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR1L = (uint8_t)(OutPwmValue); PWM_C_ON; } elseif(bHallStartStep==2) //BC { TIM1->CCR2H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR2L = (uint8_t)(OutPwmValue); PWM_C_ON; } elseif(bHallStartStep==3) //BA { TIM1->CCR2H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR2L = (uint8_t)(OutPwmValue); PWM_A_ON; } elseif(bHallStartStep==4)//CA { TIM1->CCR3H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR3L = (uint8_t)(OutPwmValue); PWM_A_ON; } elseif(bHallStartStep==5) //CB { TIM1->CCR3H= (uint8_t)(OutPwmValue >> 8); TIM1->CCR3L = (uint8_t)(OutPwmValue); PWM_B_ON; } TIM1->CCER1=PWM_EN1_TAB[bHallStartStep]; TIM1->CCER2=PWM_EN2_TAB[bHallStartStep]; TIM1->BKR|=TIM1_BKR_MOE;//使能PWM輸出 } (3)mian.c /*功能: 1. PD5指示燈,上電亮,指示系統(tǒng)處于工作狀態(tài)。 2.PA4指示燈,指示電機(jī)啟停與否。 3.PA5指示燈,指示電機(jī)運行方向 4.上橋臂開關(guān)管PC1\PC2\PC3輸出可變PWM信號,以完成調(diào)速功能。 5.PG7按鍵為電機(jī)啟停控制鍵,PG6為電機(jī)方向切換鍵。 6.PF5電位器,旋轉(zhuǎn)時實現(xiàn)PWM開環(huán)調(diào)速功能。*/ #include "stm8s.h" #include "hall.h" #define STM8_FREQ_MHZ 16 #define PWM_FREQUENCY 16000 static const u16 hArrPwmVal =((u16)((STM8_FREQ_MHZ * (u32)1000000)/PWM_FREQUENCY)); //PWM信號周期 //hArrPwmVal=1000 #define MINPWMPERCENT 10 #define MAXPWMPERCENT 90 #define MINVALUE MINPWMPERCENT*10 //hArrPwmVal=1000 //MINPWMPERCENT*hArrPwmVal/100簡化為MINPWMPERCENT*10 #define MAXVALUE MAXPWMPERCENT*10 //MAXPWMPERCENT*hArrPwmVal/100簡化MAXPWMPERCENT*10 //初始化按鍵,指示燈端口 void GPIO_int(void) { GPIOG->DDR=GPIOG->DDR&0x3f;//PG6,PG7按鍵配置為輸入模式 GPIOG->CR1=GPIOG->CR1|0xC0;//PG6,PG7按鍵配置為上拉輸入 GPIOA->DDR=GPIOA->DDR|0x30;//PA4,PA5指示燈配置為輸出模式 GPIOA->CR1=GPIOA->CR1|0x30;//PA4,PA5指示燈d配置為推挽模式 GPIOA->ODR|=0x30;//關(guān)閉指示燈 GPIOD->DDR=GPIOD->DDR|0x20;//PD5指示燈配置為輸出模式 GPIOD->CR1=GPIOD->CR1|0x20;//PD5指示燈d配置為推挽模式 GPIOD->ODR&=~0x20;//點亮指示燈,指示系統(tǒng)工作 } //系統(tǒng)時鐘配置:內(nèi)部16M void Clock_init(void) { CLK->CKDIVR=0; } //電位器調(diào)速AD初始 PF5 初始化 AIN13 void AD_int(void) { u8value; u16ADC_TDR_tmp; ADC2->CSR= 13; //AIN13通道選擇 //select4MHz clock based on 16MHz fMaster (div4), single mode ADC2->CR1= 0x20; ADC2->CR2= 0x08;//數(shù)據(jù)右對齊 ADC2->TDRH=0x20;//AIN13禁止施密特觸發(fā) ADC2->CR1|= 0X01;//使能ADC value=30; while(value--);//等待ADC穩(wěn)定 ADC2->CSR&= 0x7f;//清EOC標(biāo)志 ADC2->CR1|= 0x01;//啟動AD } //換相電路開關(guān)管IO初始化 void PWM_IO_init(void) { //PB012 下橋臂1有效 GPIOB->DDR=GPIOB->DDR|0x7;//PB012配置為輸出模式 GPIOB->CR1=GPIOB->CR1|0x7;//PB012推挽模式 GPIOB->ODR&=0xf8;//關(guān)閉下橋臂開關(guān)管 //PC123上橋臂1有效 GPIOC->DDR=GPIOC->DDR|0x0E;//PC123配置為輸出模式 GPIOC->CR1=GPIOC->CR1|0x0E;//PC123推挽模式 GPIOC->ODR&=~(0x0E);//關(guān)閉上橋臂開關(guān)管 } //高級定時器初始化配置 void Tim1_init(void) { //計數(shù)器禁止、ARR預(yù)裝載禁止、邊沿對齊模式 TIM1->CR1= 0x04; TIM1->SMCR= 0;//禁止從模式 TIM1->IER= 0;//禁止所有中斷 TIM1->CCER1= 0; //禁止PWM輸出 TIM1->CCER2= 0; TIM1->CCMR1= 0x60; //PWM1模式,禁止預(yù)裝載 TIM1->CCMR2= 0x60; TIM1->CCMR3= 0x60; //prescale= div1 @ 16MHz -> 62.5ns/count, Full scale = 4.09ms TIM1->PSCRH= 0; TIM1->PSCRL= 0; TIM1->ARRH=hArrPwmVal/256;//PWM周期設(shè)定 TIM1->ARRL=hArrPwmVal%256; //disablerepetition counter TIM1->RCR= 0; TIM1->CCR1H=0;TIM1->CCR1L=0;//占空比輸出均為0 TIM1->CCR2H=0;TIM1->CCR1L=0; TIM1->CCR3H=0;TIM1->CCR1L=0; //使能定時計數(shù)器 TIM1->CR1|= 0x01; } main() { unsignedint tem_c=0; unsignedchar B_k1=0,B_k2=0; unsignedint ADConverValue=0; for(tem_c=0;tem_c<50000;tem_c++);//上電延時,等待系統(tǒng)穩(wěn)定 Clock_init();//時鐘配置 GPIO_int();//指示燈端口初始化 PWM_IO_init();//開關(guān)管控制端口初始化 Tim1_init();//高級定時器配置 Init_TIM2();//捕獲輸入定時器初始化配置 enableInterrupts(); AD_int(); OutPwmValue=MINVALUE; while(1) {if((GPIOG->IDR&0x80)==0x80)B_k1=0;//PG7為啟停鍵 elseif(B_k1==0)//PG7按下時,指示燈亮 { for(tem_c=0;tem_c<500;tem_c++); if((GPIOG->IDR&0x80)==0x00) { B_k1=1; if(FaultF!=0)FaultF=0;//當(dāng)前處于故障狀態(tài) St_F=1-St_F;//啟停標(biāo)志變量改變 if(St_F==1)//啟動 { TIM2_InitCapturePolarity(); //根據(jù)HALL狀態(tài)輸出PWM狀態(tài),啟動電機(jī)運行 GPIOA->ODR&=~(0x10); //PA4指示燈亮,表示啟動電機(jī) } else { ComHandler();//根據(jù)啟停標(biāo)志變量關(guān)閉PWM輸出。 GPIOA->ODR|=0x10;//電機(jī)停止運行指示燈指示 } } } if((GPIOG->IDR&0x40)==0x40)B_k2=0;//PG6為方向鍵 elseif(B_k2==0)//PG7按下時,指示燈滅 { for(tem_c=0;tem_c<500;tem_c++); if((GPIOG->IDR&0x40)==0x00) { B_k2=1; if(St_F==0)//電機(jī)處于停止?fàn)顟B(tài) { Run_dir=1-Run_dir;//方向切換 GPIOA->ODR^=0x20;//PA5指示燈變換 } } } if(ADC2->CSR&0x80) { ADC2->CSR&= (u8)(~0x80);//清除EOC標(biāo)志 ADConverValue=ADC2->DRH*256+ADC2->DRL;//讀取AD轉(zhuǎn)換值 ADC2->CR1|= 0x01;//啟動AD if(ADConverValue<MINVALUE) ADConverValue=MINVALUE; elseif(ADConverValue>MAXVALUE) ADConverValue=MAXVALUE; OutPwmValue=ADConverValue;//賦值PWM輸出變量值 } if(FaultF==1) { ComHandler();//故障時,關(guān)閉PWM輸出 FaultF=2; } } }
|