第二届“北斗杯”全国青少年科技创新大赛优秀作品
得电压差由BA6688的3脚输出。该输出送人电机驱动集成电路BA6686,以驱动电机正反转。当电机转速一定时,通过级联减速齿轮带动电位器R。,旋转,直到电压差为O,电机停止转动。舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。
舵机的控制方法:标准的舵机有3条导线,分别是:电源线、地线、控制线。
电源线和地线用于提供舵机内部的直流电机和控制线路所需的能源.电压通常介于4~6V,一般取5V。注意,给舵机供电电源应能提供足够的功率。控制线的输入是一个宽度可调的周期性方波脉冲信号,方波脉冲信号的周期为20 ms(即频率为50 Hz)。当方波的脉冲宽度改变时,舵机转轴的角度发生改变,角度变化与脉冲宽度的变化成正比。某型舵机的输出轴转角与输入信号的脉冲宽度之间的关系可用下图表示。
后轮电机 (JOHNSON560/ 580):
技术参数:
1)、7.2V时8500转,电流0.65A 2)、12V时14500转,电流0.75A
3)、长65MM,直径35MM,轴径3.17MM,轴长11MM.
4)、重约:255克
3.7.2. 电子调速器 (SP-03018)
中学组一等奖作品
P1 P2 P3 P4 P5 P6 序号 1 2 3 4 5 5.1 5.2 5.2.1 5.2.2 5.2.3 VDD UART Tx UART Rx NC GND LED 3.0 ~ 5.5 VDC 输入 NMEA 串行数据输出 串行数据输入 无连接, 在正常运行下必须悬空 地 GPS状态的显示灯 连接: 电机 电源 电机 电源 换向开关 接收机 (通道 2) 接收机电源 接收机电源 从接收机返回的脉宽调制信号控制电子调速器 裁线种类 单侧 16 awg (黑) 单侧 16 awg (红) 单侧 16 awg (红) 单侧 16 awg (黑) 多路通信线路 (红-黑) (红-黑-白) 红(+) 黑(-) 白(信号) PWM控制:脉冲的周期为20ms。脉冲的长度决定的运动状态如下所示。 前进方向:
——开始启动:1586 μs 脉宽 ——平稳运动:1610 μs 脉宽 ——全速前进:2120 μs 脉宽 后退方向:
——开始启动:1428 μs 脉宽 ——平稳运动:1422 μs 脉宽 ——全速前进:875 μs 脉宽 4 软件设计方案
4.1. 求救装置控制程序
求救装置需要完成的功能是:接收GPS模块发出的定位数据,从$GPRMC语句从提取自身的经纬度信息,存储在单片机(MC9S12XS128MAL)内;当用户按下“短信发送”按键时,使用AT指令控制GSM模块发出含有自身位置信息的求救短信。
以上功能所涉及的软件功能有: 1.总线频率设置(PLL模块); 2.外部中断控制(IRQ模块); 2.串口数据收发(SCI模块);
3.从$GPRMC语句中提取经纬度信息。 4.1.1. 总线频率设置 (PLL模块)
MC9S12XS128MAL单片机中有四个不同的时钟,即外部晶振时钟、锁相环时钟、总线时钟和内核时钟。目前电路采用的是16MHz的外部晶振,默认配置下,
37
第二届“北斗杯”全国青少年科技创新大赛优秀作品
锁相环时钟为32MHz,总线时钟为8MHz,内核时钟为16MHz。通过将PLLSEL寄存器置位,可选择总线频率从锁相环时钟获得,而锁相环时钟与外部晶振时钟的关系由SYNR、REFDV两寄存器决定。
通过相关寄存器的设置,将总线时钟超频到了16MHz,在该频率下,单片机可以稳定工作,同时也保证了数据处理的实时性。具体设置过程为:
void Bus_Clock_Init() {
CLKSEL = 0x00; PLLCTL_PLLON = 1; SYNR = 0xc0 | 0x01; REFDV = 0x80 | 0x01; POSTDIV = 0x00; _asm(nop); _asm(nop);
while (!(CRGFLG_LOCK == 1)) ; CLKSEL_PLLSEL = 1; }
4.1.2. 外部中断控制 (IRQ模块)
MC9S12XS128MAL单片机的PE1为外部中断引脚,使用时需要对IRQCR寄存器的IRQE位和IRQEN位进行设置。
若IRQE=1,当PE1引脚上出现下降沿时,会触发外部中断;若IRQE=0,当PE1引脚上出现低电平时,会触发外部中断。
若IRQEN=1,PE1引脚上的外部中断使能;否则,PE1引脚的外部中断将无法触发。具体设置过程为:
void External_Interrupt_Init() {
IRQCR_IRQE = 1; IRQCR_IRQEN = 1; }
外部中断服务程序中,需要首先关闭外部中断(令IRQEN=0),以避免由于按键抖动造成多次发送数据。当GSM模块短信发送成功后,再使能外部中断(令IRQEN=1),允许下一次发送。具体过程为:
#pragma CODE_SEG NON_BANKED
void interrupt 6 External_Interrupt(void) {
IRQCR_IRQEN = 0;
Sci0_Putstring(commandCmgf); isCmgs = 1; isText = 0;
PORTA = 0x01; }
#pragma CODE_SEG DEFAULT 4.1.3. 串口收发数据 (SCI模块)
中学组一等奖作品
MC9S12XS128MAL单片机有两个串行通信接口,分别为SCI0和SCI1,使用时,需要分别进行初始化设置,下面以SCI0的初始化过程为例进行介绍。
SCI0的初始化,主要是对工作方式控制寄存器(SCI0CR1、SCI0CR2)和波特率寄存器(SCI0BDH、SCI0BDL)进行设置。我们需要将SCI0设置为接收中断使能,波特率为9600(总线频率为16MHz),其他均保留默认配置即可。具体设置过程为:
void Sci0_Init() {
SCI0CR2 = 0x2c; //enable Receive Full Interrupt,RX enable,Tx enable
SCI0BDH = 0x00; SCI0BDL = 0x68;
//Baudrate = busclk / (16 * SCI0BDH:L)
//busclk 16MHz, 9600bps, SCI0BDH = 0x00, SCI0BDL = 0x68 }
完成SCI0的初始化后,就可以通过进行串口数据的收发了。其中发送数据的方式为:检查SCI0SR1寄存器中的TDRE(发送保持器空标志位)是否为1,当TDRE=1时,将待发送数据写入SCI0DRL寄存器。具体过程为:
void Sci0_Putchar(uint8 ch) {
while(!(SCI0SR1&0x80)) ; //keep waiting when not empty SCI0DRL = ch; }
接收数据的过程为:检查SCI0SR1寄存器中的RDRF(接收数据就绪标志位)是否为1,若RDRF=1,从SCI0DRL寄存器中读取数据。具体过程为:
void Sci0_Getchar(uint8 *ch) {
if (SCI0SR1_RDRF == 1) {
*ch = SCI0DRL; SCI0SR1_RDRF = 1; } }
4.1.4. 从$GPRMC语句中提取经纬度信息
这一部分主要是对保存的GPRMC语句进行分析,搜寻关键语句段,进行分析,并生成待发送的短信内容。具体过程为:
void Make_Desicion_GPS() {
if (gpsMessage[3] == 'R' && gpsMessage[4] == 'M' && gpsMessage[5] == 'C')
{
commandTextPointer = 0;
for (i = 0, commaCount = 0; commaCount < 3; i++) {
39
第二届“北斗杯”全国青少年科技创新大赛优秀作品
if (gpsMessage[i] == ',') { commaCount++; } }
latitudeDegree = gpsMessage[i] * 10 + gpsMessage[i + 1];
latitudeMinute = gpsMessage[i + 2] * 10 + gpsMessage[i + 3] + gpsMessage[i + 5] * 0.1 + gpsMessage[i + 6] * 0.01 + gpsMessage[i + 7] * 0.001 + gpsMessage[i + 8] * 0.0001;
Append_String(\for (; gpsMessage[i] != ','; ) {
Append_Character(gpsMessage[i++]); }
Append_Character(';');
for (commaCount = 0; commaCount < 2; i++) {
if (gpsMessage[i] == ',') { commaCount++; } }
longitudeDegree = gpsMessage[i] * 100 + gpsMessage[i + 1] * 10 + gpsMessage[i + 2];
longitudeMinute = gpsMessage[i + 3] * 10 + gpsMessage[i + 4] + gpsMessage[i + 6] * 0.1 + gpsMessage[i + 7] * 0.01 + gpsMessage[i + 8] * 0.001 + gpsMessage[i + 9] * 0.0001;
Append_String(\for (; gpsMessage[i] != ','; ) {
Append_Character(gpsMessage[i++]); }
Append_String(\ Append_Character('\\0'); } }
其中涉及到Append_Character()函数和Appen_String()函数的定义分别为:
void Append_Character(char ch) {
commandText[commandTextPointer++] = ch; }
void Append_String(char *p)