基于STM32循迹小车(两相步进电机+ST188)

th13teenth 2012-12-09 04:15:06
之前做了一个基于STM32的循迹小车,刚开始调试代码的时候写法比较粗糙和简单,等后来将代码优化完成,类似于电脑鼠代码的格式,现在给大家分享下我的主函数,因为初始化配置等代码在看看了主函数之后就知道该配置哪些GPIO口,TIM2定时器中断等,其他的就是STM32库函数了。
步进电机用的是两相四线的电机,代码时序是8拍;红外用的是ST188两个红外,左右两个红外在黑线外面,当探测到黑线的时候电机停止。


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "StepperMotor.h"
#include "stm32f10x_exti.h"
#include <stdio.h>

/*
*左电机四引脚
*/

#define MT_LFT_A1 GPIO_Pin_6
#define MT_LFT_B1 GPIO_Pin_7
#define MT_LFT_A2 GPIO_Pin_9
#define MT_LFT_B2 GPIO_Pin_10
/*
*右电机四引脚
*/
#define MT_RGT_A1 GPIO_Pin_6
#define MT_RGT_B1 GPIO_Pin_7
#define MT_RGT_A2 GPIO_Pin_9
#define MT_RGT_B2 GPIO_Pin_10
/*
*左电机时序宏定义
*/
#define MT_LFT_OFF() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2)

#define MT_LFT_STEP1_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_A1);

#define MT_LFT_STEP2_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_A1|MT_LFT_B1);

#define MT_LFT_STEP3_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_B1);

#define MT_LFT_STEP4_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_B1|MT_LFT_A2);

#define MT_LFT_STEP5_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_A2);

#define MT_LFT_STEP6_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_A2|MT_LFT_B2);

#define MT_LFT_STEP7_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_B2);

#define MT_LFT_STEP8_SET() GPIO_SetBits(GPIOA,MT_LFT_A1|MT_LFT_B1|MT_LFT_A2|MT_LFT_B2); \
GPIO_ResetBits(GPIOA,MT_LFT_B2|MT_LFT_A1);

/*
*右电机时序宏定义
*/
#define MT_RGT_OFF() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2)

#define MT_RGT_STEP1_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_A1);

#define MT_RGT_STEP2_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_A1|MT_RGT_B1);

#define MT_RGT_STEP3_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_B1);

#define MT_RGT_STEP4_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_B1|MT_RGT_A2);

#define MT_RGT_STEP5_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_A2);

#define MT_RGT_STEP6_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_A2|MT_RGT_B2);

#define MT_RGT_STEP7_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_B2);

#define MT_RGT_STEP8_SET() GPIO_SetBits(GPIOC,MT_RGT_A1|MT_RGT_B1|MT_RGT_A2|MT_RGT_B2); \
GPIO_ResetBits(GPIOC,MT_RGT_B2|MT_RGT_A1);

/** @addtogroup FullHalfStepMode
* @{
*/

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

ErrorStatus HSEStartUpStatus;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration1(void);
void NVIC_Configuration2(void);
void BUTTON_GPIO_Configuration(void);
void EXTI_Configruation(void);
void delay_ms(unsigned int time);
void StepLeft(void);
void StepRight(void);

/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval : None
*/
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* System Clocks Configuration */
RCC_Configuration();
/* NVIC Configuration */
NVIC_Configuration1();
NVIC_Configuration2();

EXTI_Configruation();
/* Activate the driver */
Stepper_Cmd(ENABLE);
/* Driver control pin configuration */
Stepper_PinControlConfig();
Stepper_Init();
while (1)
{

}
}
/*
*左步进电机时序
*/
void StepLeft(void)
{
static unsigned int ucRunStepLft=0;
switch(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
{
case 0:
if(++ucRunStepLft>=8)
ucRunStepLft=0;
break;
case 1:
MT_LFT_OFF();
break;
default:
break;
}

switch(ucRunStepLft)
{
case 0:
MT_LFT_STEP1_SET();
break;
case 1:
MT_LFT_STEP2_SET();
break;
case 2:
MT_LFT_STEP3_SET();
break;
case 3:
MT_LFT_STEP4_SET();
break;
case 4:
MT_LFT_STEP5_SET();
break;
case 5:
MT_LFT_STEP6_SET();
break;
case 6:
MT_LFT_STEP7_SET();
break;
case 7:
MT_LFT_STEP8_SET();
break;
default:
break;
}
}
/*
*右步进电机时序
*/
void StepRight(void)
{
static unsigned int ucRunStepRgt=0;
switch(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3))
{
case 0:
if(++ucRunStepRgt>=8)
ucRunStepRgt=0;
break;
case 1:
MT_RGT_OFF();
break;
default:
break;
}
if(++ucRunStepRgt>=8)
ucRunStepRgt=0;
switch(ucRunStepRgt)
{
case 0:
MT_RGT_STEP1_SET();
break;
case 1:
MT_RGT_STEP2_SET();
break;
case 2:
MT_RGT_STEP3_SET();
break;
case 3:
MT_RGT_STEP4_SET();
break;
case 4:
MT_RGT_STEP5_SET();
break;
case 5:
MT_RGT_STEP6_SET();
break;
case 6:
MT_RGT_STEP7_SET();
break;
case 7:
MT_RGT_STEP8_SET();
break;
default:
break;
}
}
/*
*定时器中断
*/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
StepLeft();
StepRight();
}
}

/**
* @brief Configures the different system clocks.
* @param None
* @retval : None
*/
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}

}

/**
* @brief Configure the nested vectored interrupt controller.
* @param None
* @retval : None
*/
void NVIC_Configuration1(void)
{
NVIC_SetPriorityGrouping(7); /* 0 bits for pre-emption priority 4 bits for
subpriority*/
NVIC_SetPriority(DMA1_Channel2_IRQn, 0x01); /* 0x01 = 0x0 << 3 | (0x1 & 0x7), prority
is 0x01 << 4 */
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}

#ifdef USE_FULL_ASSERT

/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{

}
}
#endif
void EXTI_Configruation(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
/* Connect Button EXTI Line to Button GPIO Pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
/* Configure Button EXTI line */
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Connect Button EXTI Line to Button GPIO Pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
/* Configure Button EXTI line */
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_Init(&EXTI_InitStructure);
}

void NVIC_Configuration2(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
//NVIC_Init(&NVIC_InitStructure);
}

/************************END OF FILE**********************/
...全文
672 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
dragon_cheng 2013-04-19
  • 打赏
  • 举报
回复
还可以吧、、、
wan2111 2013-04-17
  • 打赏
  • 举报
回复
这个貌似只能直走?
lbing7 2012-12-10
  • 打赏
  • 举报
回复
很少看完这种光贴代码的。。。
th13teenth 2012-12-09
  • 打赏
  • 举报
回复
没人?占楼自坐~
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 【运算单元构造实验报告】运算单元是计算机硬件系统中的关键构成部分,主要承担执行算术运算和逻辑运算的任务。在本次实验中,我们着重探讨了带有累加器的运算单元的设计,涵盖了溢出识别、有符号数值与无符号数值运算的差异性,以及采用补码方式进行的加法与减法运算的实现机制。 一、实验目标 1. 掌握运算单元的基本构造,理解带有累加器的运算单元的具体实现途径。 2. 学习并领会溢出检测的机制,能够设计并构建溢出检测电路,用以判定运算结果是否超出了数据类型的表示范畴。 3. 明辨有符号数值和无符号数值运算的不同特性,把握它们在运算过程中各自的处理方法。 4. 熟练掌握基于补码方式的加法与减法运算的执行,理解补码形式下的溢出判定准则。 5. 熟悉运算单元内部的数据传输路线,明晰数据在运算过程中的流转路径。 6. 设计一个能够支持有符号数值与无符号数值运算、补码加法/减法运算以及有符号数值溢出检测的运算单元电路。 二、实验仪器 采用JZYL—Ⅱ型计算机组成原理实验装置,配备2片74181运算单元芯片作为算术逻辑单元(ALU),2片74LS373用作八位D型锁存器,并辅以一些基础门电路和多路选择器来完成电路设计。 三、实验内容 1. 运用片74181构建一个8位运算单元,负责处理数据的高4位与低4位。 2. 设计并实现溢出检测电路,确保在有符号数值与无符号数值的加法运算中均能准确识别溢出状况。 3. 通过74LS373增加累加器功能,使运算结果得以保存。 4. 将所有设计整合,利用多路选择器来支持有符号数值与无符号数值的加法/减法运算。 四、实验电路 1. 8位运算单元由2片74181构成,通过控制...

27,521

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧