我们不做一锤子买卖,只做技术成长的长期伙伴!
源码获取链接再后面:
目录
一、模块介绍以及常用方案
1.模块实物图


2.模块介绍

3.常用方案
基于单片机的智能风扇
基于STM32的智能小车
基于STM32的模拟刹车系统
二、引脚图以及原理图快速绘制技巧(视频教程)
TT马达(直流电机)

提示:在嘉立创库中能找到的器件都不需要自己画!
三、模块的引脚连接以及代码讲解与移植
1、引脚功能以及与单片机连接和代码讲解
单片机型号:STM32F103C8T6
模块型号:TT马达(直流电机)
驱动芯片:L293D
|-----------|------------|-----------------------------|
| 模块引脚号 | 单片机引脚号 | 单片机引脚功能 |
| ENABLE1 | 浮空 | 使能引脚1,高电平有效,用于激活第一个H桥电机驱动通道 |
| INPUT1 | 浮空 | 输入引脚1,与INPUT2配合控制第一个电机的转向 |
| OUTPUT1 | 浮空 | 输出引脚1,连接到第一个电机的一端 |
| GND | GND | 接地引脚,系统接地参考点 |
| GND | GND | 接地引脚,系统接地参考点 |
| OUTPUT2 | 浮空 | 输出引脚2,连接到第一个电机的另一端 |
| INPUT2 | 浮空 | 输入引脚2,与INPUT1配合控制第一个电机的转向 |
| VS | +5V | 电机驱动电源正极,为电机提供驱动电压 |
| ENABLE2 | PB1 | 使能引脚2,高电平有效,用于激活第二个H桥电机驱动通道 |
| INPUT3 | PA5 | 输入引脚3,与INPUT4配合控制第二个电机的转向 |
| OUTPUT3 | 电机端口 | 输出引脚3,连接到第二个电机的一端 |
| GND | 浮空 | 接地引脚,系统接地参考点 |
| GND | 浮空 | 接地引脚,系统接地参考点 |
| OUTPUT4 | 电机端口 | 输出引脚4,连接到第二个电机的另一端 |
| INPUT4 | PA6 | 输入引脚4,与INPUT3配合控制第二个电机的转向 |
| VSS | +5V | 芯片逻辑电源正极,为芯片内部逻辑电路供电 |
2、模块实例工程代码讲解
MOTOR.c文件
#include "MOTOR.h"
void motor_init()//????I/O??????
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //PC.10 DATA
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);//???GPIOA.10
GPIO_ResetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);
}
void TIM_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//////////////////////////////////////////////////////////////////////////////////////////////
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;//TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM3,ENABLE); //MOE 主输出使能
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //CH1预装载使能
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //CH1预装载使能
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM1
}
void TIM_PWM_Init2(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
// 第一步 使能TIM1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 第二步 使能TIM1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //时钟 TIM1 使能
// 第二步 定时器 TIM1 初始化,输入时钟72MHz,时钟分割1,分频系数72,PWM频率72M/72/1000=1kHz
TIM_TimeBaseStructure.TIM_Period = 199; //设置自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = 7199; //设置时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数
TIM_TimeBaseStructure.TIM_RepetitionCounter=0; //高级定时器1是用定时器功能配置这个才可以是正常的计数频率一开始的72mhz 值得注意的地方
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //初始化 TIM1
// TIM_ITConfig(TIM1,TIM_IT_Update, ENABLE ); //允许更新中断
TIM_ITConfig(TIM1,TIM_IT_Update, DISABLE ); //禁止更新中断
// 第三步 中断优先级 NVIC 设置
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //TIM1 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 1 级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级 3 级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化 NVIC 寄存器
//第四步pwm输出配置
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置为pwm2输出模式
TIM_OCInitStructure.TIM_Pulse=23; //设置占空比时间
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //设置输出极性
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Disable; //使能该通道输出
//下面几个参数是高级定时器才会用到,通用定时器不用配置
TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High; //设置互补端输出极性
TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;//使能互补端输出
TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset; //死区后输出状态
TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset; //死区后互补端输出状态
TIM_OC2Init(TIM1,&TIM_OCInitStructure); //按照指定参数初始化
//第五步,死区和刹车功能配置,高级定时器才有的,通用定时器不用配置
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;//运行模式下输出选择
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;//空闲模式下输出选择
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; //锁定设置
TIM_BDTRInitStructure.TIM_DeadTime = 0x10; //死区时间设置
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //刹车功能使能
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; //刹车输入极性
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出使能
TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
//第六步,使能端的打开
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIMx在CCR2上的预装载寄存器
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1,ENABLE); //打开TIM2
//下面这句是高级定时器才有的,输出pwm必须打开
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
void go(u8 y)//进
{
IN3 = 0;
IN4 = 1;
TIM_SetCompare4(TIM3,y);
}
void back(u8 y)//退
{
IN3 = 1;
IN4 = 0;
TIM_SetCompare4(TIM3,y);
}
void stop(void)
{
IN3 = 0;
IN4 = 0;
}
MOTOR.h文件
#ifndef __MOTOR_H
#define __MOTOR_H
#include "sys.h"
#define IN3 PAout(6)
#define IN4 PAout(5)//13
void motor_init(void);
void TIM_PWM_Init(u16 arr,u16 psc);
void TIM_PWM_Init2(void);
void go(u8 y);
void back(u8 y);
void turn_right(u8 x,u8 y);
void turn_left(u8 x,u8 y);
void stop(void);
#endif
main文件
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "lcd.h"
#include "timer.h"
#include "MOTOR.h"
#include <stdbool.h>
/**************************星一工作室***************************
声明:本程序只供学习使用,未经作者许可,不得用于其它任何用途
型号:STM32F103C8T6
公众号:星一电子工作室
B站教程号:星一工作室
CSDN:星一工作室
更多资料和视频教程请关注公众号!
***************************星一工作室***************************/
u8 count = 0;
int main (void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
OLED_Init();
delay_ms(1);
OLED_Clear();
motor_init();
TIM_PWM_Init(72-1,1000-1);
while(1)
{
OLED_ShowCH(0,6," 公众号获取资料 ");
count+=30;
if(count >= 100){
count = 0;
}
go(count);
switch(count){
case 0: OLED_ShowCH(0,2," 停止 ");break;
case 30: OLED_ShowCH(0,2," 低速 ");break;
case 60: OLED_ShowCH(0,2," 中速 ");break;
case 90: OLED_ShowCH(0,2," 高速 ");break;
default:break;
}
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
}
}