STM32 使用串口 控制DM542步进电机

前言

提示:下部分为STM32 程序的控制部分,下面案例可供参考。

一、引脚初始化GPIO :

代码如下(示例):

void TIM1_PWM_Init(u16 arr,u16 psc)
{
   GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
  
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ
  GPIO_Init(GPIOA, &GPIO_InitStruct); 
  }

该处初始化使用的引脚功能,GPIOA11脚为脉冲信号接口。
该处初始化使用的引脚功能,GPIOA12引脚接口正反方向(高电平为逆转,低点平为正转)

二、产生脉冲的或高低电平的TIM定时器配置 :

该处是定时器相关的配置,代码如下(示例):

    TIM_TimeBaseInitStruct.TIM_ClockDivision =TIM_CKD_DIV2;
	TIM_TimeBaseInitStruct.TIM_CounterMode =TIM_CounterMode_Down;
	TIM_TimeBaseInitStruct.TIM_Period =arr;
	TIM_TimeBaseInitStruct.TIM_Prescaler =psc;
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
	
	TIM_OCInitStruct.TIM_OCMode =TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity =TIM_OCNPolarity_Low;
	TIM_OCInitStruct.TIM_OutputState =TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse =50;
	TIM_OC2Init(TIM1,&TIM_OCInitStruct);
	TIM_OC4Init(TIM1,&TIM_OCInitStruct);

	TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
	TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Disable);	
	
	TIM_ARRPreloadConfig(TIM1,ENABLE);
	
	TIM_CtrlPWMOutputs(TIM1,ENABLE);
	
	TIM_Cmd(TIM1,ENABLE);

三、主函数的调用或对应初始化的调用:

初始化相关代码如下(示例):

void mian()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    uart_init (9600);
    delay_init();
    Encoder_TIM2_Init();
	//GPIO_SetBits(GPIOA, GPIO_Pin_12);
      TIM1_PWM_Init(180,100);//pwm???
}

四、USART 初始化:

代码如下(示例):

#include "sys.h"
#include "usart.h"	  
#include "key.h"

u32 tab[200];
u8 Uart2_Rx;
extern u8 y;
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
	USART1->DR = (u8) ch;      
	return ch;
}
#endif 

 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
u32 tab[200];
 void uart_init(u32 bound){
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

	USART_Init(USART1, &USART_InitStructure); //初始化串口1
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_Cmd(USART1, ENABLE);                    //使能串口1
}
u32 rece_buffer[30];
int RxCounter=0;
u8 kk=0;
void USART1_IRQHandler(void)	
{
	 u8 shujv;
	if(USART_GetFlagStatus(USART1,USART_IT_RXNE) != RESET)  //接收到数据
	{			
		shujv=USART_ReceiveData(USART1);
		if(shujv == 0x12)
			{
			delay_ms(10);//去抖动 
      GPIO_ResetBits(GPIOA, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭	使能
      TIM1_PWM_Init(180,100);//pwm???
		  }
			if(shujv == 0x13)
			{
	   	delay_ms(10);//去抖动 
      TIM1_PWM_Init(0,0);//pwm输出
		  }
			if(shujv == 0x14)
			{
			delay_ms(10);//去抖动 
      GPIO_SetBits(GPIOA, GPIO_Pin_12);
      TIM1_PWM_Init(120,50);//pwm???
		  }
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);        //清除接收标志位,每次接收完成都需要清除一下
		while(USART_GetFlagStatus(USART1,USART_FLAG_TC) ==RESET);	  //用于检查串口UART1是否发送完成,完成时,TC中断标志置位,退出轮询等待!	
	}
}
#endif	

总结

提示:这里对文章进行总结:
STM32F103系列单片机的功能强大,配置相关引脚的GPIO时,需要注意引脚的寄存配置,定时器配置;初次实验学习,如有问题,请大佬多多指教,评价区留言;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现串口控制电机转动圈数,需要使用STM32F103单片机的串口通信功能和TB6600步电机驱动模块。具体实现步骤如下: 1. 确定串口通信协议:首先需要确定串口通信的波特率、数据位、校验位和停止位等参数,一般可以选择9600bps、8位数据位、无校验位和1位停止位。 2. 接线连接:将STM32F103单片机的串口TX引脚连接到TB6600的DIR和PUL引脚上,其中DIR引脚用于控制电机的方向,PUL引脚用于控制电机的脉冲信号。 3. 编程实现:编写STM32F103单片机的程序代码,实现串口接收数据并解析出控制电机转动圈数的指令,然后根据指令控制TB6600驱动模块输出脉冲信号,从而控制电机转动。 以下是一个简单的示例程序,可以实现通过串口控制电机转动圈数的功能: ```c #include "stm32f10x.h" #include <stdio.h> #define PUL GPIO_Pin_0 #define DIR GPIO_Pin_1 void delay_ms(u32 n) { u32 i; for(i=0;i<n*1000;i++); } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE); GPIO_InitStructure.GPIO_Pin = PUL | DIR; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure); USART_Cmd(USART1,ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while(1) { //等待串口接收完数据 while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET); //获取接收到的数据 uint8_t data = USART_ReceiveData(USART1); //解析出控制电机转动圈数的指令 if(data == '1') { //控制电机正转1圈 GPIO_SetBits(GPIOA,DIR); for(int i=0;i<200;i++) { GPIO_SetBits(GPIOA,PUL); delay_ms(5); GPIO_ResetBits(GPIOA,PUL); delay_ms(5); } } else if(data == '2') { //控制电机反转1圈 GPIO_ResetBits(GPIOA,DIR); for(int i=0;i<200;i++) { GPIO_SetBits(GPIOA,PUL); delay_ms(5); GPIO_ResetBits(GPIOA,PUL); delay_ms(5); } } } } ``` 在这个示例程序中,我们通过USART1串口接收数据,并解析出控制电机转动圈数的指令。当接收到数字字符'1'时,控制电机正转1圈;当接收到数字字符'2'时,控制电机反转1圈。 需要注意的是,这个示例程序中只能控制电机转动1圈,如果需要控制电机转动多圈,需要在程序中行相应的修改。同时,由于步电机的转速和准确度与脉冲频率有关,因此在实际应用中需要根据具体情况行调试和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值