实践形式: √校内实践基地实践 □校外实践基地 □导师联系校外实践 □自行联系校外实践 □ 其他______________ 起止日期:2015.12.14-2015.12.25 实践总结(要求写明实践地点、实践时间、指导教师、实践目的、实践内容和完成情况,字数及其它具体要求由各学院根据学科情况自行制定。) 实践地点 实践目的 1. 利用所学过的基础知识,通过本次电子实习培养独立解决实际问题的能力。 2. 巩固本课程所学习的理论知识和实验技能。 3. 了解循迹小车构成的设计方法。 4. 掌握常用电子电路的一般设计方法,提高设计能力和实验、动手能力,为今后从事电子电路的设计、研制电子产品打下基础。 5. 培养团队的协作和沟通能力。 实践内容: 一、 智能小车配置 本次实训中所用到的智能小车如图1所示,其主要配置包括: 图1 智能小车 1、 小车底盘 小车底盘是机器人最重要的载体,相当于人体的驱干,ZK-4WD小车平台采用差速转弯非常灵活可以实现原地打转。小车平台大小刚好可以承载一些如驱动器控制器、控制器、电池、传感器等。 图2 小车底盘 2、驱动器 小车直流电机工作电流一般是200-400MA,有些更大,如果一个小车是二个轮子,那么总的电流在400-800MA左右,这些电机轮子都是要接受单片机指令执行相应的动作,而市面有的单片机IO 口一般只能提供5MA到10MA的电流,直接驱动不了电机,所以需要一个驱动模块,放大电流。驱动采用专业的L298N驱动芯片。 图3 L298N驱动芯片 3、控制器 图4为控制器STM32核心板,STM32平台采用核心板+外围板方式。核心板主要包括STM32F103VET6最小系统、按键、LED灯、TF卡、串口和JTAG电路。可以完成STM32内部资源的大部分开发应用。外围板包括数码管电路、存储器电路、红外、光敏电阻、温度传感器、ULN2003电路、步进电机、蜂鸣器、DS1302时钟电路和CAN总线等电路设计,基本包括了STM32的所有资源、同时又对IIC、单总线、SPI总线、CAN总线等协议进行了硬件设计。 图4 控制器STM32核心板 4、小车所需的能源 一般采用低内阻的充电电池套装。 图5 小车所需的充电电池 5、寻迹传感器 用来识别黑白线,小车沿着黑白线行走,就需要寻迹传感器。原理:寻迹传感器通常采用红外的方式,红外管发射出来的红外光通过地面(白色)反射回来,在接收管里收到信号,一旦碰到黑线,那么红外光都被吸收,接收管没有接收到信号,从而得知传感器是否压线,从而调整小车运行方向。 图6 寻迹传感器 二、 硬件接口电路设计 图7 硬件接线图 三、 软件编程实现 在空的Demo中打开软件编程界面编写程序,如图8所示。 图8 软件编程界面 小车寻迹控制程序包括主程序和中断程序如下: 主程序: #include "stm32f10x.h" void GPIO_Config() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_All; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStruct); } void HW_Config() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3); } void CAR_Config() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_All; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(GPIOD, &GPIO_InitStruct); } void EXIT_Config() { EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line=EXTI_Line0; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStruct); EXTI_InitStruct.EXTI_Line=EXTI_Line1; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStruct); EXTI_InitStruct.EXTI_Line=EXTI_Line2; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStruct); EXTI_InitStruct.EXTI_Line=EXTI_Line3; EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_InitStruct.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStruct); } void NVIC_Config() { NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel=EXTI1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel=EXTI2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel=EXTI3_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); } void TIM_Config() { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; TIM_TimeBaseInitStruct.TIM_Prescaler=360-1; TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period=200-1; TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//YS TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=80; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //有效值赋值 TIM_OC1Init(TIM4,&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//YX TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=85; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OC2Init(TIM4,&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//ZS TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=80; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //有效值赋值 TIM_OC3Init(TIM4,&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//ZX TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=85; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //有效值赋值 TIM_OC4Init(TIM4,&TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4,ENABLE); TIM_Cmd(TIM4,ENABLE); } int main() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOC|RCC _APB2Periph_GPIOB|RCC_APB2Periph_GPIOD,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); GPIO_Config(); HW_Config(); TIM_Config(); CAR_Config(); EXIT_Config(); NVIC_Config(); { while(1) { GPIO_Write(GPIOD,0x0066); } } } 中断程序: void delay(uint16_t z) { uint16_t i = 0; while(z--) { for(i=0;i<1;i++); } } void EXTI0_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line0); GPIO_Write(GPIOD,0x0069); if ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0)==SET)) { while ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0)==SET)) { } } } void EXTI1_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line1); GPIO_Write(GPIOD,0x0069); if ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1)==SET)) { while ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1)==SET)) { } } } void EXTI2_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line2); GPIO_Write(GPIOD,0x0096); if ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2)==SET)) { while ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2)==SET)) { } } } void EXTI3_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line3); GPIO_Write(GPIOD,0x0096); if ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3)==SET)) { while ((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3)==SET)) { } } } 四、 小车调试 打开图标 ,如图9示: 图9 ISP程序下载 点击联机下载时的程序文件,然后选择要下载的hex(目标文件)程序,如图10所示。 图10 ISP程序下载 寻迹功能:接通电源后,小车会沿着地上的黑线行驶,小车配有4个红外传感器,当左边的两个红外传感器检测到黑线时,小车向左转;当右边的两个红外传感器检测到黑线时,小车向右转,具体可通过PWM控制L298N来控制小车速度,达到小车寻迹行驶的目的。 调试中出现的问题及解决方法: 问题①:小车的速度太慢; 解决:通过改变定时器参数,调节占空比来达到调节小车速度的目的。 问题②:小车在拐弯时的弯度太大,寻迹不准确; 解决:将小车上的四个红外探头的距离调近一些,并且调整红外探头的灵敏度,使小车能够在不冲出轨迹的前提下快速转弯。 问题③:小车速度太快时,小车会冲出轨迹,导致无法继续寻迹; 解决:通过多次试验,找到最合适的参数值,以最快的速度完成寻迹。 五、 收获 首先感谢自动化系为我们提供这次宝贵的培训机会,感谢两位老师的悉心指导,通过为期十天的STM32智能小车实训,我基本掌握了智能小车的硬件设计,软件编程调试等内容,了解循迹小车构成的设计方法,掌握常用电子电路的一般设计方法,提高设计能力和实验、动手能力。通过本次电子实习,我加强了对于本课程所学习的理论知识的理解,提高了实验技能和独立解决实际问题的能力以及团队的协作和沟通能力,并且产生了对于嵌入式开发的浓厚兴趣。以后将继续深入学习STM32,掌握STM32开发流程及编程思想,为以后的工作和发展打下良好的基础,为今后从事电子电路的设计、研制电子产品打下基础。最后,期待学院以后还会给学生提供更多方面的培训。 本文来源:https://www.wddqw.com/doc/14cce8cde309581b6bd97f19227916888486b9e2.html