写一个基于stm32c8t6能讲电机转速发送到上位机labview中,并且从上位机中控制电机目标转速的在下位机中需要的程序
时间: 2024-06-09 10:04:37 浏览: 87
以下是一个基于STM32C8T6的电机转速测量和控制程序,可以将实际转速发送到上位机LabVIEW中,并从上位机中控制电机的目标转速。
程序中使用了STM32C8T6自带的定时器TIM2来测量电机转速,使用USART1串口通信模块将实际转速发送到上位机LabVIEW中。同时,程序还可以接收上位机发送的控制指令,并根据指令控制电机的转速。具体实现细节如下:
```
#include "stm32f10x.h"
#include <stdio.h>
#define MOTOR_PIN GPIO_Pin_8
#define MOTOR_PORT GPIOB
#define MOTOR_CLK RCC_APB2Periph_GPIOB
#define USART_PIN_TX GPIO_Pin_9
#define USART_PIN_RX GPIO_Pin_10
#define USART_GPIO GPIOA
#define USART_CLK RCC_APB2Periph_GPIOA
#define USART USART1
#define USART_CLK_ENABLE RCC_APB2Periph_USART1
#define USART_BAUDRATE 9600
#define TIMER TIM2
#define TIMER_CLK RCC_APB1Periph_TIM2
#define TIMER_PERIOD 65535
void init_motor(void);
void set_motor_speed(uint16_t speed);
void init_usart(void);
void send_data(uint16_t data);
void init_timer(void);
uint16_t get_motor_speed(void);
volatile uint16_t motor_speed = 0;
int main(void)
{
init_motor();
init_usart();
init_timer();
while (1)
{
uint16_t speed = get_motor_speed();
send_data(speed);
}
}
void init_motor(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(MOTOR_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = MOTOR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_PORT, &GPIO_InitStructure);
}
void set_motor_speed(uint16_t speed)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = speed;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIMER, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIMER, TIM_OCPreload_Enable);
TIM_Cmd(TIMER, ENABLE);
}
void init_usart(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(USART_CLK | USART_CLK_ENABLE, ENABLE);
GPIO_InitStructure.GPIO_Pin = USART_PIN_TX | USART_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USART_GPIO, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = USART_BAUDRATE;
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_Tx | USART_Mode_Rx;
USART_Init(USART, &USART_InitStructure);
USART_ITConfig(USART, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART, ENABLE);
}
void send_data(uint16_t data)
{
char buffer[10];
sprintf(buffer, "%d\r\n", data);
for (int i = 0; i < strlen(buffer); i++)
{
while (USART_GetFlagStatus(USART, USART_FLAG_TXE) == RESET);
USART_SendData(USART, buffer[i]);
}
}
void init_timer(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(TIMER_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = MOTOR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_PORT, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / (2 * TIMER_PERIOD) - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMER, &TIM_TimeBaseStructure);
TIM_OC1PreloadConfig(TIMER, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIMER, ENABLE);
TIM_ITConfig(TIMER, TIM_IT_Update, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIMER, ENABLE);
}
uint16_t get_motor_speed(void)
{
return motor_speed;
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIMER, TIM_IT_Update) != RESET)
{
motor_speed = TIM_GetCounter(TIMER);
TIM_SetCounter(TIMER, 0);
TIM_ClearITPendingBit(TIMER, TIM_IT_Update);
}
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART, USART_IT_RXNE) != RESET)
{
uint16_t speed = USART_ReceiveData(USART);
set_motor_speed(speed);
USART_ClearITPendingBit(USART, USART_IT_RXNE);
}
}
```
需要注意的是,LabVIEW中需要使用串口通信模块来接收下位机发送的数据,并发送控制指令给下位机。具体实现方法可以参考LabVIEW官方文档。
阅读全文