找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4481|回復(fù): 0
收起左側(cè)

stm32f407驅(qū)動(dòng)步進(jìn)電機(jī)(用限位傳感器限制位置)

[復(fù)制鏈接]
ID:807127 發(fā)表于 2020-7-24 15:21 | 顯示全部樓層 |閱讀模式
本帖最后由 resumebb 于 2020-7-24 16:19 編輯

一、硬件
1.硬件準(zhǔn)備:57步進(jìn)電機(jī)(型號(hào)57CM18),驅(qū)動(dòng)器TB6600,開(kāi)發(fā)板STM32F407ZGT6,SN-4NDO限位金屬傳感器,檢測(cè)面在9mm左右。



2.連線

驅(qū)動(dòng)器右邊分有兩個(gè)區(qū)域

Signal:用于驅(qū)動(dòng)器與開(kāi)發(fā)板連接,進(jìn)行電機(jī)的控制驅(qū)動(dòng)。

ENA接口:當(dāng)此信號(hào)有效時(shí),驅(qū)動(dòng)器將自動(dòng)切斷電機(jī)繞組電流,使電機(jī)處于自由狀態(tài)(無(wú)保持轉(zhuǎn)矩)。當(dāng)此信號(hào)不連接時(shí)默認(rèn)為無(wú)效狀態(tài),這時(shí)電機(jī)繞組通以電流,可正常工作。
DIR接口:控制電機(jī)旋轉(zhuǎn)方向,信號(hào)有效時(shí)電機(jī)順時(shí)針旋轉(zhuǎn),無(wú)效時(shí)逆時(shí)針旋轉(zhuǎn)。
PUL接口:步進(jìn)電機(jī)驅(qū)動(dòng)器把控制器發(fā)出的脈沖信號(hào)轉(zhuǎn)化為步進(jìn)電機(jī)的角位移,驅(qū)動(dòng)器每接受一個(gè)脈沖信號(hào) PUL,就驅(qū)動(dòng)步進(jìn)電機(jī)旋轉(zhuǎn)一個(gè)步距角,PUL 的頻率和步進(jìn)電機(jī)的轉(zhuǎn)速成正比。對(duì)于最佳輸入要求,此信號(hào)占空比最好 1:1,脈沖信號(hào)的頻率不大于100KHz。
連接方式有兩種方法:

(1)共陽(yáng)極連接



將驅(qū)動(dòng)器的ENA+,DIR+,PUL+接地, 陰極接電,也就是開(kāi)發(fā)板的相對(duì)應(yīng)的控制管腳。

(2)共陰極連接



如STM32F407接線如下:

ENA+(驅(qū)動(dòng)器)  PE6(開(kāi)發(fā)板)
DIR+(驅(qū)動(dòng)器)  PE5(開(kāi)發(fā)板)
PUL+(驅(qū)動(dòng)器)  PC7(開(kāi)發(fā)板)
ENA- DIR- PUL-(驅(qū)動(dòng)器) GND(開(kāi)發(fā)板)

3. High Voltage區(qū)域

該區(qū)域用于驅(qū)動(dòng)器與步進(jìn)電機(jī)連接。
和下圖類(lèi)似:




電機(jī)接法:





這里我采用的是驅(qū)動(dòng)器接法是共陰極接法



對(duì)于電源,開(kāi)發(fā)板使用3.3v,電機(jī)使用12v,1A,可根據(jù)實(shí)際情況調(diào)整。


4.細(xì)分

根據(jù)需求,該驅(qū)動(dòng)器最多支持32細(xì)分,根據(jù)指示的S1,S2,S3開(kāi)關(guān)狀態(tài)調(diào)整驅(qū)動(dòng)器側(cè)面的dip撥碼進(jìn)行細(xì)分選擇,同樣可以通過(guò)S4,S5,S6三個(gè)開(kāi)關(guān)控制電流大小,最大支持3.5A,峰值電流為4.0A。

我這里采用了4細(xì)分。具體如下圖:



5.故障問(wèn)題



PWR:綠燈,電源指示燈。
ALARM:紅燈,故障(過(guò)流、過(guò)熱和欠壓)時(shí)亮。紅燈亮起時(shí),表明驅(qū)動(dòng)器出故障了,
請(qǐng)立即切斷驅(qū)動(dòng)器電源,排除故障后再繼續(xù)操作。

6.限位金屬傳感器

雖然說(shuō)是傳感器,但其實(shí)就是一個(gè)開(kāi)關(guān)量,就跟光電開(kāi)關(guān)一樣。有兩種接法:

  • PNP接法

藍(lán)線接地,棕線接電源,黑色線作為輸出接入開(kāi)發(fā)板作為輸入,在PNP接法中,常態(tài)黑色線為低電平,當(dāng)傳感器檢測(cè)到物體時(shí),會(huì)輸出24V正電壓。


NPN接法差別就是檢測(cè)到物體時(shí),黑線輸出的是負(fù)電壓。

我這里將傳感器的黑線輸出連接至KEY0作為對(duì)開(kāi)發(fā)板的輸入,當(dāng)檢測(cè)到物體時(shí),PB0引腳會(huì)變?yōu)榈碗娖健?/font>


二、代碼

驅(qū)動(dòng)器代碼參照正點(diǎn)原子的例程,然后針對(duì)具體的情況做了相應(yīng)的更改
主要用到了四個(gè)函數(shù)

void Driver_Init(void);//驅(qū)動(dòng)器初始化

void TIM8_OPM_RCR_Init(u16 arr, u16 psc);//TIM8_CH2 初始化 單脈沖+重復(fù)計(jì)數(shù)模式

void Locate_Rle(long num, u32 frequency, DIR_Type dir) //相對(duì)定位函數(shù)

void Locate_Abs(long num, u32 frequency);/絕對(duì)定位函數(shù)

1.驅(qū)動(dòng)初始化

由于ENA和DIR使用的引腳為PE6,PE5,因此在初始化中對(duì)它們進(jìn)行相關(guān)的初始化即可(可以根據(jù)自己的開(kāi)發(fā)板來(lái)更改引腳)。

整體流程:
定義GPIO結(jié)構(gòu)體
使能GPIOE時(shí)鐘
對(duì)結(jié)構(gòu)體進(jìn)行相關(guān)初始化,推挽輸出,上拉等
設(shè)置PE5,輸出為高電平沿順時(shí)針?lè)较?br /> 設(shè)置PE6,輸出為低電平,使能輸出


  1. void Driver_Init(void)

  2. {

  3.         GPIO_InitTypeDef  GPIO_InitStructure;



  4.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);



  5.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;

  6.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  7.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  8.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  9.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  10.         GPIO_Init(GPIOE, &GPIO_InitStructure);

  11.         

  12.         GPIO_SetBits(GPIOE,GPIO_Pin_5);

  13.         GPIO_ResetBits(GPIOE,GPIO_Pin_6);

  14. }
復(fù)制代碼



2.定時(shí)器

定時(shí)器的時(shí)基單元主要有三個(gè)寄存器組成:16位計(jì)數(shù)器,自動(dòng)重轉(zhuǎn)載寄存器(包括一個(gè)影子寄存器),預(yù)分頻器(控制計(jì)數(shù)器時(shí)鐘),其中預(yù)分頻計(jì)數(shù)器的時(shí)鐘頻率1——65535。

16位向上、向下、向上/向下自動(dòng)裝載計(jì)數(shù)器
● 16位可編程(可以實(shí)時(shí)修改)預(yù)分頻器,計(jì)數(shù)器時(shí)鐘頻率的分頻系數(shù)為1~65536之間的任意
數(shù)值
● 4個(gè)獨(dú)立通道:
─ 輸入捕獲
─ 輸出比較
─ PWM生成(邊緣或中間對(duì)齊模式)
─ 單脈沖模式輸出
● 使用外部信號(hào)控制定時(shí)器和定時(shí)器互連的同步電路
● 如下事件發(fā)生時(shí)產(chǎn)生中斷/DMA: ─ 更新:計(jì)數(shù)器向上溢出/向下溢出,計(jì)數(shù)器初始化(通過(guò)軟件或者內(nèi)部/外部觸發(fā))
─ 觸發(fā)事件(計(jì)數(shù)器啟動(dòng)、停止、初始化或者由內(nèi)部/外部觸發(fā)計(jì)數(shù))
─ 輸入捕獲
─ 輸出比較
● 支持針對(duì)定位的增量(正交)編碼器和霍爾傳感器電路
● 觸發(fā)輸入作為外部時(shí)鐘或者按周期的電流管理



因?yàn)橛玫絋IME8與GPIOC(進(jìn)行端口復(fù)用),所以使能對(duì)應(yīng)的時(shí)鐘。將GPIOC的Pin7復(fù)用為T(mén)IME8,對(duì)TIME8的結(jié)構(gòu)體進(jìn)行變量初始化,查開(kāi)發(fā)手冊(cè)可以知道,PC7復(fù)用功能為T(mén)IME8的CH2。



整體流程

配置TIME8,GPIOC時(shí)鐘。
初始化TIM8,設(shè)置ARR(自動(dòng)裝填值即周期),PSC(時(shí)鐘預(yù)分頻系數(shù))
設(shè)置TIM8_CH2的PWM模式,使能TIM2_CH2輸出
使能TIM2

  1. <span style="background-color: rgb(255, 255, 255);">/</span>***********************************************

  2. //TIM8_CH2(PC7) 單脈沖輸出+重復(fù)計(jì)數(shù)功能初始化

  3. //TIM8 時(shí)鐘頻率 84*2=168MHz

  4. //arr:自動(dòng)重裝值

  5. //psc:時(shí)鐘預(yù)分頻數(shù)

  6. ************************************************/

  7. void TIM8_OPM_RCR_Init(u16 arr,u16 psc)

  8. {                                                         

  9.         GPIO_InitTypeDef GPIO_InitStructure;

  10.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  11.         TIM_OCInitTypeDef  TIM_OCInitStructure;

  12.         NVIC_InitTypeDef NVIC_InitStructure;



  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);          //TIM8時(shí)鐘使能   

  14.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);         //使能PORTC時(shí)鐘                                                                                    



  15.         GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //GPIOC7復(fù)用為定時(shí)器8

  16.         

  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;           //GPIOC7

  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //復(fù)用功能

  19.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz

  20.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽復(fù)用輸出

  21.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;      //下拉

  22.         GPIO_Init(GPIOC,&GPIO_InitStructure);               //初始化PF9

  23.         

  24.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

  25.         

  26.         TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值         

  27.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值   

  28.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim

  29.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式

  30.         TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位

  31.         TIM_ClearITPendingBit(TIM8,TIM_IT_Update);



  32.         TIM_UpdateRequestConfig(TIM8,TIM_UpdateSource_Regular); /********* 設(shè)置只有計(jì)數(shù)溢出作為更新中斷 ********/

  33.         TIM_SelectOnePulseMode(TIM8,TIM_OPMode_Single);/******* 單脈沖模式 **********/



  34.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式2

  35.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出2使能

  36.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比較輸出2N失能 *******/

  37.         TIM_OCInitStructure.TIM_Pulse = arr>>1; //設(shè)置待裝入捕獲比較寄存器的脈沖值,右移一位

  38.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高

  39.         TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx



  40.         TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2預(yù)裝載使能         

  41.         TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的預(yù)裝載寄存器

  42.         

  43.         TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE);  //TIM8   使能或者失能指定的TIM中斷



  44.         NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;  //TIM8中斷

  45.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占優(yōu)先級(jí)1級(jí)

  46.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //從優(yōu)先級(jí)1級(jí)

  47.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

  48.         NVIC_Init(&NVIC_InitStructure);  //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器

  49.         

  50.         TIM_ClearITPendingBit(TIM8, TIM_IT_Update);  //清除TIMx的中斷待處理位:TIM 中斷源

  51.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                                                                                          

  52. }

  53. 3.中斷服務(wù)函數(shù)



  54. void TIM8_UP_TIM13_IRQHandler(void)

  55. {

  56.         if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//更新中斷

  57.         {

  58.                 TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中斷標(biāo)志位               

  59.                 if(is_rcr_finish==0)//重復(fù)計(jì)數(shù)器未設(shè)置完成

  60.                 {

  61.                         if(rcr_integer!=0) //整數(shù)部分脈沖還未發(fā)送完成

  62.                         {

  63.                                 TIM8->RCR=RCR_VAL;//設(shè)置重復(fù)計(jì)數(shù)值

  64.                                 rcr_integer--;//減少RCR_VAL+1個(gè)脈沖                                

  65.                         }else if(rcr_remainder!=0)//余數(shù)部分脈沖 不為0

  66.                         {

  67.                                 TIM8->RCR=rcr_remainder-1;//設(shè)置余數(shù)部分

  68.                                 rcr_remainder=0;//清零

  69.                                 is_rcr_finish=1;//重復(fù)計(jì)數(shù)器設(shè)置完成                                

  70.                         }else goto out;   //rcr_remainder=0,直接退出                        

  71.                         TIM_GenerateEvent(TIM8,TIM_EventSource_Update);//產(chǎn)生一個(gè)更新事件 重新初始化計(jì)數(shù)器

  72.                         TIM_CtrlPWMOutputs(TIM8,ENABLE);        //MOE 主輸出使能        

  73.                         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                        

  74.                         if(motor_dir==CW) //如果方向?yàn)轫槙r(shí)針   

  75.                                 current_pos+=(TIM8->RCR+1);//加上重復(fù)計(jì)數(shù)值

  76.                         else          //否則方向?yàn)槟鏁r(shí)針

  77.                                 current_pos-=(TIM8->RCR+1);//減去重復(fù)計(jì)數(shù)值                        

  78.                 }else

  79.                 {

  80. out:                is_rcr_finish=1;//重復(fù)計(jì)數(shù)器設(shè)置完成

  81.                         TIM_CtrlPWMOutputs(TIM8,DISABLE);        //MOE 主輸出關(guān)閉

  82.                         TIM_Cmd(TIM8, DISABLE);  //關(guān)閉TIM8                                

  83.                         printf("當(dāng)前位置=%ld\r\n",current_pos);//打印輸出

  84.                 }        

  85.         }

  86. }
復(fù)制代碼


4.相對(duì)定位函數(shù)

首先判斷脈沖如果小于0就停止運(yùn)行。頻率的取值在20-100000Hz之間,如果不在這個(gè)范圍內(nèi)就終止。

通過(guò)傳入的參數(shù)dir可以知道旋轉(zhuǎn)方向,若為順時(shí)針,就用當(dāng)前位置加上一個(gè)脈沖對(duì)應(yīng)的步距,如果是逆時(shí)針就減去。

最后獲取重復(fù)計(jì)數(shù)器的整數(shù)和余數(shù)部分,開(kāi)啟TIM8

  1. /********************************************

  2. //相對(duì)定位函數(shù)

  3. //num 0~2147483647

  4. //frequency: 20Hz~100KHz

  5. //dir: CW(順時(shí)針?lè)较?  CCW(逆時(shí)針?lè)较?

  6. *********************************************/

  7. void Locate_Rle(long num,u32 frequency,DIR_Type dir) //相對(duì)定位函數(shù)

  8. {

  9.         if(num<=0) //數(shù)值小等于0 則直接返回

  10.         {

  11.                 printf("\r\nThe num should be greater than zero!!\r\n");

  12.                 return;

  13.         }

  14.         if(TIM8->CR1&0x01)//上一次脈沖還未發(fā)送完成  直接返回

  15.         {

  16.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");

  17.                 return;

  18.         }

  19.         if((frequency<20)||(frequency>100000))//脈沖頻率不在范圍內(nèi) 直接返回

  20.         {

  21.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");

  22.                 return;

  23.         }

  24.         motor_dir=dir;//得到方向        

  25.         DRIVER_DIR=motor_dir;//設(shè)置方向

  26.         

  27.         if(motor_dir==CW)//順時(shí)針

  28.                 target_pos=current_pos+num;//目標(biāo)位置

  29.         else if(motor_dir==CCW)//逆時(shí)針

  30.                 target_pos=current_pos-num;//目標(biāo)位置

  31.         

  32.         rcr_integer=num/(RCR_VAL+1);//重復(fù)計(jì)數(shù)整數(shù)部分

  33.         rcr_remainder=num%(RCR_VAL+1);//重復(fù)計(jì)數(shù)余數(shù)部分

  34.         is_rcr_finish=0;//重復(fù)計(jì)數(shù)器設(shè)置完成

  35.         TIM8_Startup(frequency);//開(kāi)啟TIM8

  36. }

  37. 5.絕對(duì)定位函數(shù)



  38. 絕對(duì)定位函數(shù)很簡(jiǎn)單,也就是說(shuō)給定一個(gè)位置,固定的讓電機(jī)轉(zhuǎn)到這個(gè)位置即可。



  39. 當(dāng)給定目標(biāo)位置與當(dāng)前位置不同時(shí),先判斷旋轉(zhuǎn)方向然后復(fù)制給DIR,因?yàn)椴淮_定給的位置是正值還是負(fù)值,所以最后求重復(fù)計(jì)數(shù)器的時(shí)候加了一個(gè)abs絕對(duì)值。



  40. /********************************************

  41. //絕對(duì)定位函數(shù)

  42. //num   -2147483648~2147483647

  43. //frequency: 20Hz~100KHz

  44. *********************************************/

  45. void Locate_Abs(long num,u32 frequency)//絕對(duì)定位函數(shù)

  46. {

  47.         if(TIM8->CR1&0x01)//上一次脈沖還未發(fā)送完成 直接返回

  48.         {

  49.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");

  50.                 return;

  51.         }

  52.         if((frequency<20)||(frequency>100000))//脈沖頻率不在范圍內(nèi) 直接返回

  53.         {

  54.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");

  55.                 return;

  56.         }

  57.         target_pos=num;//設(shè)置目標(biāo)位置

  58.         if(target_pos!=current_pos)//目標(biāo)和當(dāng)前位置不同

  59.         {

  60.                 if(target_pos>current_pos)

  61.                         motor_dir=CW;//順時(shí)針

  62.                 else

  63.                         motor_dir=CCW;//逆時(shí)針

  64.                 DRIVER_DIR=motor_dir;//設(shè)置方向

  65.                

  66.                 rcr_integer=abs(target_pos-current_pos)/(RCR_VAL+1);//重復(fù)計(jì)數(shù)整數(shù)部分

  67.                 rcr_remainder=abs(target_pos-current_pos)%(RCR_VAL+1);//重復(fù)計(jì)數(shù)余數(shù)部分

  68.                 is_rcr_finish=0;//重復(fù)計(jì)數(shù)器未設(shè)置完成

  69.                 TIM8_Startup(frequency);//開(kāi)啟TIM8

  70.         }

  71. }
復(fù)制代碼

6.限位傳感器中斷初始化
  1. void EXTIX_Init(void)
  2. {
  3.        
  4.         //PB0使用Exit0號(hào)中斷線,PG1使用Exit1,PC2使用Exit2,PA3使用Exit3
  5.         NVIC_InitTypeDef   NVIC_InitStructure;
  6.         EXTI_InitTypeDef   EXTI_InitStructure;
  7.         GPIO_InitTypeDef   GPIO_InitStructure;
  8.        

  9.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOG|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOB,GPIOG,GPIOC,GPIOA時(shí)鐘

  10.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時(shí)鐘(中斷需要使用AFIO時(shí)鐘)
  11.        
  12.        
  13.        
  14.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PB0對(duì)應(yīng)IO配置
  15.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
  16.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  17.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  18.   GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB0
  19.        
  20.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PG1對(duì)應(yīng)IO配置
  21.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
  22.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  23.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  24.   GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOG1
  25.        
  26.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PC2對(duì)應(yīng)IO配置
  27.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
  28.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  29.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  30.   GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC2
  31.        
  32.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PA3對(duì)應(yīng)IO配置
  33.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
  34.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  35.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  36.   GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA3
  37.        



  38.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);//PB0 連接到中斷線0
  39.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG, EXTI_PinSource1);//PG1 連接到中斷線1
  40.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource2);//PC2 連接到中斷線2
  41.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource3);//PA3 連接到中斷線3
  42.        
  43.         //配置0號(hào)中斷線
  44.   EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1 | EXTI_Line2 | EXTI_Line3;//LINE0
  45.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
  46.         //初始狀態(tài)為低電平,當(dāng)檢測(cè)到物體時(shí),KEY0輸出高電平,此時(shí)INT0導(dǎo)通,變?yōu)榈碗娖,即從上升沿跳變至下降沿時(shí)觸發(fā)
  47.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  48.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
  49.   EXTI_Init(&EXTI_InitStructure);//配置
  50.        

  51.         NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//PB0對(duì)應(yīng)的外部中斷0
  52.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不區(qū)分優(yōu)先級(jí),只需要電平轉(zhuǎn)換時(shí)進(jìn)入中斷即可
  53.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
  54.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
  55.   NVIC_Init(&NVIC_InitStructure);//配置
  56.        
  57.         NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//外部中斷2
  58.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//搶占優(yōu)先級(jí)3
  59.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子優(yōu)先級(jí)2
  60.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
  61.   NVIC_Init(&NVIC_InitStructure);//配置
  62.        
  63.        
  64.         NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中斷3
  65.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//搶占優(yōu)先級(jí)2
  66.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子優(yōu)先級(jí)2
  67.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
  68.   NVIC_Init(&NVIC_InitStructure);//配置
  69.        
  70.        
  71.         NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中斷4
  72.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//搶占優(yōu)先級(jí)1
  73.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子優(yōu)先級(jí)2
  74.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
  75.   NVIC_Init(&NVIC_InitStructure);//配置
  76.           
  77. }
復(fù)制代碼

7.電平檢測(cè)與中斷服務(wù)函數(shù)

  1. u8 Check_Sensor_State(void)
  2. {
  3.          
  4.     //高電平?jīng)]有檢測(cè)到
  5.     if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == SET)
  6.     {
  7.       return NO_Tagger;

  8.     }
  9.     //低電平檢測(cè)到
  10.     else
  11.     {
  12.       return Tagger;   
  13.     }  
  14. }
復(fù)制代碼
四個(gè)服務(wù)函數(shù)根據(jù)自己的需求寫(xiě),可以正轉(zhuǎn)反轉(zhuǎn),加減速,停止啥的
  1. void EXTI0_IRQHandler(void)
  2. {
  3.   if(EXTI_GetITStatus(EXTI_Line0) == SET)
  4.   {
  5.     //可以停止,可以反轉(zhuǎn)
  6.     EXTI_ClearITPendingBit(EXTI_Line0);
  7.   }
  8. }
復(fù)制代碼





6.main函數(shù)

主函數(shù)也很簡(jiǎn)單,先進(jìn)行相關(guān)初始化,通過(guò)按鍵操控電機(jī),按下wkup就通過(guò)絕對(duì)定位函數(shù)回到零點(diǎn),按下key0就以500hz的頻率順時(shí)針發(fā)送200脈沖,假如不設(shè)置細(xì)分,該操作就是順時(shí)針旋轉(zhuǎn)一圈,key1也是一樣,逆時(shí)針發(fā)送500脈沖。這里設(shè)置了一個(gè)計(jì)數(shù)器i,工作了50次后led會(huì)有一個(gè)提示。



7.結(jié)果

最終運(yùn)行程序,電機(jī)就會(huì)轉(zhuǎn)動(dòng)起來(lái),同時(shí)驅(qū)動(dòng)器下面的led燈會(huì)閃爍藍(lán)色的燈光,通過(guò)脈沖加頻率可以調(diào)整速度,也可以通過(guò)細(xì)分設(shè)定去調(diào)節(jié)。當(dāng)用金屬擋在傳感器前時(shí),黑色線輸出正電壓,PB0變?yōu)榈碗娖剑瑱z測(cè)函數(shù)檢測(cè)到電平發(fā)生變化,進(jìn)入中斷,停止電機(jī)或者反轉(zhuǎn)都行,拿開(kāi)物體后,電機(jī)恢復(fù)原來(lái)的運(yùn)動(dòng)狀態(tài)。






中斷服務(wù)函數(shù)里面可以根據(jù)具體需求來(lái)寫(xiě),可以正轉(zhuǎn)反轉(zhuǎn)停止各種,我這里主函數(shù)開(kāi)始一直讓電機(jī)順時(shí)針旋轉(zhuǎn),當(dāng)檢測(cè)到物體后進(jìn)入中斷,調(diào)取中斷服務(wù)函數(shù),打印一下exti(代碼寫(xiě)成exit了)提示信息 ,然后設(shè)置電機(jī)進(jìn)行逆時(shí)針旋轉(zhuǎn),當(dāng)傳感器沒(méi)有被遮擋后,又恢復(fù)順時(shí)針旋轉(zhuǎn)。


完整項(xiàng)目(步進(jìn)電機(jī)驅(qū)動(dòng)+限位傳感器)


需要用到驅(qū)動(dòng)可以下載我打包的驅(qū)動(dòng)包,將其放置在HARDWARE目錄下,使用時(shí)調(diào)用driver.h文件即可,在使用時(shí),根據(jù)具體電路圖或者開(kāi)發(fā)手冊(cè),調(diào)整驅(qū)動(dòng)器對(duì)應(yīng)的引腳號(hào),電平,定時(shí)器,通道等初始化設(shè)置即可。

博客:https://blog.csdn.net/qq_41573860/article/details/107254090


步進(jìn)電機(jī).7z

777.78 KB, 下載次數(shù): 51, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表