一、设计简介
毕业设计基础模块--stm32单片机通过薄膜压力传感器自动调节步进电机28BYJ-48正反转加减速,可串口通讯指令控制,ULN2003驱动,+0.96oled显示压力传感器值+实物仿真原理图源代码程序由于篇幅限制,我将提供一个简化的代码框架和实物仿真原理图的描述。
二、硬件介绍
-
STM32单片机:作为主控制器,负责PWM信号的生成、按键扫描和OLED显示数据的发送。
-
TULN2003电机驱动模块
-
直流电机:连接到TB6612的输出端。
-
按键:连接到STM32的GPIO引脚,用于调节电机转速。
-
0.96寸OLED显示屏:连接到STM32的SPI或I2C接口,用于显示转速占空比。
-
Proteus仿真模拟串口:在Proteus仿真中COMPIM 模块模拟无线串口模块的功能,通过与单片机的串口引脚建立连接,能够实现串口数据的高效发送与接收仿真。
-
-
二、所需硬件以及传感器模块
1.1 stm32f103c8t6(1个)
STM32F103C8T6单片机是一款非常用的单片机型号,可以方便灵活的进行嵌入式系统开发。首先,它的处理器基于Cortex-M3内核,最高工作频率达72MHz。STM32F103C8T6拥有64KB闪存和20KB SRAM,非常适合中小型单片机开发项目。
具有非常丰富的外设接口,如串口USART、SPI通信、I2C通讯、CAN通讯和USB,在与单片机外设通信方面非常方便。有多个GPIO通用IO口,定时器,中断系统,灵活配置为输入,输出、模拟输入或PWM输出,可以连接各类传感器和模块。
内部集成的12位逐次逼近型ADC和DAC,支持高精度模拟信号处理。STM32F103C8T6还支持低功耗模式,适合电池供电的应用场景。结合强大的STM32开发生态,包括库函数和工具链,可以让开发者很方便的完成单片机项目的开发。
-
1.2 电机驱动模块ULN2003(1个)
ULN2003A是一款高压、大电流达林顿晶体管阵列单片集成电路
1、基本特性
ULN2003A内部由7个相同的达林顿对组成,单个达林顿对由两个双极晶体管组成,具有一个共同的发射极和开路的集电极。当输入端为高电平时,ULN2003A输出端为低电平;当输入端为低电平时,由于内部非门结构的存在,输出端实际上会变为高阻态,而非直接输出高电平,但通常可以理解为在应用中该状态下输出无效或高电平(因为需要通过外部上拉电阻等电路来产生实际的高电平输出)。此外,ULN2003A还包含用于感应负载驱动的抑制二极管,以防止反电动势对电路造成损害。
-
特点: - 耐压高,输出工作电压可达50V。
- 内设过压保护电路,防止由感应负载引入的过压损害。
- 峰值涌入电流达600mA,可以驱动白炽灯等负载。
- 输入阻抗为2.7kΩ,可与使用5V电压的TTL或CMOS逻辑电路配合使用。
三、Proteus仿真
四、程序代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "OLED.h"
#include "stepmotor.h"
#include "Serial.h"
#include "Key.h"
#include "AD.h"
uint8_t Serial_RxData; //定义串口接收的数据变量
uint16_t Press; //薄膜压力传感器数据变量
uint32_t Beats; //电机转动节拍
uint8_t KeyNum; //按键变量
uint8_t Speed; //速度变量
uint8_t Flag; //手动自动标志位变量
int main(void)
{
OLED_Init(); //显示屏初始化
Stepper_Servo_Init(); //步进电机初始化
LED_Init(); //LED初始化
AD_Init(); //AD初始化
Key_Init(); //按键初始化
Serial_Init(); //串口初始化
OLED_ShowString(0,0,"Press:",OLED_8X16); //显示静态文字
OLED_ShowString(0,16,"Speed:",OLED_8X16); //显示静态文字
while (1)
{
Delay_ms(100);
OLED_ShowNum(48,0,Press,4,OLED_8X16); //显示压力值
OLED_ShowNum(48,16,Speed,2,OLED_8X16); //显示转速
if(Flag==0) //自动模式,显示屏显示auto
{
OLED_ClearArea(0,32,128,16);
OLED_ShowString(0,32,"Auto",OLED_8X16);
}
else //手动模式,显示屏显示Manual
{
OLED_ClearArea(0,32,128,16);
OLED_ShowString(0,32,"Manual",OLED_8X16);
}
OLED_Update();
Press=AD_GetValue(ADC_Channel_0); //启动ADC,转换通道0
KeyNum=Key_GetNum(); //获取按键值
if(KeyNum==1) //按键1按下
{
Flag=0; //切换回自动模式
}
if(Press<=1500&&Flag==0) //不同压力值,调节电机转速,同时亮起对应LED
{
Speed=10;
Stepper_Servo_Angle(Forward,Speed,180);
LED1_ON();
LED2_OFF();
LED3_OFF();
}
else if(Press>1500&&Press<2000&&Flag==0) //不同压力值,调节电机转速,同时亮起对应LED
{
Speed=5;
Stepper_Servo_Angle(Forward,Speed,180);
LED1_OFF();
LED2_OFF();
LED3_ON();
}
else if(Press>=2000&&Press<2100&&Flag==0) //不同压力值,调节电机转速,同时亮起对应LED
{
Speed=0;
Beats=0;
Stepper_Servo_Stop();
LED1_OFF();
LED2_OFF();
LED3_OFF();
}
else if(Press>=2100&&Flag==0) //不同压力值,调节电机转速,同时亮起对应LED
{
Speed=10;
Stepper_Servo_Angle(Reversal,Speed,180);
LED1_OFF();
LED2_ON();
LED3_OFF();
}
if(KeyNum==2) //按键2按下,电机停止转动,LED灭灯
{
Flag=1;
Speed=0;
Beats=0;
Stepper_Servo_Stop();
LED1_OFF();
LED2_OFF();
LED3_OFF();
}
}
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否是USART1的接收事件触发的中断
{
Serial_RxData = USART_ReceiveData(USART1); //读取数据寄存器,存放在接收的数据变
if(Serial_RxData==1) //串口接收到数据0X01,正转,速度10
{
Flag=1;
Speed=10;
Stepper_Servo_Angle(Forward,Speed,180);
LED1_ON();
LED2_OFF();
LED3_OFF();
}
else if(Serial_RxData==2) //串口接收到数据0X02,正转,速度5
{
Flag=1;
Speed=5;
Stepper_Servo_Angle(Forward,Speed,180);
LED1_OFF();
LED2_OFF();
LED3_ON();
}
else if(Serial_RxData==3) //串口接收到数据0X03,反转,速度10
{
Flag=1;
Speed=10;
Stepper_Servo_Angle(Reversal,Speed,180);
LED1_OFF();
LED2_ON();
LED3_OFF();
}
else if(Serial_RxData==4) //串口接收到数据0X04,停止转动
{
Flag=1;
Speed=0;
Beats=0;
Stepper_Servo_Stop();
LED1_OFF();
LED2_OFF();
LED3_OFF();
}
else if(Serial_RxData==5) //串口接收到数据0X05,切换回自动模式
{
Flag=0;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除USART1的RXNE标志位
//读取数据寄存器会自动清除此标志位
//如果已经读取了数据寄存器,也可以不执行此代码
}
}
五、资料内容清单