久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
stm32控制兩相電機源程序
[打印本頁]
作者:
ahld
時間:
2019-5-8 10:54
標題:
stm32控制兩相電機源程序
這是我設計的stm32F103控制兩相電機程序
測試好用
附件有keil工程文件
單片機源程序如下:
#include "Bsp.h"
#include "stm32f10x.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
#define DEBUG 1
char TestWord[USARTBUFLEN];
char Cmd_buf[USARTBUFLEN];
uint8_t Cmd_LockFlag = 0;
uint8_t ResetCmd_Flag = 0;
uint8_t Cmd_FinishFlag= 0;
#define ACKSTR "OK_\r\n"
#define NACKSTR "BADCMD_\r\n"
#define BUSYSTR "WAIT_\r\n"
char startchar[USARTBUFLEN];
const char CMD_LIST[8][PARASTRLEN]={"RESET","MOVE","STOP","POWER","SET","READ","ZERO"}; //允許的命令
const char HelpMsg[8][USARTBUFLEN]={{"Command List: MOVE STOP SET READ POWER ZERO;\r\n"},
{"MOVE: e.g. :FF MOVE VERTICAL/HORIZONT CW/ANCW xxx.xx(0-360,sOLUTION: 0.01);\r\n"},
{"STOP: e.g. :FF STOP VERTICAL/HORIZONT;\r\n"},
{"POWER: e.g. :FF POWER VERTICAL/HORIZONT ON/OFF;\r\n"},
{"SET: e.g. :FF SET VERTICAL/HORIZONT ;\r\n"},
{"READ: e.g. :FF READ VERTICAL/HORIZONT;\r\n"},
{"ZERO: e.g. :FF ZERO VERTICAL/HORIZONT;\r\n"},
{"RESET: e.g. :FF RESET;\r\n"}};
char CmdRespondStr[50];
char para_list[CMDPARANUM][PARASTRLEN]; //保存命令中的參數
SYSTEM_STA Sys_Sta;
void CMD_Analyse(const char *cmd,uint8_t cmdlen);
uint8_t str2float(const char *str,float *result);
u8 Flag=0; //指示輸出角度是否到達360度或-360,如果到了,講360置為0度
/****************************************************************************
* 名 稱: main
* 功 能: 串口占用GPIO初始化
* 入口參數:
* 出口參數:
* 說 明:
* 調用方法:
* 修改日志:
****************************************************************************/
int main(void)
{
uint16_t temp[4],temp1=0,HVTemp1;
uint16_t data_tmp;
int32_t step_num = 0;
uint32_t devison_tmp,step_speed;
uint32_t sendbytes=0;
const char *usart_sendaddr;
float angle_tmp,speed_tmp,limit_tmp;
uint8_t error;
uint8_t tmp = 0;
uint8_t fault_try = 0;
STEPMOTOR_INDEX ver_hor;
MOTIONDIR cw_ncw;
uint8_t cycle_cnt,char_num;;
Cmd_LockFlag = 0;
Bsp_Init();
// AT24CXX_Write(0,HelpMsg[0],strlen(HelpMsg[0]));
usart_sendaddr = CmdRespondStr;
cycle_cnt = 0;
temp[0] = 0;
ResetCmd_Flag = 0;
#ifdef DEBUG
//打印識別信息
char_num = sprintf(startchar,"\r\n 134mm-Diameter Step-Motor Driver.\r\nCorp.AGGC,By LK,140\r\n");
UsartDMASend(startchar,char_num);
#endif
//上電首先檢查振鏡位置是否超出允許
/*
Delay_ms(5000);
if((RESET == GPIO_ReadInputDataBit(ANCW_LIMIT))|(RESET == GPIO_ReadInputDataBit(CW_LIMIT)))
{
Hor_Info.motion_sta = OutOfRange;
if(RESET == GPIO_ReadInputDataBit(ANCW_LIMIT))
{
Hor_Info.motion_dir = Motion_CW;
Hor_Info.dir_now = Hor_Info.dir_range_ancw;
}
else
{
Hor_Info.motion_dir = Motion_ANCW;
Hor_Info.dir_now = Hor_Info.dir_range_cw;
}
}
*/
while(1)
{
//程序運行指示燈
cycle_cnt++;
if(cycle_cnt > 1)
{
LEDToggle();
cycle_cnt =0;
}
//垂直電機位置超出允許范圍,嘗試反向轉動3次,失敗后,定義為振鏡異常
/*
if(OutOfRange == Hor_Info.motion_sta)
{
Delay_ms(1000);
if((RESET == GPIO_ReadInputDataBit(ANCW_LIMIT))|(RESET == GPIO_ReadInputDataBit(CW_LIMIT)))
{
//
if(fault_try<3)
{
if(Stop== Hor_Info.motor_sta)
{
MOTOR_DISEN_HOR;
Hor_Info.motor_sta = Move;
Hor_Info.motor_fb = FB_Enable;
Move_Angles(Horizontal,Hor_Info.motion_dir,5); //嘗試反向轉5度,離開限位開關位置
MOTOR_START_HOR;
fault_try++;
}
}
else
{
Hor_Info.motion_sta = Fault;
MOTOR_EN_HOR;
}
}
}
else
fault_try = 0;
*/
//收到一條命令
if(1 == Cmd_FinishFlag)
{
Cmd_LockFlag =0; //串口命令解鎖
Cmd_FinishFlag =0;
CMD_Analyse(Cmd_buf+1,30);
memset(Cmd_buf,0,USARTBUFLEN); //USARTBUFLEN=100 串口命令最大長度
//void *memset(void *s,int c,size_t n) 將已開辟內存空間S的首個n字節的值設置為C
sendbytes = sprintf(CmdRespondStr,NACKSTR); //sprintf字符串格式化命令,主要將格式化的數據寫入字符串中
if(0 == strncmp(para_list[0],"MOVE",sizeof("MOVE"))) //電機運動命令,sizeof返回字節大小
{ //strncmp ( const char * str1, const char * str2, size_t n );str1,str2為需要比較的字符串,n為比較數量
//str1第一個字符減去str2第一個字符,若差值為0,則繼續比較下一個字符
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
ver_hor = Vertical; //垂直
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
ver_hor = Horizontal; //水平
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
if(0 == str2float(para_list[2],&angle_tmp))
{
float end_angle=0;
end_angle= Motor_Info[ver_hor].angle_now+angle_tmp;
//當前位置不能超過設定范圍
if((end_angle >= -1*Motor_Info[ver_hor].limit_angle)&&(end_angle <= Motor_Info[ver_hor].limit_angle))
{
if(angle_tmp >0)
{
cw_ncw = Motion_CW; //步進電機方向
}
else if(angle_tmp <0)
{
cw_ncw = Motion_ANCW;
angle_tmp *= -1;
}
else
cw_ncw = Hold;
}
else if(end_angle < -1*Motor_Info[ver_hor].limit_angle) //超過逆時針轉動范圍
{
cw_ncw = Motion_ANCW;
angle_tmp = Motor_Info[ver_hor].angle_now + Motor_Info[ver_hor].limit_angle;
}
else if(end_angle > Motor_Info[ver_hor].limit_angle) //超過順時針轉動范圍
{
cw_ncw = Motion_CW;
angle_tmp = Motor_Info[ver_hor].limit_angle - Motor_Info[ver_hor].angle_now;
}
else
cw_ncw = Hold;
//電機停止狀態下,才能允許轉動
if((Hold != cw_ncw)&&(Stop == Motor_Info[ver_hor].motor_sta))
{
// Motor_Info[ver_hor].move_pulsenum =(uint32_t)(angle_tmp*CODER_NUM);
Move_Angles(ver_hor,cw_ncw,angle_tmp);
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
else
sendbytes = sprintf(CmdRespondStr,BUSYSTR);
// }
// else
// sendbytes = sprintf(CmdRespondStr,"AngleWrong_\r\n");
}
else sendbytes = sprintf(CmdRespondStr,NACKSTR);
}
}
else if(0 == strncmp(para_list[0],"CHECK",sizeof("CHECK"))) //查詢當前電機狀態(是否在轉)
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
{
ver_hor = Vertical;
}
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
{
ver_hor = Horizontal;
}
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
if(Move == Motor_Info[ver_hor].motor_sta)
sendbytes = sprintf(CmdRespondStr,"MOVE_\r\n");
else
sendbytes = sprintf(CmdRespondStr,"HOLD_\r\n");
}
}
else if(0 == strncmp(para_list[0],"STATUS",sizeof("STATUS"))) //查詢當前電機狀態(是否在轉)
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
{
ver_hor = Vertical;
}
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
{
ver_hor = Horizontal;
}
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
if(Stepslost == Motor_Info[ver_hor].motion_sta)
sendbytes = sprintf(CmdRespondStr,"STEPSLOST_\r\n");
else if(OutOfRange == Motor_Info[ver_hor].motion_sta)
sendbytes = sprintf(CmdRespondStr,"OVERRANGE_\r\n");
else if(Zero == Motor_Info[ver_hor].motion_sta)
sendbytes = sprintf(CmdRespondStr,"ZERO_\r\n");
else if(Fault == Motor_Info[ver_hor].motion_sta)
sendbytes = sprintf(CmdRespondStr,"FAULT_\r\n");
else
sendbytes = sprintf(CmdRespondStr,"NORMAL_\r\n");
}
}
else if(0 == strncmp(para_list[0],"STOP",sizeof("STOP"))) //運動停止命令
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
ver_hor = Vertical;
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
ver_hor = Horizontal;
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
if(Vertical == ver_hor)
{
Ver_Info.motor_sta = Stop;
Ver_Info.motor_fb = FB_Disable;
MOTOR_STOP_VER;
}
else
{
Hor_Info.motor_sta = Stop;
Hor_Info.motor_fb = FB_Disable;
MOTOR_STOP_HOR;
}
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
else if(0 == strncmp(para_list[0],"SET",sizeof("SET"))) //參數設置命令
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
ver_hor = Vertical;
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
ver_hor = Horizontal;
else
ver_hor = Unknow;
//電機停止時,允許進行參數設定
if(Stop == Motor_Info[ver_hor].motor_sta)
{
if(Unknow != ver_hor)
{
if(0 == strncmp(para_list[2],"DEVISION",sizeof("DEVISION"))) //設置細分比例
{
devison_tmp = atoi(para_list[3]);
if((devide_1 == devison_tmp)|(devide_2 == devison_tmp)|(devide_8 == devison_tmp)|(devide_16 == devison_tmp))
{
if(Vertical == ver_hor)
{
Ver_Info.subdevision = (DEVISIONVALUE)devison_tmp;
Ver_Info.step_resolution= MOTOR_RESOLUTION/(RATIO_GEAR*devison_tmp);
Ver_Info.step_speed = 360.0f*Ver_Info.speed/(60.0f*Ver_Info.step_resolution);
SPEEDSET_VER(1000000/Ver_Info.step_speed);
Ver_Info.dir_range_cw = (int32_t)RATIO_GEAR*Ver_Info.subdevision*180/MOTOR_RESOLUTION; //順時針電機方位角范圍
Ver_Info.dir_range_ancw = -1*(int32_t)RATIO_GEAR*Ver_Info.subdevision*180/MOTOR_RESOLUTION; //逆時針電機方位角范圍
//更新EEPROM中保存的參數
UPDATE_DEVISIONH_VER;
UPDATE_STEPRE_VER;
UPDATE_SPEED_VER;
UPDATE_DIRRANGE_VER;
}
else if(Horizontal == ver_hor)
{
Hor_Info.subdevision =(DEVISIONVALUE)devison_tmp;
Hor_Info.step_resolution= MOTOR_RESOLUTION/(RATIO_GEAR*devison_tmp);
Hor_Info.step_speed = 360.0f*Hor_Info.speed/(60.0f*Hor_Info.step_resolution);
SPEEDSET_HOR(1000000/Hor_Info.step_speed);
Hor_Info.dir_range_cw = (int32_t)RATIO_GEAR*Hor_Info.subdevision*360/MOTOR_RESOLUTION; //順時針電機方位角范圍
Hor_Info.dir_range_ancw = -1*(int32_t)RATIO_GEAR*Hor_Info.subdevision*360/MOTOR_RESOLUTION; //逆時針電機方位角范圍
AT24CXX_Write(HORINFO_ADDR,(const uint8_t *)&Hor_Info,sizeof(MOTORINFO));
//更新EEPROM中保存的參數
UPDATE_DEVISIONH_HOR;
UPDATE_STEPRE_HOR;
UPDATE_SPEED_HOR;
UPDATE_DIRRANGE_HOR;
}
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
else if(0 == strncmp(para_list[2],"LOCATION",sizeof("LOCATION"))) //設置當前位置對應角度,手動歸零時使用該命令
{
if(0 == str2float(para_list[3],&angle_tmp))
{
if((angle_tmp >= -185)&&(angle_tmp <= 185))
{
if(Vertical == ver_hor)
{
Ver_Info.angle_now = angle_tmp;
Ver_Info.dir_now = angle_tmp/360.0f*Ver_Info.dir_range_cw*2;
//更新EEPROM中保存的參數
UPDATE_ANGEL_VER;
UPDATE_DIRNOW_VER;
}
else if(Horizontal == ver_hor)
{
Hor_Info.angle_now = angle_tmp;
Hor_Info.dir_now = angle_tmp/360.0f*Hor_Info.dir_range_cw*2;
//更新EEPROM中保存的參數
UPDATE_ANGEL_HOR;
UPDATE_DIRNOW_HOR;
}
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
}
else if(0 == strncmp(para_list[2],"SPEED",sizeof("SPEED"))) //設置轉動速度
{
speed_tmp = atof(para_list[3]);
if((speed_tmp > 0)&&(speed_tmp <= 2000)) //分鐘轉速小于2000r/min
{
if(Vertical == ver_hor)
{
Ver_Info.speed = speed_tmp;
Ver_Info.step_speed = 360.0f*Ver_Info.speed/(60.0f*Ver_Info.step_resolution);
SPEEDSET_VER(1000000/Ver_Info.step_speed);
//更新EEPROM中保存的參數
UPDATE_SPEED_VER;
UPDATE_SPEEDSTEPS_VER;
// AT24CXX_Write(VERINFO_ADDR,(const uint8_t *)&Ver_Info,sizeof(MOTORINFO));
}
else if(Horizontal == ver_hor)
{
Hor_Info.speed = speed_tmp;
Hor_Info.step_speed = 360.0f*Hor_Info.speed/(60.0f*Hor_Info.step_resolution);
SPEEDSET_HOR(1000000/Hor_Info.step_speed);
// AT24CXX_Write(HORINFO_ADDR,(const uint8_t *)&Hor_Info,sizeof(MOTORINFO));
//更新EEPROM中保存的參數
UPDATE_SPEED_HOR;
UPDATE_SPEEDSTEPS_HOR;
}
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
else if(0 == strncmp(para_list[2],"LIMIT",sizeof("LIMIT"))) //設置轉動范圍
{
if(0 == str2float(para_list[3],&limit_tmp))
{
if((limit_tmp > 0)&&(limit_tmp <= 361))
{
Motor_Info[ver_hor].limit_angle = limit_tmp;
if(Vertical == ver_hor)
UPDATE_LIMITANGEL_VER;
else
UPDATE_LIMITANGEL_HOR;
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
}
}
}
else
sendbytes = sprintf(CmdRespondStr,BUSYSTR);
}
else if(0 == strncmp(para_list[0],"READ",sizeof("READ"))) //讀取細分參數命令
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
ver_hor = Vertical;
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
ver_hor = Horizontal;
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
if(0 == strncmp(para_list[2],"DEVISION",sizeof("DEVISION"))) //讀取細分比例
{
if(Vertical == ver_hor)
sendbytes = sprintf(CmdRespondStr,"Vertical_Devision_%d_\r\n",Ver_Info.subdevision);
else if(Horizontal == ver_hor)
sendbytes = sprintf(CmdRespondStr,"Horizontal_Devision_%d_\r\n",Hor_Info.subdevision);
}
else if(0 == strncmp(para_list[2],"LOCATION",sizeof("LOCATION"))) //讀取當前位置對應角度
{
if(Vertical == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.2f_\r\n",Ver_Info.angle_now);
else if(Horizontal == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.2f_\r\n",Hor_Info.angle_now);
}
else if(0 == strncmp(para_list[2],"SPEED",sizeof("SPEED"))) //讀取當前位置對應步進速度
{
if(Vertical == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.2d_\r\n",Ver_Info.step_speed);
else if(Horizontal == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.2d_\r\n",Hor_Info.step_speed);
}
else if(0 == strncmp(para_list[2],"LIMIT",sizeof("LIMIT"))) //設置轉動范圍
{
if(Vertical == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.1f_\r\n",Ver_Info.limit_angle);
else if(Horizontal == ver_hor)
sendbytes = sprintf(CmdRespondStr,"%.1f_\r\n",Hor_Info.limit_angle);
}
}
}
else if(0 == strncmp(para_list[0],"ZERO",sizeof("ZERO"))) //角度歸零,待完善
{
if(0 == strncmp(para_list[1],"VERTICAL",sizeof("VERTICAL")))
ver_hor = Vertical;
else if(0 == strncmp(para_list[1],"HORIZONT",sizeof("HORIZONT")))
ver_hor = Horizontal;
else
ver_hor = Unknow;
if(Unknow != ver_hor)
{
ZeroMotor(ver_hor);
sendbytes = sprintf(CmdRespondStr,ACKSTR);
}
}
else if(0 == strncmp(para_list[0],"HELP",sizeof("HELP"))) //命令使用信息查詢
{
usart_sendaddr =HelpMsg[0];
sendbytes =strlen(HelpMsg[0]);
}
else if(0 == strncmp(para_list[0],"RESET",sizeof("RESET"))) //系統復位命令
{
//復位前,停止電機轉動
MOTOR_STOP_HOR;
MOTOR_STOP_VER;
Sys_Soft_Reset();
}
else
sendbytes = sprintf(CmdRespondStr,NACKSTR);
for(tmp=0;tmp<CMDPARANUM;tmp++)
memset(para_list[tmp],0,PARASTRLEN);
}
//DMA空閑時,將數據發送出去
if((0 == DMA_GetCurrDataCounter(PC_DMA_CHANNEL))&&(sendbytes > 0))
{
UsartDMASend(usart_sendaddr,sendbytes);
usart_sendaddr = CmdRespondStr;
sendbytes =0;
}
//將方位更新到角度,并判斷是否超過設定范圍
Ver_Info.angle_now = (float)Ver_Info.dir_now*Hor_Info.step_resolution;
Hor_Info.angle_now = (float)Hor_Info.dir_now*Hor_Info.step_resolution; //當前的角度為實際脈沖數計算得到,angle_now=360*dir_now/(2*200*140) (細分比率*200*次輪比)
UPDATE_ANGEL_HOR;
UPDATE_DIRNOW_HOR;
UPDATE_ANGEL_VER;
UPDATE_DIRNOW_VER;
WG_Feed();
}
}
/****************************************************************************
* 名 稱: str2float()
* 功 能:收到的角度是否合法
* 入口參數:
* 出口參數:
* 說 明:
* 調用方法:
* 修改日志:
****************************************************************************/
uint8_t str2float(const char *str,float *result)
{
uint8_t charcnt;
volatile uint8_t isok=1;
uint8_t paracnt =0;
uint8_t paracharcnt =0;
uint8_t point_flag =0;
uint8_t num_flag =0;
uint8_t sym_flag =0;
uint8_t sym_loc =0;
for(charcnt=0;charcnt<PARASTRLEN;charcnt++)
{
if(('-' == *(str+charcnt))|('-' == *(str+charcnt)))
{
sym_flag = charcnt+1;
if(sym_flag>1)
break; //符號位超過一個
}
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
StepMotor_LV4(134口徑振鏡源代碼).7z
(180.66 KB, 下載次數: 32)
2019-5-8 20:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
ahld
時間:
2019-5-8 13:35
不錯不錯喲
作者:
admin
時間:
2019-5-8 20:51
本帖需要重新編輯補全電路原理圖,源碼,詳細說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
作者:
Chenw_Fly
時間:
2020-12-31 10:06
目前在了解這個,感謝樓主的分享
作者:
mouse_ox
時間:
2021-1-1 20:17
不錯不錯,感謝樓主的分享!
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
99精品网
|
黄色a一级片
|
成人免费公开视频
|
国产一级免费观看
|
亚洲精品在线免费
|
欧美综合视频
|
久久久久久久久国产精品
|
亚洲成人精品一区
|
中文字幕永久
|
国产精品久久久999 成人在线国产
|
日韩精品在线看
|
麻豆影音
|
美国黄色一级大片
|
一区二区三区四区在线播放
|
成人在线观看视频网站
|
黄av在线
|
国产一区二区在线免费
|
日本三级在线视频
|
日本丰满少妇裸体自慰
|
黄色一级大片在线免费看产
|
久热中文字幕
|
999国产视频
|
亚洲福利视频一区
|
九九热只有精品
|
国产精品久久久久久亚洲影视
|
黄色高清视频
|
91午夜精品亚洲一区二区三区
|
免费成人小视频
|
完全免费av
|
中文字幕第一页在线
|
国产中文字幕在线观看
|
超碰免费在线观看
|
国产三级在线播放
|
日韩三级久久
|
a级片在线播放
|
免费黄色在线
|
久久久久久久久国产
|
91精品久久久久久久久
|
综合色婷婷
|
久久私人影院
|
少妇高潮露脸国语对白
|