电动车跷跷板程序

合集下载

电动车跷跷板设计方案

电动车跷跷板设计方案

电动车跷跷板设计方案电动车跷跷板是一种创新性的设计,可以帮助人们更方便地停靠和启动电动车。

在许多城市,电动车已经成为主要的出行方式。

然而,电动车在停车时,需要使用力量将车辆托起或降下,这对于一些年纪较大或身体不适的人来说可能会很困难。

因此,电动车跷跷板是一项非常有用的发明,能够让电动车的停放更加容易和便捷。

一般来说,电动车跷跷板有两种设计方案:手动操作和自动操作。

手动操作的设计需要用户手动旋转跷跷板,以将电动车推起或降下。

这种设计成本较低,但用户需要一定的力量和技能才能轻松完成操作。

另外,手动操作的设计需要更多的时间和精力,不太适合老年人或身体有残疾的人。

自动操作的设计是一种更加先进和高级的设计,它利用电动机和控制器来完成跷跷板的升降操作。

用户只需要轻按按钮或开关即可完成整个过程。

自动操作的设计有多种控制方式,包括遥控器、传感器和自动识别系统等等。

这种设计的成本更高,但用户可以省去很多时间和精力,使用起来非常方便。

除了操作方式的不同,电动车跷跷板的设计还有很多其他的特点。

比如,电动车跷跷板的材料可以采用钢板、铝合金、塑料等多种材质,不同的材料有着不同的优势和劣势,需要根据风险防范、耐用性、安全性和成本等多个因素来选择。

电动车跷跷板的设计还可以增加一些额外的功能,如夜视灯、加热器、视音频系统等等,这些增强功能可以使车辆的停放更加智能化和便捷。

除了以上提到的基本设计特点,为了满足不同用户的需求和喜好,电动车跷跷板还可以增加一些个性化的设计元素。

比如,可以在跷跷板表面印上个性化的图案或标志,让用户可以将自己的电动车个性化地装扮起来。

此外,电动车跷跷板的外形和尺寸也可以根据用户需求进行定制。

在选择电动车跷跷板方案时,需要考虑很多因素,如成本、设计和效果等等。

这些因素关系到电动车跷跷板的使用效果和意义,也与对于产品的整体评估有关。

因此,我们需要在设计电动车跷跷板时,充分考虑不同用户的需求和喜好,以期为用户提供最佳的使用体验。

电动车跷跷板设计方案

电动车跷跷板设计方案

电动车跷跷板设计方案柳州运输职业技术学院摘要该电动车以凌阳SPCE061A作为操纵及数据处理的核心,通过传感器检测、操纵电动车电机的快慢、启停。

电动车能够在跷跷板上自动查找平稳点,并具有实时显示电动车行驶时刻及任务完成之后自动播报从起始端自动行走到末端及返回所需时刻或从起始端自动行走到电动车保持平稳所需时刻。

关键字:SPCE061A 倾角传感器光电传感器 PWM一、方案设计与论证本项目按设计要求可分为五部分,分别为操纵模块、循迹模块、平稳检测模块、电机驱动模块、显示模块,如图1所示。

图1 系统模块框图〔一〕操纵模块方案一:采纳AT89C51系列单片机作为操纵的核心。

51单片机按单纯的操纵和数据处理是比较经济实惠的,但本项目触及到A/D转换和PWM操纵,假如要具备这两个功能必须要有专用的A/D芯片和PWM操纵电路,这无疑是提高了成本。

方案二:采纳凌阳16位单片机SPCE061A作为操纵的核心。

SPCE061A具有10位A/D转换和PWM操纵功能,且具备语音播报功能,使作品更加智能化。

综上分析,选择方案二。

〔二〕平稳检测模块方案一:采纳水银开关检测跷跷板平稳点。

其内部是由两根导线组合而成,只要当水银流淌到导线的两端即水银把两根导线短接在一起。

但当跷跷板平稳时,有可能水银开关还未闭合,可靠性不高。

方案二:采纳Accu StarⅡ倾角传感器检测跷跷板平稳点。

此倾角传感器是通过改变角度来改变其输出电压,具有良好的线性变化,如图2所示,通过读取输出电压的值来操纵小车的速度,有助于电动车找到平稳点。

因此选择方案二。

〔三〕电机驱动模块方案一:采纳分立元件构成的H桥式电机驱动电路。

该驱动电路的优点是成本低,缺点是电路制作比较苦恼,可靠性不高。

方案二:采纳L293D驱动电机。

使用该芯片驱动的好处是在额定的电压和电流内使用专门方便可靠,能够缩小PCB板。

用SPCE061A自带的PWM操纵电机成效更好,使电动车更容易的查找到跷跷板的平稳点。

基于PID 算法的电动车跷跷板系统设计

基于PID 算法的电动车跷跷板系统设计

基于PID算法的电动车跷跷板系统设计聂晓凯中南大学信息科学与工程学院,长沙(410083)E-mail:kasaos@摘要:本系统采用P89V51RD2单片机作为控制系统的核心,采用步进电机作为电动车驱动电机,以L298为驱动芯片,配以舵机改变转向,使用角度传感器检测跷跷板的角度变化,在车的前后端设计了红外黑线检测模块保证电动车顺利驶上板以及在板上笔直行驶,红外光电码盘通过脉冲计数确定电动车在板上的位置,红外遥控键盘启动系统开始运行,液晶显示相关参数信息。

系统的平衡调节采用了数字PID控制算法,利用凑试法整定PID参数,通过角度传感器所测角度变化来控制步进电机的的转动实现跷跷板达到平衡状态。

关键词:P89V51RD2单片机,PID,角度传感器中图分类号:TP2712007年全国大学生电子设计竞赛的一道控制类的题目是电动车跷跷板问题,本系统设计要求电动车能够在规定时间内到达跷跷板的中心点C处,并保持平衡,随后电动车到达跷跷板的末端B处,停留之后返回始端A处。

另外,如果将跷跷板配重,则要求跷跷板在规定范围内驶上板,同时,也能实现平衡,如果再加一块重物之后跷跷板重新达到平衡。

本系统的设计在本文中采用了数字PID控制算法来实现。

1 系统方案设计、比较与论证1.1 总体方案设计论证本系统采用P89V51RD2单片机作为控制系统的主模块,实现系统控制与信号检测,如图1-1所示系统框图。

主要包括单片机模块,驱动电机模块,舵机模块,平衡检测模块,寻线模块,位置检测模块,液晶显示模块以及红外遥控模块。

图 1-1 系统框图系统通过平衡检测来判断电动车是否处于平衡状态,使电动车停留在C处附近,采用位置检测使电动车行驶至B处停止,采用寻黑线方法使电动车直线前行以及由末端B处能够直线后退到始端A处。

红外遥控启动系统,液晶显示各阶段用时以及温度时间。

在配重情况下通过黑线检测的方法使电动车在规定区域内的任意指定位置顺利驶上跷跷板。

电动车跷跷板 新2

电动车跷跷板 新2

2007年全国大学生电子设计竞赛F题电动车跷跷板设计报告摘要本系统是以单片机AT89S52为核心,利用红外光电传感器,角度传感器以及他们的外围电路组成的测控系统,实现对在跷跷板上行驶的小车的运动状态的实时跟踪监测,由单片机对电动小车的位姿状态做出及时正确的反应,并输出相应的控制指令,经过驱动模块后由执行模块完成小车的爬行、减速、找出平衡位置并保持等一系列要求完成的整套动作。

关键词:步进电机;电动小汽车;控制AbstractThe system is at the core MCU AT89S52, using infrared photoelectric sensor, angle sensors and their external circuit composed of measurement and control system, in the seesaw of a car traveling on the state of real-time campaign tracking, MCU right by the electric trolley in state funding to timely correct response output control and the corresponding instructions, the driver module after module completed by the Executive car crawling, slow down, find balance and maintain the position, and a series of actions required to complete the package.Keywords: step motor; electronic automobile; control一、系统方案论证本系统采用的是AT89S52实现电动小车的寻迹、爬行、找平衡、返回,并达到时间上的精确控制与显示。

跷跷板小车程序

跷跷板小车程序

#include<reg52.h>#include<stdio.h>#include<intrins.h>#include"delay.h"#include"PWM.h"#include"1602.h"sfr ADC_CONTR = 0xBC; //A/D 转换控制寄存器ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000sfr ADC_RES = 0xBD; //A/D 转换结果高8位ADCV.9 ADCV.8 ADCV.7 ADCV.6 ADCV.5 ADCV.4 ADCV.3 ADCV.2 0000,0000sfr ADC_RESL = 0xBE; //A/D 转换结果低2位sfr P1ASF = 0x9D; //P1 analog special functionsfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000//-----------------------------------sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ - DPS 0000,0000sbit key=P2^7;sbit dianji10=P1^1;sbit dianji11=P1^2;sbit dianji20=P1^5;sbit dianji21=P1^6;sbit XUNJIL=P2^0;sbit XUNJIR=P2^1;sbit XUNJI2L=P2^2;sbit XUNJI2R=P2^4;typedef unsigned char INT8U;typedef unsigned int INT16U;typedef unsigned long int INT32U;//---------------------------------------------------------------------//以下选择ADC 转换速率,只能选择其中一种// SPEED1 SPEED0 A/D转换所需时间#define AD_SPEED 0x60 // 0110,0000 1 1 70 个时钟周期转换一次,// CPU工作频率21MHz时A/D转换速度约300KHz//#define AD_SPEED 0x40 //0100,0000 1 0 140 个时钟周期转换一次//#define AD_SPEED 0x20 //0010,0000 0 1 280 个时钟周期转换一次//#define AD_SPEED 0x00 //0000,0000 0 0 420 个时钟周期转换一次//---------------------------------------------------------------------INT16U get_AD_result_10F(INT8U channel) //10位AD带均值滤波{INT8U AD_finished=0; //存储A/D 转换标志INT16U out=0;INT16U N=40;INT16U sum=0;INT8U m;ADC_RES = 0;ADC_RESL = 0;channel &= 0x07; //0000,0111 清0高5位ADC_CONTR |= channel; //选择A/D 当前通道_nop_();for(m=0;m<N;m++){ //均值滤波ADC_CONTR |= 0x08; //0000,1000 令ADCS = 1, 启动A/D转换,AD_finished = 0;while (AD_finished ==0 ) //等待A/D转换结束{AD_finished = (ADC_CONTR & 0x10); //0001,0000 测试A/D 转换结束否}ADC_CONTR &= 0xE7; //1110,0111 清ADC_FLAG 位, 关闭A/D转换,out= ADC_RES;out=(out<<2)+(ADC_RESL&0xfc);sum=sum+out;} //带均值滤波return (sum/N); //返回A/D 高8 位转换结果}//定义变量float Kp; //PID调节的比例常数float Ti; //PID调节的积分常数float T; //采样周期float Ki;float ek1; //偏差e[k-1]float ek2; //偏差e[k-2]float uk; //u[k]int uk1; //对uk四舍五入求整int adjust; //最终输出的调整量int ee;int bb,bb1,bb2;bit flag=1;INT16U ADC_result2;INT32U gg2;double a;float gabs(float a1){if(a1<0){a1=0-a1;}return a1;}int piadjust(float ek) //PI调节算法{if( gabs(ek)<2 ){adjust=0;}else{uk=Kp*(ek-ek1)+Ki*ek; //计算控制增量ek1=ek;uk1=(signed int)uk;if(uk>0){if(uk-uk1>=0.5){uk1=uk1+1;}}if(uk<0){if(uk1-uk>=0.5){uk1=uk1-1;}}adjust=uk1;}return adjust;}void INIT_TIME0(){TMOD=0x01;EA=1;ET0=1;TR0=1;TH0=(65535-5000)/256;TL0=(65535-5000)%256;}void main(){P1ASF = 0x01; //0000,0010, 将P1.0 置成模拟口//ADRJ = AUXR1^2:// 0: 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2位放在ADC_RESL 寄存器// 1: 10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器AUXR1 &= ~0x04; //0000,0100, 令ADRJ=0// AUXR1 |= 0x04; //0000,0100, 令ADRJ=1 ADC_CONTR = AD_SPEED;_nop_();ADC_CONTR |= 0x80; //1000,0000 打开A/D 转换电源P0=0x00;PWMINIT();// LCD_Init();delay_50ms(100);dianji10=1;dianji11=0;dianji20=1;dianji21=0;//INIT_TIME0();/******************************************************** ********///变量初始化,根据实际情况初始化Kp=8;// Ti=0.05;T=0.01;Ki=0;// Ki=KpT/Ti=0.8,微分系数Kd=KpTd/T=0.8,Td=0.0002,根据实验调得的结果确定这些参数ek1=0;ek2=0;uk=0;uk1=0;adjust=0;bb=150;INIT_TIME0();while(1) //循迹{if(flag==1){/*if(XUNJIL==0&&XUNJIR==1){delay_50us(5);if(XUNJIL==0&&XUNJIR==1)PWMDR(10,0);}if(XUNJIR==0&&XUNJIL==1){delay_50us(5);if(XUNJIR==0&&XUNJIL==1)PWMDR(0,10);}if(XUNJIR==0&&XUNJIL==0){delay_50us(5);if(XUNJIR==0&&XUNJIL==0)PWMDR(1,2);}if(XUNJIR==1&&XUNJIL==1){delay_50us(5);if(XUNJIR==1&&XUNJIL==1)PWMDR(25,25);}*/if(XUNJIL==0&&XUNJIR==1){PWMDR(10,0);}if(XUNJIR==0&&XUNJIL==1){PWMDR(0,10);}if(XUNJIR==0&&XUNJIL==0){PWMDR(1,2);if(XUNJIR==1&&XUNJIL==1){PWMDR(25,25);}}if(flag==0){// PWMDR(2,3);/*if(XUNJI2L==0&&XUNJI2R==1){//delay_50us(5);// if(XUNJI2L==0&&XUNJI2R==1)PWMDR(0,10);}if(XUNJI2R==0&&XUNJI2L==1){//delay_50us(5);// if(XUNJI2R==0&&XUNJI2L==1)PWMDR(10,2);}if(XUNJI2R==0&&XUNJI2L==0){//delay_50us(5);// if(XUNJI2R==0&&XUNJI2L==0)PWMDR(2,1);}if(XUNJI2R==1&&XUNJI2L==1){//delay_50us(5);// if(XUNJI2R==1&&XUNJI2L==1)PWMDR(25,25);}*/if(XUNJI2L==0&&XUNJI2R==1){PWMDR(0,10);}if(XUNJI2R==0&&XUNJI2L==1){PWMDR(10,0);}if(XUNJI2R==0&&XUNJI2L==0){PWMDR(2,1);if(XUNJI2R==1&&XUNJI2L==1){PWMDR(25,25);}}}}void time0() interrupt 1{TR0=0;TH0=(65535-10000)/256;TL0=(65535-10000)%256;ADC_result2 = get_AD_result_10F(0);//P1.0 为A/D 当前通道, 测量并发送结果gg2=(INT32U)((INT32U)ADC_result2*5000)/1024;if(gg2<500) gg2=500;a=(float)(gg2-500)*0.045; // 转换成角度/* a=a-90;bb=bb+piadjust(a);bb2=bb;if(bb2>255) bb2=255;if(bb2<0) bb2=0;CCAP0H = CCAP0L = bb2; //P1.3输出CCAP1H = CCAP1L = bb2; //P1.4输出*/if(a>95){d ianji10=1;dianji11=0;dianji20=1;dianji21=0;flag=0;}if(a<95&&a>85){d ianji10=0;dianji11=0;dianji20=0;dianji21=0;//flag=2;}if(a<85){dianji10=0;dianji11=1;dianji20=0;dianji21=1;flag=1;}TR0=1;}。

跷跷板小车制作

跷跷板小车制作

电动车跷跷板设计任务:设计并制作一个电动车跷跷板,在跷跷板起始端A一侧装有可移动的配重。

配重的位置可以在从始端开始的200mm~600mm范围内调整,调整步长不大于50mm;配重可拆卸。

电动车从起始端A出发,可以自动在跷跷板上行驶。

电动车跷跷板起始状态和平衡状态示意图分别如图1和图2所示。

设计思路:因为小车要在跷跷板上自动寻找平衡点所以要有一个平衡装置当小车倾斜时小车就会向前或后走的地方走而达到平衡。

因为翘翘板的宽度较小所以要小车按固定的直线行走,小车要时刻记时所以用电子显示装置计时。

基本设计(1)平衡部分因为小车在板上寻找平衡点所以要用到平衡装置有以下三个方案方案一:利用SCA100T传感器。

SCA100T优点:(1)双轴倾角传感器。

(2)测量范围0.5g或者1g。

(3)单极5伏供电,比例电压输出。

(4)长期稳定性非常好。

(5)高分辨率,低声,工作温度范围广。

缺点:灵敏度太高,价格昂贵,抗干扰能力差。

方案二:利用水银开关。

优点:(1)价格低,容易买到。

(2)制作方便,操控性好。

(3)工作范围广缺点:不稳定,水银液体不太容易控制。

方案三:利用旋转型可调电阻和铅坠。

优点:(1)价格低,容易组装。

(2)操控性好,灵敏度高。

(3)可以利用电阻的变化算出倾斜角。

缺点:有摩擦影响,受外界影响。

综上所述:经比较方案三比较好实验室中可以找到所用器材,可以通过电阻的变化算出倾角,价格较为便宜。

方案三的具体方法:首先将可变电阻的旋钮与铁杆连接起来,铁杆的另一端是较重的铅锤。

当小车的倾角变化时由于铅锤的重力作用在小车的带动下可变电阻的阻值产生变化,电压或电流发生变换传给单片机从而控制小车来找平衡点。

平衡装置原理图:(2)小车寻路装置:方案一启发:利用小车红外向寻路装置,可以让小车沿黑线在桥面上行走,当小车找到平衡点时小车自动停止,当小车到达桥的尽头是黑线消失小车停止倒行,这样可以防止小车一直沿直线行走能掉下桥。

方案二可以在小车两侧按上传感装置让小车不能掉下桥去。

2007电动车跷跷板

2007电动车跷跷板
直流电机具有很高的速度、调速平滑方便、调整范围广等优点,但是当低速运行时,输出力矩很小。在本题目中当小车处在平衡系统的平衡点附近时,小范围的移动和反馈变得十分重要,这很难用直流电机完成,而且直流电机在小角度转动的时候接近短路,大电流给驱动电路带来了很大负担。
方案三:直流减速电机
减速电机是一种带有减速齿轮的直流电机。因此它具有直流的优点,另外它在低速运行时也能够实现较大的力矩输出。
图8.程序流程图
五、测试结果及分析
测试仪器:数字万用表、游标高度计、秒表、卷尺、示波器,测试环境为室内。
1.测试步骤
1)在外界环境光变化比较缓和的情况下用数字滤波算法,测定反射物分别是白色和黑色表面的反射参数。
2)在舵机正常供电的情况下输入PWM信号确定与舵机转角的线性关系。
六、结束语
本次设计按照题目要求,采用模块化的硬件和软件设计方法,以及较合适的控制算法,成功地实现了小车自动平衡控制,以及自动方向导行功能,整个系统紧凑,完成了题目基本部分和发挥部分的全部要求。
2.倾角检测电路
角度传感器(SCA60C)的供电电压为5V,其模拟输出电压范围为0.5-4.5V,对应倾斜角为 ,其输出信号最高刷新频率为80Hz,该信号送至单片机内部10位高速A/D口。得到的A/D值可以经过运算转换为倾角度数。
3.红外循迹电路
红外发射管的安全工作电流为40mA左右,三极管的饱和压降为0.3V,红外发射管的正压向降为1.3V左右,因此最小限流电阻R=(5-1.3-0.3)/0.04=85(Ω),选用100Ω。红外发射电路如图7所示。红外管安装结构是小车前部为8对,一字型等距排开,主要起正向导向作用,后部安装两对,主要起后退导向作用。由于红外管对外界光比较敏感,因此硬件和软件都需采取一定的技术措施,主要采用脉冲调制方法去除外部干扰信号。将一定频率的PWM信号调制在红外发射管上,使得红外发射管按照PWM信号开关,在相邻两次的开和关状态对接收管上反馈电阻进行A/D采样,当PWM频率较高时,就可以将外部低频干扰滤除。由表1和表2可见,当差值以0.5V为阈值时,可以将黑线很好地判别出来。

电动车跷跷板 (电子设计大赛)

电动车跷跷板 (电子设计大赛)

电动车跷跷板摘要本系统以freescale公司提供的DG128芯片作为核心控制芯片,且通过在白色衬底上贴一条长2.5cm的黑线作为小车的引导线,让小车在跷跷板上能稳定的行驶。

为实现题目所要求的功能,用角度传感器作为跷跷板角度反馈量,通过一定的算法控制小车的速度使小车能够在跷跷板上找到平衡点。

小车的设计包括如下几个模块:摄像头采集,角度传感器安装与采集,驱动和转向的控制,速度检测,液晶显示模块等。

一、系统方案(一)方案的论证与比较根据大赛题目的设计要求,跷跷板的尺寸规格已经在题目中规定好,只需按照规定自制一个就可,所以此次设计的主要精力放在小车的设计上。

1、小车的引导由于可以在跷跷板上加引导措施,受2003年简易智能小车启发,在跷跷板表面铺白色衬底,在中间贴2.5cm的黑线,用传感器检测中间黑线的位置即可使小车在板上能稳定的行驶。

方案一:红外管,即用红外管检测黑线,通过黑白线之间的电压值的变化识别黑线,此方案电路较为简单,处理数据也较简单,但是红外管受环境光的影响比较大,及容易出现偏离轨道等错误。

方案二:摄像头,受环境光影响比红外管小很多,但在光照很强的情况下也会有很大的影响。

但是由于这是室内的比赛,所以光照很强的情况可以不用太多考虑。

另一方面是摄像头照射范围宽并且广,所以采集的信息比红外管多,对黑线的识别更为精确和有效。

选取方案二。

2、驱动电路的选择采用专门的小功率电机驱动芯片MC33886,可用单片机PWM端口给直接控制,但一片发热量比较大,所以采用4片33886并联驱动,首先驱动能力加强,而且在不加散热片反压时的发热量也很低。

4片也有一定的缺点:一是所占面积比较大,二是对电池电压的损耗比较大。

3、检测角度传感器的选择由于小车需要在加重的情况下在木板上保持平衡,需要采用木板所倾斜的角度作为回馈量,理想状态下当木板的倾斜角度为0时表示木板已经平衡。

方案一:电位器电阻值法,即在电位器上挂一个重物,重物由于重力总是垂直与水平面,当角度变化时则可以带动电位器的中心抽头变化,从而通过电阻值变化计算出角度的变化。

电动车跷跷板的设计与制作

电动车跷跷板的设计与制作

具有自平衡装置的电动车跷跷板摘要:电动车跷跷板是第八届全国大学生电子设计大赛的题目之一,本设计在四川赛区获得了一等奖,在全国竞赛中获得了二等奖。

本制作是一种能在跷跷板上行驶,并且可以在跷跷板上自动找到平衡点的电动车。

它以MC9S12DG128单片机作为控制核心,由驱动调速模块、路面检测模块、显示模块、电源模块等几部分组成。

本制作设计了平衡杆力矩补偿装置,使调节跷跷板的平衡精度更高。

关键词:MC9S12DG128单片机单轴倾角传感器SCA61T 摄像头 PWM调速Abstract: The electric car seesaw is one of eighth session of national university student electron design big game topics, this design has won the first award in the Sichuan contest area, has won the second prize in the national competition. This manufacture is one kind can go on the seesaw, and may find the balance point automatically on the seesaw the electric car.It by the MC9S12DG128 monolithic integrated circuit took the control core, by the actuation velocity modulation module, the road surface examination module, the demonstration module, the power source module and so on several parts is composed. This manufacture has designed the equalizing bar moment of force compensation system, causes the adjustment seesaw the balanced precision to be higher.Key word: MC9S12DG128 monolithic integrated circuit Single axle inclination angle sensor SCA61T camera PWM velocity modulation汽车作为人们交通的工具,随着计算机技术、通信技术、传感器技术等的发展,智能汽车的研究成为汽车发展的一大趋势。

电动车跷跷板说明书(1)

电动车跷跷板说明书(1)

电动车跷跷板设计并制作一个电动车跷跷板,在跷跷板起始端A一侧装有可移动的配重。

配重的位置可以在从始端开始的200mm~600mm范围内调整,调整步长不大于50mm;配重可拆卸。

电动车从起始端A出发,可以自动在跷跷板上行驶。

在不加配重的情况下,电动车完成以下动作:(1)电动车从起始端A出发,在30秒钟内行驶到中心点C附近。

(2)60秒钟之内,电动车在中心点C附近使跷跷板处于平衡状态,保持平衡5秒钟,给出明显的平衡指示。

(3)电动车从(2)中的平衡点出发,30秒钟内行驶到跷跷板末端B处(车头距跷跷板末端B不大于50mm)。

(4)电动车在B点停止5秒后,1分钟内倒退回起始端A,完成整个行程。

(5)在整个行驶过程中,电动车始终在跷跷板上,并分阶段实时显示电动车行驶所用的时间。

图10.9.1 起始状态示意图图10.9.2 平衡状态示意图【项目知识点和技能点】1、步进电机的应用和控制。

2、自动寻迹系统原理与应用。

3、角度传感器的原理和应用。

4、PTR8000无线发送与接收模块的应用。

5、AT89s52单片机模数转换的原理和应用。

8.2.2 总体设计方案以单片机AT89S52为主要控制芯片,查询按键的输入,传输各种参数的显示,两台电机的正反转和速度控制以及两台电机的协调运动,负责光电检测信号的接收和对信号的处理,从而能够确定小车轨迹,在B点停止和返回,并最终停止。

角度传感器把角度信号输给单片机,把检测到的角度和基准角度比较,从而确定翘翘板的平衡点。

寻找平衡点时主要是采用PID闭环控制算法,在小车行驶过程中每当小车翻过平衡点的时候都令小车向后退一段路程,直到小车再次翻过平衡点,小车再次向前行驶一段比前一段要小的距离直到翻过平衡点,最终找到平衡点。

系统框图如8-13所示,由如下几个模块组成控制模块——采用AT89S52单片机控制。

电机选择模块——采用四线两相步进电机。

显示模块——采用1602LCD液晶显示屏进行显示。

电动车跷跷板

电动车跷跷板

起 始端 A , 动 车 能分 别显 示 前 进 和 倒 退 有二 十 分 钟 左右 , 电 之后 必须 对 电池 充 电。 3 2 驱 动 电路 行 驶 在 1 5 钟 内 完成 。 .分
( 重物 体 位 置不 限制 ) 电动 车 从起 始端 A 配 , 出 发 , 驶 跷跷 板 的 全程 。 停 止 5秒 后 , 行 电 动车 再 从 跷跷 板 的 B端 倒退 回至 跷跷 板 的 起 始端 A , 动 车 能 分 别显 示 前 进 和 倒 退 电 退行 驶 在 2分 钟 内完 成 。
AT8 S5 2主 要 实 现 对 翘翘 板上 黑 线 9 的软 件 检测 和 纠 缠 , 储 并 显 示 小 车 在 不 存
采 用 具 H 桥 的 L 92 驱 动 芯 片 和 同阶 段保 完 成 任 务 所 用 的 时 间 , 3D 以及 在 平 位 施 密 特 反 向 器 构 成 了 驱 动 电路 , 电 路 两 位 编 码 器 对 不 同 操 作 任 务 进 行 编 码 , 使 更稳 定 。L 9 B的 内部 有 两个 可选 择 的导 “ 0 23 0 进 入 基本 要 求 1的控 制 系统 ,“ l 0 ”进
3 3 黑 线检 测模 块 .
探 测 路 面 黑 线的 原 理 是 :光 线 照射 到 分 程 序 部 分 没 有 做 的 很 好 , 致 小 车 不 能 导 不 同可 根 据 接受 到 的 反 射 光的 强 弱 判断 是
板 达 到 平衡 时 , 保持 时 间 不小 于 5秒 , 同时 路 面 并 反 射 , 于 黑 线和 自纸 的反 射 系 数 由
通通 道 分 别 控制 后 轮 电机正转 和 反 转两 种 入基 本要 求 2的控 制 系统 ,“ 0”进 入发 挥 l 状 态 。一 片 L2 93可 以 分 别控 制 两 个直 流 部 分 l 的控 制 系统 ,“ 1 I ”进 入 发挥 部分 2

【精品】电动车跷跷板设计几种方案汇总与对比

【精品】电动车跷跷板设计几种方案汇总与对比

电动车跷跷板系统方案设计、比较与论证实现方法:根据题目的基本要求,设计任务主要完成电动车在规定时间内自由行走并能具有保持平衡功能,同时对行程中的有关数据进行处理显示。

根据设计任务及要求,采用单片机作为核心控制器。

在白色跷跷板上铺设黑色引导线,在小车的前后各循迹线探测模块。

为完成相应功能,系统可以划分为以下几个基本模块:电动机驱动模块、寻迹线探测模块、平衡状态检测模块、信息显示模块、语音模块。

控制模块主控芯片的选择方案:采用89C52单片机方案:采用AT89C51系列单片机作为控制的核心。

51单片机按单纯的控制和数据处理是比较经济实惠的,但是功能单一,并且51单片机需要仿真器来实现软硬件调试,较为烦琐。

如果系统需要增加语音播报功能,还需外接语音芯片,实现较为复杂;而且本项目触及到A/D转换和PWM控制,如果要具备这两个功能必须要有专用的A/D芯片和PWM控制电路,这无疑是提高了成本。

方案:使用89S51单片机。

价格便宜、程序资源丰富,控制简单,技术比较成熟,但运算速度慢、片内资源少、存储器容量小,难以存储大体积程序和实现复杂的算法。

不能直接进行数据采集,接口电路比较复杂。

方案:使用AT89S52单片机,AT89S52单片机采用CHMOS工艺及高密度、非易失性存储技术制造,内部包括1个8位CPU,1个片内振荡器及时钟电路,3个16位定时计数器,4个8位并行I/O口,8个中断源,1个可编程全双工串行口,8kB 可插除FLASH和256B的RAM,且内置看门狗电路,一旦程序跑飞则复位系统[2]。

因此,设计中采用8位AT89S52单片机负责系统的控制与协调工作,同时它还不断处理红外对管传感器送来的地面标志信号,这些信号主要控制小车的加速、减速、限速、刹车、倒车等状态。

此外,在系统设计中当利用片内的定时器作为小车行驶计时,并为LED驱动集成电路提供时钟和数据。

方案:采用凌阳16位单片机SPCE061A(30.21)作为控制的核心。

2008电动车跷跷板设计讲课用01

2008电动车跷跷板设计讲课用01

电动车跷跷板自动平衡控制系统设计1 方案设计按照任务书给定的功能要求,我们设计的电动车跷跷板自动平衡控制系统结构框图如图1-1所示,被控对象由电动小车与跷跷板组成。

通过安装在小车上的角度传感器测量小车平衡位置,平衡状态下传感器输出角度值作为系统给定值,实时状态下的传感器输出作为系统输出值。

1. 1 控制原理在电动车运行中,实时采集输出值,与给定值比较,不平衡时,根据偏差通过控制算法计算出输出,作用于电动车驱动电路,使车前后运动,最终达到平衡。

电动车在行走与寻找平衡的过程中,需要自动寻迹,这个过程也是一个反馈控制过程,其结构图如图1-2所示。

该系统的输入即给定轨迹是电动车正常行驶对应的位置信号,系统的输出即实际轨迹是实时测量获得的电动车位置信号。

本设计采用五组光电对管,产生五个位置信号分别用于前进与后退时轨迹的测量,同时也用于车位测量。

根据信号的组合判断电动车运行状态及应该调整的方向,控制电动车转向从而自动寻迹,或者根据车位控制电动车行走与停车。

根据上述思想,设计了自动控制系统的具体电路,系统结构图如图1-3所示。

2 系统硬件设计与实现2.1 单片机及其扩展电路按照性能价格比高的原则,选择8位单片机PIC16F877A 作为系统的控制核心,在此基础上根据系统要求设计了单片机扩展电路。

主要包括时间显示、平衡状态指示及其输入输出接口。

PIC 系列单片机指令系统精练,它可以实现在线调试和在线编程。

PIC 单片机内集成了上电复位电路、I/O 引脚上拉电路、看门狗定时器等,对于本设计来讲,利用其片内集成的10位A/D 电路,可以最大程度地减少外接器件。

2.2 电机驱动模块的电路设 计与实现本系统电动车驱动使用直流电动机,采用H 型驱动电路,电压控制采用PWM 方式以方便调速。

这种电路由于工作在管子的饱和或截止状态下,效率非常高,有利于节省能源。

该电路电子开关的速度很快,稳定性也很强,可以简单的实现转向控制。

F题 电动机跷跷板

F题   电动机跷跷板

F 题 电动机跷跷板一、任 务设计并制作一个电动机跷跷板,在跷跷板起始端A 一侧装有可移动的配重。

配重的位置可以在从时端开始的200~600mm 范围内调整,调整步长不大于50mm ;配重可拆卸。

电动车从起始端A 出发,可以自动在跷跷板上行驶。

电动车跷跷板起始状态和平衡状态示意图分别如图F-1和图F-2所示。

400m m200m mACB配重物体1600m m图F-1 起始状态示意图800mmdA70mmdB图F-2 平衡状态示意图二、要 求1.基本要求在不加配重的情况下,电动车完成以下运动: ①电动车从起始端A 出发,在30s 内行驶到中心点附近。

②60s 之内,电动车在中心点附近使跷跷板处于平衡状态保持5s ,并给出明显的平衡提示。

③电动车从 中的平衡点出发,30s 内行驶到跷跷板末端B 处(车头距跷跷板末端B 不大于50mm )。

④电动车在B 点停止5s 后,1min 内倒退回起始端A,完成整个行程。

⑤在整个行驶过程中电动车始终在跷跷板上,并分阶段实时显示电动车行驶所用的时间。

2.发挥部分将配重固定在可调整范围内任一指定位置,电动车完成以下运动: ①将电动车放置在地面距离跷跷板起始端A 点300 mm 以外、90º扇形区域内某一指定位置(车头朝向跷跷板),电动车能够自动驶上跷跷板,如图F-3所示。

300mmA B90º电动车300mm图F-3 自动驶上跷跷板示意图②电动车在跷跷板上取得平衡,给出明显的平衡提示,保持平衡5s 以上。

③将另一块质量为电动车质量10%~20%的块状配重放置在A 至C 指定的位置,电动车能够重新取得平衡,给出明显的平衡提示保持平衡5s 以上。

④电动车在3min 之内完成①~③全过程。

⑤其他。

三、 说 明①跷跷板长1600mm 、宽300mm ,为便于携带也可以将跷跷板制成折叠形式。

②跷跷板中心固定在直径不大于50mm 的半圆轴上,轴两端支撑在支架上,并保证与支架圆滑接触,能灵活转动。

07年国赛电动车上跷跷板程序源码.c

07年国赛电动车上跷跷板程序源码.c

/***************************************************** This program was produced by theCodeWizardAVR V2.03.4 StandardAutomatic Program Generator?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.Project :Version :Date : 2009/7/25Author :Company :Comments:Chip type : ATmega16LProgram type : ApplicationClock frequency : 14.745600 MHzMemory model : SmallExternal RAM size : 0Data Stack size : 256*****************************************************/ #include <mega16.h>#include <delay.h>// USART控制和状态寄存器的标志位定义#define RXC 7 // UCSRA位定义#define TXC 6#define UDRE 5#define FE 4#define DOR 3#define PE 2#define U2X 1#define MPCM 0#define RXCIE 7 // UCSRB位定义#define TXCIE 6#define UDRIE 5#define RXEN 4#define TXEN 3#define UCSZ2 2#define RXB8 1#define TXB8 0#define URSEL 7 // UCSRC位定义#define UMSEL 6#define UPM1 5#define UPM0 4#define USBS 3#define UCSZ1 2#define UCSZ0 1#define UCPOL 0#define FRAMING_ERROR (1<<FE)#define PARITY_ERROR (1<<PE)#define DATA_OVERRUN (1<<DOR)#define DATA_REGISTER_EMPTY (1<<UDRE)#define MOTOR_L1 PORTB.0 //电机#define MOTOR_L2 PORTB.1#define MOTOR_R1 PORTB.2#define MOTOR_R2 PORTB.3#define BW_LEFT PINA.0 //黑白线#define BW_RIGHT PINA.1#define BUZZER PORTA.3 //蜂鸣器#define NULL 0x00#define LEFT 0x01#define RIGHT 0x02#define BAL_START 0x03#define BAL 0x04#define BAL_OK 0x05#define GET_B 0x06#define B_OK 0x07#define A_OK 0x08#define MODE_B 0x09#define MODE_P 0x0A#define BAL_AGAIN 0x0B#define FULL 0xFFunsigned char tran = 5; //USART数据bit receive_ok = 0;bit dir = 0;bit mode2 = 0;unsigned char delay_dir = 0;interrupt [USART_RXC] void usart_rx_isr(void) // USART接收中断服务{unsigned char status,data;status = UCSRA;data = UDR;if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {tran = data;receive_ok = 1;}}void USART_Transmit(unsigned char data){while (!(UCSRA & DATA_REGISTER_EMPTY)); // 等待发送寄存器空UDR = data; // 发送数据}void motor_direct(unsigned char direct) //电机换向{if(direct == 0){MOTOR_L1 = 0;MOTOR_L2 = 1;MOTOR_R1 = 0;MOTOR_R2 = 1;}if(direct == 1){MOTOR_L1 = 1;MOTOR_L2 = 0;MOTOR_R1 = 1;MOTOR_R2 = 0;}}void motor_start(void) //电机启动{if(dir == 0){MOTOR_L1 = 0;MOTOR_L2 = 1;MOTOR_R1 = 0;MOTOR_R2 = 1;if(dir == 1){MOTOR_L1 = 1;MOTOR_L2 = 0;MOTOR_R1 = 1;MOTOR_R2 = 0;}}void motor_stop(void) //电机停止{MOTOR_L1 = 1;MOTOR_L2 = 1;MOTOR_R1 = 1;MOTOR_R2 = 1;}void motor_jerk(unsigned int time ,unsigned char direct_stop){motor_direct(direct_stop);delay_ms(time);motor_stop();}void buzzer_voice(void){BUZZER = 1;delay_ms(500);BUZZER = 0;}void mode_pro(void){unsigned char cache = 0;bit once = 0,balance_again = 0;//buzzer_voice();motor_start(); //电机开启delay_ms(500);motor_stop();while(1)if(BW_RIGHT == 1 && BW_LEFT == 0) {OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0xaf;OCR1BL=0xFF;delay_ms(300);motor_jerk(150,0);OCR1BH=0xef;OCR1BL=0xFF;OCR1AH=0x00;OCR1AL=0xFF;delay_ms(300);motor_jerk(200,1);delay_dir = 1;}else if(BW_RIGHT == 0 && BW_LEFT == 1) {OCR1BH=0xef;OCR1BL=0xFF;OCR1AH=0xaf;OCR1AL=0xFF;delay_ms(300);motor_jerk(150,0);OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0x00;OCR1BL=0xFF;delay_ms(300);motor_jerk(200,1);delay_dir = 2;}else if(BW_RIGHT == 0 && BW_LEFT == 0) {OCR1AH=0xc0;OCR1AL=0xFF;OCR1BH=0xf0;OCR1BL=0xFF;motor_jerk(30,0);}else if(BW_RIGHT == 1 && BW_LEFT == 1) {/*if(delay_dir == 1){OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0xaf;OCR1BL=0xFF;delay_ms(300);motor_jerk(150,0);OCR1BH=0xef;OCR1BL=0xFF;OCR1AH=0x00;OCR1AL=0xFF;delay_ms(300);motor_jerk(200,1);}else if(delay_dir == 2){OCR1BH=0xef;OCR1BL=0xFF;OCR1AH=0xaf;OCR1AL=0xFF;delay_ms(300);motor_jerk(150,0);OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0x00;OCR1BL=0xFF;delay_ms(300);motor_jerk(200,1);}*/break;}delay_ms(400);};OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0xef;OCR1BL=0xFF;buzzer_voice();motor_start(); //电机开启delay_ms(1000);motor_stop();again:delay_ms(1000);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);while (1) //找平衡{cache = tran;if(receive_ok == 1 && cache == LEFT){motor_jerk(30,1);delay_ms(800);}else if(receive_ok == 1 && cache == RIGHT) {motor_jerk(30,0);delay_ms(800);}else{motor_stop();if(cache == BAL && once == 0){buzzer_voice();once = 1;}if(cache == BAL_OK){buzzer_voice();break;}}}if(balance_again == 0){while(1){if(tran == BAL_AGAIN)break;delay_ms(100);}balance_again = 1;once = 0;receive_ok = 0;goto again;}motor_jerk(150,0);while (1){if(BW_LEFT == 1 && BW_RIGHT == 1){USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);break;}else{motor_jerk(30,0);delay_ms(800);}}while (1){if(tran == B_OK)break;};motor_jerk(1200,1);while (1){if(BW_LEFT == 1 && BW_RIGHT == 1){motor_jerk(30,1);delay_ms(500);motor_jerk(30,1);delay_ms(500);motor_jerk(30,1);break;}else{motor_jerk(40,1);delay_ms(800);}};USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);while (1){};}void main(void){unsigned char cache = 0;bit once = 0;//unsigned char middle,balance,B,A;//unsigned char time_h[10] = {0},time_m[10] = {0},time_s[10] = {0};//unsigned char *mid = ""// Input/Output Ports initialization// Port A initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In// State7=T State6=T State5=T State4=T State3=0 State2=P State1=P State0=P PORTA=0x07;DDRA=0x08;// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB = 0x00;DDRB=0x0F;// Port C initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00;DDRC=0x00;// Port D initialization// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=1 State5=0 State4=0 State3=T State2=T State1=T State0=T PORTD=0x40;DDRD=0x70;// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 14.400 kHz// Mode: Normal top=FFh// OC0 output: DisconnectedTCCR0=0x00;TCNT0=0x00;OCR0=0x00;// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: 14745.600 kHz// Mode: Fast PWM top=ICR1// OC1A output: Non-Inv.// OC1B output: Non-Inv.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: Off// Compare B Match Interrupt: OffTCCR1A=0xA2;TCCR1B=0x19;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0xFF;ICR1L=0xFF;OCR1AH=0xef;OCR1AL=0xFF;OCR1BH=0xef;OCR1BL=0xFF;// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: Timer 2 Stopped// Mode: Normal top=FFh// OC2 output: DisconnectedASSR=0x00;TCCR2=0x00;TCNT2=0x00;OCR2=0x00;// USART initialization// Communication Parameters: 8 Data, 1 Stop, No Parity// USART Receiver: On// USART Transmitter: On// USART Mode: Asynchronous// USART Baud Rate: 19200UCSRA=0x00;UCSRB=0x98;UCSRC=0x86;UBRRH=0x00;UBRRL=0x2F;// External Interrupt(s) initialization// INT0: Off// INT1: Off// INT2: OffMCUCR=0x00;MCUCSR=0x00;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x01;// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80;SFIOR=0x00;// Global enable interrupts#asm("sei")if(BW_LEFT == 1 && BW_RIGHT == 1){mode2 = 1;USART_Transmit(MODE_P);USART_Transmit(MODE_P);delay_ms(400);USART_Transmit(MODE_P);USART_Transmit(MODE_P);delay_ms(400);USART_Transmit(MODE_P);mode_pro();}USART_Transmit(MODE_B);USART_Transmit(MODE_B);delay_ms(400);USART_Transmit(MODE_B);USART_Transmit(MODE_B);delay_ms(400);USART_Transmit(MODE_B);buzzer_voice();motor_start(); //电机开启delay_ms(1000);motor_stop();delay_ms(1000);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);USART_Transmit(BAL_START);while (1) //找平衡{cache = tran;if(receive_ok == 1 && cache == LEFT){motor_jerk(30,1);delay_ms(800);}else if(receive_ok == 1 && cache == RIGHT)motor_jerk(30,0);delay_ms(800);}else{motor_stop();if(cache == BAL && once == 0){buzzer_voice();once = 1;}if(cache == BAL_OK){buzzer_voice();break;}}}motor_jerk(200,0);while (1){if(BW_LEFT == 1 && BW_RIGHT == 1){USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);USART_Transmit(GET_B);break;}else{motor_jerk(30,0);delay_ms(800);}}while (1){if(tran == B_OK)break;motor_jerk(1200,1);while (1){if(BW_LEFT == 1 && BW_RIGHT == 1){motor_jerk(30,1);delay_ms(500);motor_jerk(30,1);delay_ms(500);motor_jerk(30,1);break;}else{motor_jerk(40,1);delay_ms(800);}};USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);USART_Transmit(A_OK);while (1){};}。

基于STM32的电动车跷跷板系统设计

基于STM32的电动车跷跷板系统设计

基于STM32的电动车跷跷板系统设计摘要:介绍电动车跷跷板系统的设计与实现。

该系统包括单片机系统电路、寻迹检测电路、平衡检测电路、步进电机驱动电路、数码显示电路等。

在系统中,以STM32单片机为电动小车控制核心,使用反射式红外发射接收器来检测轨迹,步进电机作为动力源实现小车前进后退和转向控制,用2个水银开关控制完成平衡状态的检测,用数码管分阶段实时显示电动车行驶所用时间。

3次实验数据表明,这里所提出的平衡检测方案是有效可行的。

关键词:寻迹检测电路;步进电机;跷跷板系统;平衡检测电路。

一、引言全国大学生电子设计大赛的F题目是“电动车跷跷板”;题口要求设计并制作一个电动车跷跷板,使得电动小车从图1所示跷跷板起始端A出发在30 s内到达中心点C 并保持平衡5 s,之后在30 s内到达跷跷板末端B并停留5 s,最后在1 min内退回到起始端Ao在整个行驶过程中,电动车始终在跷跷板上,并分阶段实时显示电动车行驶所用的时间。

所要求平衡的定义为A, B两端与地面的距离差d =dA - dB不大于40 mm。

图1 电动车跷跷板示意图二、系统方案设计在系统设计中,根据竞赛要求电动小车设计车体长为20cm,宽为15cm,电动小车采用四轮驱动、调节驱动轮的快慢进行转向的方案,这种结构使得小车在运动时比较平稳。

STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核。

按性能分成两个不同的系列:STM32F103 “增强型”系列和STM32F101 “基本型”系列。

增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品:基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性能,是16位产品用户的最佳选择。

两个系列都内置32K到128K的闪存,不同的是SRAM的最大容量和外设接口的组合。

时钟频率72MHz时,从闪存执行代码,STM32 功耗36mA,是32位市场上功耗最低的产品,相当于0. 5mA/MHzo STM32芯片如图2。

电动车平衡跷跷板+ADXL345程序

电动车平衡跷跷板+ADXL345程序
SDA = 0; //拉低数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 1; //产生上升沿
SCL = 1; //拉高时钟线
Delay5us(); //延时
CY = SDA; //读应答信号
SCL = 0; //拉低时钟线
//ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
typedef unsigned char BYTE;
typedef unsigned short WORD;
BYTE BUF[8]; //接收数据缓存区
}
/**************************************
延时5毫秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5ms()
void ADXL345_SendByte(BYTE dat)
{
; i++) //8位计数器
{
dat <<= 1; //移出数据的最高位
SDA = CY; //送数据口
Delay5us(); //延时
dat |= SDA; //读数据
SCL = 0; //拉低时钟线
Delay5us(); //延时
uchar ge,shi,bai,qian,wan,dian; //显示变量
int dis_data; //变量
int data_xyz[3];

电动小汽(跷跷板)源程序

电动小汽(跷跷板)源程序

该小车的功能有:寻迹,寻线(点),寻找平衡,声光报警,显示(时钟,分段,倒计时),小车前进、倒退、停止等待5秒。

源汇编程序如下:(供大家参考,还未修改);================================== 小车程序====================== ===;-------------------------------- 蔡伟------------2007.9.20--------------ORG 0000HAJMP MAINORG 000BHAJMP TIMEORG 001BHAJMP MAI_CHONGMAIN: MOV 22H,#01HMOV 23H,#0AHMOV 24H,#00HMOV 25H,#04HMOV 28H,#01HMOV 33H,#0FFHMOV 34H,#0FFHMOV 40H,#01HMOV 44H,#01HCLR AMOV 30H,AMOV 31H,AMOV 32H,AMOV 3BH,#05HDENG_DAI: LCALL DEEYDJNZ 3BH,DENG_DAIMOV TMOD,#11HMOV 20H,#14HMOV TH0,#3CHMOV TL0,#0B0HMOV TH1,#3CHMOV TH1,#0B0HSETB ET1SETB ET0SETB TR1SETB TR0SETB EASTART: LCALL SU_DULCALL XUN_XIANLCALL XUN_TIESJMP START;==========================================时间程序======================== =============TIME: PUSH PSWPUSH ACCMOV TH0,#3CHMOV TL0,#0B0HDJNZ 20H,RETUNTMOV 20H,#14HMOV A,#01HADD A,32HDA AMOV 32H,ACJNE A,#60H,RETUNTMOV 32H,#00HMOV A,#01HADD A,31HDA AMOV 31H,ACJNE A,#60H,RETUNTMOV 31H,#00HMOV A,#01HADD A,30HDA AMOV 30H,ACJNE A,#24H,RETUNTMOV 30H,#00HRETUNT: POP ACCPOP PSWRETI;=============================================脉冲产生程序================= ===============MAI_CHONG: PUSH PSWPUSH ACCMOV TH1,#3CHMOV TL1,#0B0HMOV A,22HJB ACC.1,QIAN_DABUJB ACC.2,HOU_DABUJB ACC.3,QIAN_XIAOBUJB ACC.4,HOU_XIAOBUJB ACC.5,W1RETU: POP ACCPOP PSWRETIW1: LJMP GUAI_ZHUOW2: LJMP GUAI_YOU QIAN_DABU: DJNZ 23H,RETU MOV A,24HCPL AMOV 24H,AJNZ ZHENG_MAIMOV TH1,#3CHMOV TL1,#0B0HMOV 23H,#0AHAA: SETB P3.0CLR P3.1SETB P3.2CLR P3.3SJMP RETUZHENG_MAI: MOV TH1,#3CH MOV TL1,#0B0HMOV 23H,#0AHBB: CLR P3.0CLR P3.1CLR P3.2CLR P3.3SJMP RETUHOU_DABU: DJNZ 23H,RETU MOV A,24HCPL AMOV 24H,AJNZ ZHENG_MAIMOV TH1,#3CHMOV TL1,#0B0HMOV 23H,#0AHAA1: SETB P3.1CLR P3.0SETB P3.3CLR P3.2SJMP RETUQIAN_XIAOBU:DJNZ 25H,RETU MOV 26H,#04HMOV TH1,#3CHMOV TL1,#0B0HMOV 25H,#04HSJMP AACC: MOV 25H,#04HSJMP BBRETUU: POP ACCPOP PSWRETIHOU_XIAOBU:DJNZ 25H,RETUU MOV 26H,#04HMOV TH1,#3CHMOV TL1,#0B0HDJNZ 26H,DD1DD1: MOV 25H,#04HSJMP BBGUAI_ZHUO: DJNZ 25H,RETUU MOV A,24HCPL AMOV 24H,AJNZ AA2MOV TH1,#3CHMOV TL1,#0B0HMOV 25H,#04HLJMP AAAA2: MOV TH1,#3CHMOV TL1,#0B0HMOV 25H,#04HCLR P3.0CLR P3.1SETB P3.2CLR P3.3LJMP RETUGUAI_YOU: DJNZ 25H,RETUU MOV A,24HCPL AMOV 24H,AJNZ AA3MOV TH1,#3CHMOV TL1,#0B0HMOV 25H,#04HLJMP AAAA3: MOV TH1,#3CHMOV TL1,#0B0HMOV 25H,#04HSETB P3.0CLR P3.1CLR P3.2CLR P3.3LJMP RETU;==========================================选择速度程序==================== =============SU_DU: MOV A,22HJB ACC.0,QIAN_KUAIJB ACC.7,HOU_KUAIRETQIAN_KUAI: SETB P3.0CLR P3.1SETB P3.2CLR P3.3RETHOU_KUAI: SETB P3.1CLR P3.0SETB P3.3CLR P3.2RET;============================================寻线程序===================== ===========XUN_XIAN: MOV A,40HJZ GGMOV 41H,22HMOV 40H,#00HGG: MOV A,P1JB ACC.0,FFJB ACC.1,HHMOV 22H,41HMOV 41H,#01HRETFF: MOV 22H,#20HSETB P0.4LCALL DELLYCLR P0.4RETHH: MOV 22H,#40HSETB P0.5LCALL DELLYCLR P0.5RET;==========================================寻铁程序======================== =============XUN_TIE: MOV 43H,42HLCALL DELLYMOV A,P1MOV 42H,AMOV A,40HJZ IIMOV 40H,#00HHEE: RETII: MOV A,43HJB ACC.2,HEEMOV A,42HJNB ACC.2,HEEMOV A,28HRL AMOV 28H,AJB ACC.1,KY1JB ACC.2,KY2JB ACC.3,KY3JB ACC.4,KY4JB ACC.5,KY5JB ACC.6,KY6RETKY1: RETKY2: MOV 22H,#01HMOV 33H,32HME: MOV A,P1LCALL DEEYJB ACC.3,YY2JNB ACC.4,YY3MOV 22H,#08HMOV 44H,#01HRETYY2: JB ACC.4,YY3MOV 22H,#10HMOV 44H,#01HRETYY3: LCALL DEEYMOV A,44HRL AMOV 44H,ACJNE A,#08H,MEMOV A,32HMOV 33H,AMOV 44H,#01HSETB P0.6LCALL DEEYCLR P0.6LCALL FIVEMOV 33H,#0FFHMOV 39H,32HMOV 22H,#01HRETKY3: MOV 22H,#00HMOV A,32HSUBB A,39MOV 33H,ACLR P3.0CLR P3.1CLR P3.2CLR P3.3SETB P0.6LCALL DELLYLCALL FIVEMOV 33H,#0FFHMOV 22H,#80HRETKY4: RETKY5: RETKY6: MOV 22H,#00HCLR P3.0CLR P3.1CLR P3.2CLR P3.3MOV 36H,31HMOV 37H,32HHERE: MOV 31H,36HMOV 32H,37HSJMP HERE;=======================================显示程序=========================== =============SHOW: MOV R0,#3AHMOV R1,#34HMOV R2,#07HMOV 5BH,#04HMOV @R0,AMOV A,R2SWAP AXCHD A,@R0MOV P2,ALCALL DELLYDEC R2MOV A,R2XCHD A,@R0MOV A,@R0SWAP AMOV P2,ALCALL DELLYDEC R2DEC R1DJNZ 5BH,LP0RETDELLY: MOV 5AH,#04HDL: MOV R6,#0FFHDL1: DJNZ R6,DL1DJNZ 5AH,DLRET;===========================================停车5秒,并显示程序============= =============FIVE: MOV 22H,#00HCLR P3.0CLR P3.1CLR P3.2CLR P3.3MOV 38H,#05HTTT0: MOV 34H,#00HINC 34HMOV R4,#7DHTTT1: LCALL SHOWDJNZ R4,TTT1DJNZ 38H,TTT0MOV 34H,#0FFHRETDEEY: MOV R5,#3DHEEY: LCALL SHOWDJNZ R5,EEYRETEND《测电机转速》单片机原代码下载 2007-11-29 18:34 阅读7 评论0字号:大中小在校期间,做了一个测速机,该测速机通过一个光敏传感器当电机每转一周,单片机记数值加一,同过每半秒中断记数到的电机转动的周数,在利用最近4秒采集的数进行加权平均算法,计算出电机的转数并显示。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

我自己写的电动车跷跷板程序,做了一个1602菜单(只用了3个键哟!),使用步进电机,采用折半查找法寻找平衡点,最小步进达到1mm,还有很多其他功能,自己用51单片机试试看,这个是源程序,文库里还有个报告,加上一句我用的是倾角传感器,用AD采样算倾角。

#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define Xiaodou 50 //消抖时间#define OneCircle 512//OneCircle次循环为360度#define LCircle 23//轮子转一圈为LCircle cm#define FirstJour 256//找重心第一步#define SAOMIAO 600//延迟600ms测一次角度#define QueDing 700//平衡确定延时#define UpAngle 0x82//上限角度,大于上限角表示向前翘起,2.56V#define DownAngle 0x7e//下限角度,小于下限角表示向后翘起,2.45Vsbit KeyEnter=P3^2;//调整确定键sbit KeyUp=P3^3;//上方向键sbit KeyRight=P3^4;//右方向键sbit LCDRs=P3^0;//液晶的命令数据端sbit LCDEn=P3^1;//液晶的使能端sbit ADST=P3^5;//AD0809的转换启动信号端STsbit ADEOC=P3^6;//AD0809的转换结束信号,高电平表示转换结束sbit ADCLK=P3^7;//AD0809的时钟为500KHzsbit FLLight=P1^4;//前左灯,低电平发光sbit FRLight=P1^5;//前右灯,低电平发光sbit BLLight=P1^6;//后左灯,低电平发光sbit BRLight=P1^7;//后右灯,低电平发光uchar timecount=0;uint count[4]={0,0,0,0};//控制时间,4个过程的时间uint journey[4]={60,65,55,115};//设置行程uchar speed=3;//速度参量uchar step=0;//步骤游标uchar protype[4]={0,2,0,1};//每个步骤指令uchar CharDisp[3];//用于显示字符uchar code F_Rotation[]={0xc9,0xc1,0xc3,0xc2,0xc6,0xc4,0xcc,0xc8};//正转表格,前灯亮uchar code B_Rotation[]={0x38,0x3c,0x34,0x36,0x32,0x33,0x31,0x39};//反转表格,后灯亮void Delay(uint x,uint y)//x=1,y=110每执行一次大概为1ms{for(;x>0;x--)for(y=110;y>0;y--);}void WriteCommond(uchar com)//给液晶写入指令,com为16进制{LCDRs=0;P0=com;//液晶的数据端口Delay(5,110);LCDEn=1;Delay(5,110);LCDEn=0;}void WriteData(uchar date)//给液晶写入字符,com为16进制{LCDRs=1;P0=date;//液晶的数据端口Delay(5,110);LCDEn=1;Delay(5,110);LCDEn=0;}void WriteString(uchar * string)//写入字符串{for(;*string;string++)WriteData(*string);}void DispTimeS(uint times,uchar address)//显示时间或者距离{uchar i=0;CharDisp[0]=times/100;CharDisp[1]=times%100/10;CharDisp[2]=times%10;WriteCommond(address);for(;i<=2;i++){WriteData(CharDisp[i]+'0');}}void RunXCircle(uchar drec,uint num)//轮子跑num圈,drec为0向前,为1向后{uchar i;uint j;while(num--){j=OneCircle;while(j--){for(i=0;i<8;i++) //4相{if(!drec)P1=F_Rotation[i]; //输出对应的相,可以自行换成反转表格elseP1=B_Rotation[i];Delay(speed,110); //改变这个参数可以调整电机转速}}}P1=0xf0;//停止行走,灯熄灭}void RunNCircle(uchar drec,uint num)//轮子转num个最小单位,drec为1向前,为0向后{uchar i;//num*=OneCircle/LCircle;while(num--){for(i=0;i<8;i++) //4相{if(!drec)P1=F_Rotation[i]; //输出对应的相,可以自行换成反转表格elseP1=B_Rotation[i];Delay(speed,110); //改变这个参数可以调整电机转速}}P1=0xf0;//停止行走,灯熄灭}uchar DeltFind()//返回指为2表示平衡了,为0需要向前走,为1需要向后走{uchar angle,result=2;ADST=0;ADST=1;ADST=0;//启动AD0809转换while(!ADEOC);//等待AD0809转换结束angle=P2;//读取转化后的数据if(angle>UpAngle) result=0;//小车向前翘起,需要向前走else if(angle<DownAngle) result=1;//小车向后翘起,需要向后走else result=2;//小车平衡return result;}void RunFwodBak(uchar drec,uchar jour)//drec为方向,0向前,1向后,jour为路程,单位是cm {RunXCircle(drec,jour/LCircle);//先跑完整圈RunNCircle(drec,(jour%LCircle)*OneCircle/LCircle);//再跑半圈}void RunFind(){uchar delt=0,flag=0;uint jour=FirstJour;TR1=1;//开时钟让AD工作for(delt=DeltFind();;delt=DeltFind()){if(delt==2){Delay(QueDing,110);delt=DeltFind();if(delt==2){WriteCommond(0x86);WriteString("balanced!!");Delay(5000,110);break;}}if(delt!=flag) jour/=2;if(!jour){WriteCommond(0x86);WriteString("Failed");Delay(3000,110);break;}RunNCircle(delt,jour);flag=delt;Delay(SAOMIAO,110);}TR1=0;//关时钟}void WindowMain()//输出主界面{WriteCommond(0x81);WriteString("SET");WriteCommond(0x8c);WriteString("VIEW");WriteCommond(0xc1);WriteString("RUN");}void WindowSet()//输出设置界面{WriteCommond(0x81);WriteString("P1");WriteCommond(0x87);WriteString("P2");WriteCommond(0x8c);WriteString("P3");WriteCommond(0xc1);WriteString("P4");WriteCommond(0xc5);WriteString("SPEED");WriteCommond(0xcc);WriteString("EXIT");}void WindowFunction()//输出功能界面{WriteCommond(0x81);WriteString("FOWORD");WriteCommond(0x8c);WriteString("BACK");WriteCommond(0xc1);WriteString("FIND");}void WindowParamet()//输出参数设置界面{WriteCommond(0x80);WriteString("S:");WriteCommond(0x85);WriteString("CM");}void WindowRun()//输出运行时界面{WriteCommond(0x80);WriteData('P');WriteCommond(0xc0);WriteString("AL:");WriteCommond(0xc6);WriteData('s');WriteCommond(0xc8);WriteString("SIG:");WriteCommond(0xcf);WriteData('s');}void WindowView()//输出查看界面{WriteCommond(0x80);WriteString("P1:");WriteCommond(0x89);WriteString("P2:");WriteCommond(0xc0);WriteString("P3:");WriteCommond(0xc9);WriteString("P4:");}void WindowSpeed(){WriteCommond(0x80);WriteString("SPEED STAGE:");}void MenuSpeed(){WriteCommond(0x0e);//显示光标WindowSpeed();WriteCommond(0xc0);WriteData(speed-2+'0');WriteCommond(0xc0);while(1){if(!KeyUp){Delay(Xiaodou,110);if(!KeyUp){while(!KeyUp){}speed++;if(speed>11) speed=3;WriteCommond(0xc0);WriteData(speed-2+'0');WriteCommond(0xc0);}}if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}break;}}}}MenuParamet(uchar process){uchar cursor=0;WriteCommond(0x0e);//显示光标WindowParamet();DispTimeS(journey[process],0x82);while(1){if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}break;}}if(!KeyRight){Delay(Xiaodou,110);if(!KeyRight){while(!KeyRight){}cursor++;cursor%=3;}}if(!KeyUp){Delay(Xiaodou,110);if(!KeyUp){while(!KeyUp){}CharDisp[cursor]++;CharDisp[cursor]%=10;journey[process]=CharDisp[0]*100+CharDisp[1]*10+CharDisp[2];DispTimeS(journey[process],0x82);}}WriteCommond(0x82+cursor);}}void MenuFunction(uchar process)//每步功能设置{uchar cursor=0,address=0x80;WriteCommond(0x0c);//不显示光标也不闪烁while(1){if(!KeyUp){Delay(Xiaodou,110);if(!KeyUp){while(!KeyUp){}cursor+=2;cursor%=4;WriteCommond(0x01);//清除显示}}if(!KeyRight){Delay(Xiaodou,110);if(!KeyRight){while(!KeyRight){}if(cursor==3) cursor=2;cursor+=1;cursor%=3;WriteCommond(0x01);//清除显示}}if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}WriteCommond(0x01);//清除显示if(cursor==2||cursor==3) protype[process]=2;else{protype[process]=cursor;MenuParamet(process);}break;}WriteCommond(0x01);//清除显示WriteCommond(0x0c);//不显示光标也不闪烁}switch(cursor){case 0:address=0x80;break;case 1:address=0x8b;break;case 2:case 3:default:address=0xc0;}WindowFunction();//显示设置界面WriteCommond(address);WriteData(0x7e);}}void MenuSet(){uchar cursor=0,address=0x80;WriteCommond(0x0c);//不显示光标也不闪烁while(1){if(!KeyUp){Delay(Xiaodou,110);if(!KeyUp){while(!KeyUp){}cursor+=3;cursor%=6;WriteCommond(0x01);//清除显示}}if(!KeyRight){Delay(Xiaodou,110);if(!KeyRight){while(!KeyRight){}cursor+=1;cursor%=6;WriteCommond(0x01);//清除显示}}if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}WriteCommond(0x01);//清除显示if(cursor==5) break;else if(cursor==4) MenuSpeed();elseMenuFunction(cursor);}WriteCommond(0x01);//清除显示WriteCommond(0x0c);//不显示光标也不闪烁}switch(cursor){case 0:address=0x80;break;case 1:address=0x86;break;case 2:address=0x8b;break;case 3:address=0xc0;break;case 4:address=0xc4;break;case 5:default:address=0xcb;}WindowSet();//显示设置界面WriteCommond(address);WriteData(0x7e);}}void MenuView()//View功能{WriteCommond(0x0c);//不显示光标也不闪烁WindowView();DispTimeS(count[0],0x83);WriteData('s');DispTimeS(count[1],0x8c);WriteData('s');DispTimeS(count[2],0xc3);WriteData('s');DispTimeS(count[3],0xcc);WriteData('s');while(1){if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}WriteCommond(0x01);//清除显示WriteCommond(0x80);WriteString("OVER ALL TIME:");DispTimeS(count[0]+count[1]+count[2]+count[3],0xc0);WriteData('s');while(1){if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}break;}}}break;}}}}void MenuRun(){WriteCommond(0x0c);//不显示光标也不闪烁WindowRun();count[0]=0;count[1]=0;count[2]=0;count[3]=0;TR0=1;//开定时器WriteCommond(0xc3);WriteString("000");//DispTimeS(count[0]+count[1]+count[2]+count[3],0xc3);for(;step<4;step++){timecount=0;//必须加的WriteCommond(0x81);WriteData(step+1+'0');WriteCommond(0x86);WriteString("Running...");WriteCommond(0xcc);WriteString("000s");//DispTimeS(count[step],0xcc);//必须加的switch(protype[step]){case 0:RunFwodBak(0,journey[step]);break;case 1:RunFwodBak(1,journey[step]);break;case 2:RunFind();}WriteCommond(0x86);WriteString("Completed!");if(step==2) Delay(3000,110);Delay(2000,110);}TR0=0;//关定时器step=0;}void MenuMain()//调整菜单{uchar cursor=0,address=0x80;WriteCommond(0x01);//清除显示WriteCommond(0x0c);//不显示光标也不闪烁while(1){if(!KeyUp){Delay(Xiaodou,110);if(!KeyUp){while(!KeyUp){}cursor+=2;cursor%=4;WriteCommond(0x01);//清除显示}}if(!KeyRight){Delay(Xiaodou,110);if(!KeyRight){while(!KeyRight){}if(cursor==3) cursor=2;cursor+=1;cursor%=3;WriteCommond(0x01);//清除显示}}if(!KeyEnter){Delay(Xiaodou,110);if(!KeyEnter){while(!KeyEnter){}WriteCommond(0x01);//清除显示switch(cursor){case 0:MenuSet();break;case 1:MenuView();break;case 2:case 3:default:MenuRun();}WriteCommond(0x01);//清除显示WriteCommond(0x0c);//不显示光标也不闪烁}}switch(cursor){case 0:address=0x80;break;case 1:address=0x8b;break;case 2:case 3:default:address=0xc0;}WindowMain();//显示主界面WriteCommond(address);WriteData(0x7e);}}void MCUInitial()//初始化MCU{EA=1;TMOD=0x01;//16位定时器TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=(65536-235)/256;TL1=(65536-235)%256;ET0=1;//开定时器0中断ET1=1;//开定时器1中断}void LCDInitial()//初始化LCD{WriteCommond(0x38);//设置为16X2,5X7点阵WriteCommond(0x06);//写一个字符地址自加1}void Timer0_Int() interrupt 1{TH0=(65536-10000)/256;TL0=(65536-10000)%256;timecount++;if(timecount>=100){timecount=0;count[step]++;DispTimeS(count[0]+count[1]+count[2]+count[3],0xc3);DispTimeS(count[step],0xcc);}}void Timer1_Int() interrupt 3{TH1=(65536-235)/256;TL1=(65536-235)%256;ADCLK=!ADCLK;}void main(){MCUInitial();LCDInitial();MenuMain();}。

相关文档
最新文档