rt-thread,江科大STM32F103C8T6实现PWM控制电机

本文参考了众多文章还有江科大的视频实现的,有些底层逻辑我也不是很清楚但是调通了,感兴趣可以自己改一下代码,接线图和江科大定时器PWM控制直流电机一致其图片如下:

1.创建rt-thread工程

打开rt-thread studio,点击右上角的文件->新建->rt_thread项目,选择配置如下:

2.使用外部晶振作为时钟源

点击drivers找到board.h文件打开,往下翻找到时钟源配置,设置为如图所示:

3.配置rt-thread的PWM驱动

此时可以点击上方工具栏的第二个小锤子编译以下,也可不用直接配置下一步

4.使用STM32CubeMX生成配置文件

这一步注意不要再rt-thread studio工程中的CubeMX Settings中配置!

打开STM32CubeMX新建一个工程,找到STM32F103C8T6

接下来配置定时器2,如图所示

5.获取所需代码

打开使用STM32Cube生成的工程,按如图所示复制代码

代码大致如下:

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
  if(htim_base->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspInit 0 */

  /* USER CODE END TIM2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_TIM2_CLK_ENABLE();
  /* USER CODE BEGIN TIM2_MspInit 1 */

  /* USER CODE END TIM2_MspInit 1 */
  }

}

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(htim->Instance==TIM2)
  {
  /* USER CODE BEGIN TIM2_MspPostInit 0 */

  /* USER CODE END TIM2_MspPostInit 0 */

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM2 GPIO Configuration
    PA2     ------> TIM2_CH3
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM2_MspPostInit 1 */

  /* USER CODE END TIM2_MspPostInit 1 */
  }

}

接下来回到rt-thread studio中,将得到的代码复制到board.c文件的最下方,并将函数HAL_TIM_Base_MspInit改成HAL_TIM_PWM_MspInit

6.打开和补全所需宏定义

PWM2对应TIM2,CH3对应通道3,因为本实验所使用的定时器是TIM2,所以在pwm_config.h文件中有其PWM2的定义,故我们不需要补全其定义,但如果你想使用TIM1,应该复制其代码并且进行修改后,将PWM2修改为PWM1并且重新添加进去,因为我们没有使用到,故不需定义,具体图如下:

TIM1添加代码如下

最后编译查看是否有报错

7.代码实现

在main.c文件中编写以下代码OLED.h头文件是将江科大提供的代码移植的,只需要将其使用的标准库函数转换成HAL库函数即可),有感兴趣的大佬可以改改代码,或者自己写也可以,本人代码写的比较丑陋:

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "OLED.h"
#define LED_Pin     GET_PIN(B,10)
#define Key1        GET_PIN(B,1)

#define PWM_DEV_NAME "pwm2"
#define PWM_DEV_CHAN 3

rt_thread_t thread1;
rt_thread_t thread_uart;
rt_thread_t thread2;
rt_thread_t thread3;
rt_mq_t dmq;
rt_mq_t dmq1;
rt_mutex_t sempare;
void thread1_entry(void *arg);
void uartthread_entry(void *arg);
void thread2_entry(void *arg);
void thread3_entry(void *arg);




struct rt_device_pwm *pwm_dev;

int main(void)
{
    OLED_Init();
    OLED_ShowString(1,1,"SPEED:");
    rt_pin_mode(LED_Pin, PIN_MODE_OUTPUT_OD);
    rt_pin_mode(Key1, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(GET_PIN(A,4),PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(A,5),PIN_MODE_OUTPUT);
    sempare = rt_mutex_create("sem1",RT_IPC_FLAG_FIFO);
    dmq = rt_mq_create("compare", sizeof(int), 10, RT_IPC_FLAG_FIFO);
    dmq1 = rt_mq_create("compare", sizeof(int), 10, RT_IPC_FLAG_FIFO);
    thread1 = rt_thread_create("thread1",thread1_entry, RT_NULL, 1024, 10, 10);
    thread_uart = rt_thread_create("uart_thread",uartthread_entry, RT_NULL, 1024, 10, 10);
    thread2 = rt_thread_create("thread2", thread2_entry,RT_NULL,1024,10,10);
    thread3 = rt_thread_create("thread3", thread3_entry,RT_NULL,1024,10,10);
    pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
    if(pwm_dev == RT_NULL)
    {
        rt_kprintf("device error\r\n");
        return RT_ERROR;
    }
    rt_pwm_set(pwm_dev, PWM_DEV_CHAN, 100, 0);
    rt_pwm_enable(pwm_dev, PWM_DEV_CHAN);

     rt_thread_startup(thread1);
     rt_thread_startup(thread_uart);
     rt_thread_startup(thread2);
     rt_thread_startup(thread3);
    return RT_EOK;
}
void thread1_entry(void *arg)
{
    int compare = 0;
    while(1)
    {
       if(rt_pin_read(Key1) == PIN_LOW)
       {
           rt_thread_mdelay(20);
           while(rt_pin_read(Key1) == PIN_LOW);
           rt_thread_mdelay(20);
           compare+=2000;
           if(compare>10000)
           {
               compare = -10000;
           }
           rt_mq_send(dmq, &compare, sizeof(int));
           rt_mq_send(dmq1, &compare, sizeof(int));
       }
    }
}
void uartthread_entry(void *arg)
{
    while (1)
    {
       rt_kprintf("此内容无效\r\n");
       rt_thread_mdelay(1000);
    }
}
void thread2_entry(void *arg)
{
    int compare = 0;
    while(1)
    {
       rt_mq_recv(dmq, &compare, sizeof(int), RT_WAITING_FOREVER);
       if(compare>=0)
       {
           rt_pin_write(GET_PIN(A,5), PIN_HIGH);
           rt_pin_write(GET_PIN(A,4), PIN_LOW);
       }
       else
       {
           rt_pin_write(GET_PIN(A,4), PIN_HIGH);
           rt_pin_write(GET_PIN(A,5), PIN_LOW);
           compare = -compare;
       }
       rt_mutex_take(sempare, RT_WAITING_FOREVER);
       rt_pwm_set(pwm_dev, PWM_DEV_CHAN,10000,compare);
       rt_mutex_release(sempare);

    }
}
void thread3_entry(void *agr)
{
    int compare = 0;
    OLED_ShowSignedNum(2, 1, compare, 6);
    while(1)
    {
        rt_mq_recv(dmq1, &compare, sizeof(int), RT_WAITING_FOREVER);
        OLED_ShowSignedNum(2, 1, compare, 6);
        rt_thread_mdelay(1000);
    }
}

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值