基于stm32微控制器的绘图机器人设计
创始人
2024-03-31 03:22:47

目录
第一章 绪论 1

  1. 基于 stm32 微控制器的绘图机器人研究设计的目的 1

  2. 基于 stm32 微控制器的绘图机器人研究设计的设计功能 1
    第二章 系统整体方案设计 2
    第三章 硬件设计 4

  3. 硬件电路资源使用设计 4
    1.1 STM32F103RBT6 片上资源 4
    1.2 外围芯片资源 4

  4. 机械结构设计 5

  5. 通信原理 9
    第四章 软件设计 11

  6. 上位机程序设计 11
    1.1 二值化算法 11
    1.2 轮廓化算法 13
    1.3 描边算法 14
    1.4 串口通信数据格式 16

  7. 下位机程序设计 17
    2.1 缓冲区算法 17
    2.2 Bresenham 直线算法 17
    2.3 坐标轴的确定 19
    第五章 系统调试与实验结果 21

  8. 系统调试 21

  9. 实验结果 24
    参 考 文 献 25
    致 谢 26
    附 录 27

  10. 通信原理
    在这里插入图片描述

图 3-6 组装实物图
下位机采用 STM32 作为控制器。STM32 使用 CH340G 与计算机端串口连接,不仅提 供到 PC 的串行连接,还提供主控供电。STM32 通过 2 个计时器输出 3 路 PWM 方波,通 过 3 个 GPIO 引脚输出数字电平或数字式脉冲信号。开发环境为 MDK。
把足够功率和频率的脉冲波按照一定的顺序传到步进电机,才能驱动步进电机转动。
步进电机驱动模块接收控制 PWM 信号、方向(DIR)电平和使能(EN)信号,并按照步 进电机分配方式所要求的状态顺序来产生各相控信号,步进电机驱动模块输出信号数与电 机相数相同。DRV8825 每接收一个 PWM 脉冲信号,DRV8825 就输出一个由 DIR、EN、 STEP 综合决定的步进电机驱动信号。信号的产生特点在 MDK 中编写,使 STM32 产生控 制脉冲信号和方向电平。步进电机驱动模块采用 DRV8825。DRV8825 是一款带过流保护和 转换器的 DMOS 微步驱动器,在“STEP”中输入一个脉冲,即可驱动电动机产生微步。 只要控制 STEP 和 DIR 就可以了,STEP 是控制脉冲输入端,DIR 是方向电平输入端;3 个 模式选择端 MS1、MS2、MS3 全部接地即使用 32 细分,如果要求更高的精度,可通过选 其他模式,如选择 1/32 步迸模式,电机转一圈就要送 6400 个微步才能完成。控制脉冲发 生器和驱动器的结构示意图如图 2-7 所示。
在这里插入图片描述
图 3-7 控制脉冲发生器和驱动器的结构
第四章 软件设计
绘图机器人运行中步进电机使用脉冲控制,STM32 发出与 42 步进电机前进距离的对 应控制信号和 PWM 信号。两点确定一条线段,由于串口速度较慢所以采用 div 参数增加细 分的方式减少串口数据传输量。给出两点 STM32 就会通过 Bresenham 直线算法,计算出其 间的各个点,再通过前后两点的位置关系完成绘图任务。

  1. 上位机程序设计
    上位机程序采用 C#编写,计算机上位机将图片二值化再轮廓化,将轮廓化子图的细分 后的点的信息发送给下位机器,下位机将数据存储进缓冲区,再将缓冲区的数据绘制成图, 不断执行.直到最后一个子图执行完毕。本文转载自http://www.biyezuopin.vip/onews.asp?id=12566图片可以是 jpg、 bmp、png 格式等。用绘图软件 打开“限制图幅.bmp”将欲打印的字或者图编辑入图片中,保存。
    在这里插入图片描述
    图 4-1 蓝星上位机界面
#include "bsp.h"void SW_GPIO_Config(void) //限位开关GPIO初始化 校准用限位
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(TOPSWITCHCLK|RCC_APB2Periph_AFIO,ENABLE );GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU ;GPIO_InitStructure.GPIO_Pin=TOPSWITCHPIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(TOPSWITCHPORT,&GPIO_InitStructure);RCC_APB2PeriphClockCmd(LEFTSWITCHCLK|RCC_APB2Periph_AFIO,ENABLE );GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU ;GPIO_InitStructure.GPIO_Pin=LEFTSWITCHPIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(LEFTSWITCHPORT,&GPIO_InitStructure);
{	
//	GPIO_EXTILineConfig(TOP_SWITCH_PORT_SOURCE, TOP_SWITCH_PIN_SOURCE);
//	GPIO_EXTILineConfig(LEFT_SWITCH_PORT_SOURCE, LEFT_SWITCH_PIN_SOURCE);	
//	
//	EXTI_InitTypeDef EXTI_InitStructure;
//	EXTI_InitStructure.EXTI_Line = LEFT_SWITCH_INT_EXTI_LINE;
//	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//	EXTI_Init(&EXTI_InitStructure);
//	
//	EXTI_InitStructure.EXTI_Line = TOP_SWITCH_INT_EXTI_LINE;
//	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//	EXTI_Init(&EXTI_InitStructure);
//	
//	NVIC_InitTypeDef NVIC_InitStructure;    
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
// 
//	NVIC_InitStructure.NVIC_IRQChannel = TOP_SWITCH_INT_EXTI_IRQ; //TOPSW外部中断线
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//	NVIC_Init(&NVIC_InitStructure);
//	
//	NVIC_InitStructure.NVIC_IRQChannel = LEFT_SWITCH_INT_EXTI_IRQ; //LEFTSW外部中断线
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//	NVIC_Init(&NVIC_InitStructure);}
}void MOT_GPIO_Config(void)//MOT pwm、GPIO初始化函数
{//Tim2 --- ch1   A0GPIO_InitTypeDef TOP_TIMGPIO_InitStructure;RCC_APB2PeriphClockCmd (AFIOCLK ,ENABLE );RCC_APB1PeriphClockCmd (TOP_MotSCLK,ENABLE );TOP_TIMGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;TOP_TIMGPIO_InitStructure .GPIO_Pin =TOP_MotSPIN;TOP_TIMGPIO_InitStructure .GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(TOP_MotSPORT,&TOP_TIMGPIO_InitStructure);//TOP D--B6GPIO_InitTypeDef TOP_DGPIO_InitStructure;RCC_APB2PeriphClockCmd (TOP_MotDCLK ,ENABLE );TOP_DGPIO_InitStructure .GPIO_Mode =GPIO_Mode_Out_PP ;TOP_DGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;TOP_DGPIO_InitStructure .GPIO_Pin =TOP_MotDPIN;GPIO_Init(TOP_MotDPORT,&TOP_DGPIO_InitStructure);//Tim2 --- ch2   A1GPIO_InitTypeDef BOT_TIMGPIO_InitStructure;RCC_APB2PeriphClockCmd (AFIOCLK ,ENABLE );RCC_APB1PeriphClockCmd (BOT_MotSCLK,ENABLE );BOT_TIMGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;BOT_TIMGPIO_InitStructure .GPIO_Pin =BOT_MotSPIN;BOT_TIMGPIO_InitStructure .GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(BOT_MotSPORT,&BOT_TIMGPIO_InitStructure);//BOT D--A8GPIO_InitTypeDef BOT_DGPIO_InitStructure;RCC_APB2PeriphClockCmd (BOT_MotDCLK ,ENABLE );BOT_DGPIO_InitStructure .GPIO_Mode =GPIO_Mode_Out_PP ;BOT_DGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;BOT_DGPIO_InitStructure .GPIO_Pin =BOT_MotDPIN;GPIO_Init(BOT_MotDPORT,&BOT_DGPIO_InitStructure);GPIO_InitTypeDef EGPIO_InitStructure;RCC_APB2PeriphClockCmd (MotECLK ,ENABLE );EGPIO_InitStructure .GPIO_Mode =GPIO_Mode_Out_PP ;EGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;EGPIO_InitStructure .GPIO_Pin =MotEPIN;GPIO_Init(MotEPORT,&EGPIO_InitStructure);MOT_DISEN;GPIO_InitTypeDef DJ_GPIO_InitStructure;RCC_APB2PeriphClockCmd (AFIOCLK ,ENABLE );RCC_APB1PeriphClockCmd (DJ_MotCLK,ENABLE );DJ_GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;DJ_GPIO_InitStructure .GPIO_Pin =DJ_MotPIN;DJ_GPIO_InitStructure .GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(DJ_MotPORT,&DJ_GPIO_InitStructure);}
void PWM_Config(u32 PWM1Freq)//Tim2 -PWM
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;u16 tim_period;u16 tim_pulse;tim_period=(u16)(TIM2_COUNTER_CLK/PWM1Freq-1);tim_pulse =(tim_period+1)*0.5;//默认占空比为50%TIM_TimeBaseStructure.TIM_Prescaler =0;//预分频为1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ;//向上计数TIM_TimeBaseStructure.TIM_Period = tim_period; //定时周期TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInit(TIM2 ,&TIM_TimeBaseStructure);TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse =tim_pulse;TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OC1Init(TIM2 ,&TIM_OCInitStructure);TIM_OC2Init(TIM2 ,&TIM_OCInitStructure);//	TIM2->CCER&=~1 ;//通道1关闭
//	TIM2->CCER&=~(1<<4) ;//通道2关闭TIM_OC1PolarityConfig (TIM2,TIM_OCPreload_Enable );TIM_OC2PolarityConfig (TIM2,TIM_OCPreload_Enable );TIM_ARRPreloadConfig (TIM2,ENABLE );TIM_Cmd (TIM2,ENABLE );TIM2->DIER |=(u32)1;//tim2中断使能
//		TIM2->CR2 &=~(u32)7<<4;
}void DJ_PWM_Config(u32 PWM1Freq)//Tim4 -ch4
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;u16 tim_period;u16 tim_pulse;tim_period=(u16)(TIM4_COUNTER_CLK/PWM1Freq-1);tim_pulse =(tim_period+1)*0.08;//默认占空比为8 x0.08TIM_TimeBaseStructure.TIM_Prescaler =1000;//预分频为1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ;//向上计数TIM_TimeBaseStructure.TIM_Period = tim_period; //定时周期TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse =tim_pulse;TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OC4Init(TIM4 ,&TIM_OCInitStructure);TIM_OC1PolarityConfig (TIM4,TIM_OCPreload_Enable );//TIM_OC4PolarityConfig (TIM4,TIM_OCPreload_Enable );TIM_ARRPreloadConfig (TIM4,ENABLE );TIM_Cmd (TIM4,ENABLE );TIM4->CCER|=(1<<12) ;//通道4打开
//TIM2->DIER |=(u32)1;//tim2中断使能
//		TIM2->CR2 &=~(u32)7<<4;}
void DJ_PWM_Change(u8 t,u32 PWM1Freq)
{u16 tim_period;u16 tim_pulse;	tim_period=(u16)(TIM4_COUNTER_CLK/PWM1Freq-1);tim_pulse =(tim_period+1)*t/1000;//默认占空比为8 x0.08DJ_TIM ->CCR4 = tim_pulse;
}void TIM_NVIC_Config(void)//TIM2中断初始化
{NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		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);
}void USART_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}
void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空模式GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);// 配置串口的工作参数USART_InitStructure.USART_BaudRate = DEBUG_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_Rx | USART_Mode_Tx;	// 配置工作模式,收发一起USART_Init(DEBUG_USARTx, &USART_InitStructure);	// 完成串口的初始化配置USART_NVIC_Config();	// 串口中断优先级配置USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);		// 使能串口接收中断USART_Cmd(DEBUG_USARTx, ENABLE);	    	// 使能串口}
void Usart_SendByte( USART_TypeDef * pUSARTx, u8 ch)//发送一个字节
{USART_SendData(pUSARTx,ch);	// 发送一个字节数据到USART while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);		// 等待发送数据寄存器为空
}void Usart_SendArray( USART_TypeDef * pUSARTx, u8 *array, u16 num) //发送8位数组
{uint8_t i;for(i=0; iUsart_SendByte(pUSARTx,array[i]);	//发送一个字节数据到USART }while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);	//等待发送完成 
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, u8 *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);  /* 等待发送完成 */
}/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, u16 ch)
{uint8_t temp_h, temp_l;/* 取出高八位 */temp_h = (ch&0XFF00)>>8;/* 取出低八位 */temp_l = ch&0XFF;/* 发送高八位 */USART_SendData(pUSARTx,temp_h);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);/* 发送低八位 */USART_SendData(pUSARTx,temp_l);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...