项目简介:
小车可分为3种工作模式,每种工作模式都会打印在oled显示屏上,通过按键转换工作模式。
模式1: 小车红外循迹,通过超声波实时监测障碍物距离,若超出规定路线,距离障碍物相对较近时,原地停止,等待指令。
模式2: 自主驾驶,通过超声扫描各障碍物距离,当小于一定距离时原地左转。
模式3: 蓝牙远程遥控
一、硬件清单
本项目用到的模块有:
- msp430f5529开发板
- 红外循迹模块 tcrt5000l
- 超声波 hc-sr04
- 蓝牙 atk_hc-05
- 显示屏 四针oled
- 充电电池 12v
- tt电机及车轮
- 电机驱动 l298n
- 万向轮
- vcc、gnd拓展口(自焊)
- 若干杜邦线及铜柱螺母
二、模块连接
手册先行
1. 蓝牙: uart
uart(a0): p3.4、p3.3(rx和tx)
uart(a1): p4.5、p4.4(rx和tx)
2. oled : iic
iic(b0): p3.0、p3.1(scl和sda)
iic(b1): p4.2、p4.1(scl和sda)
3. 超声波: timer
ta0:p1.1、p1.2、p1.3、p1.4、p1.5
ta1:p1.7、p2.0、p2.1
ta2:p2.3、p2.4、p2.5
tb0:p3.6、p5.6、p5.7、p7.4、p7.5、p7.6、p7.7
以上为该项目需要部分引脚分配,以下为我的模块连接示例:
- motor:
p3.5、p3.6
p3.0、p3.1
- pwm:
p2.4、p2.5
- tcrt5000l:
p3.4、p6.6、p1.6
- oled:
p2.0(scl)、p2.2(sda)
- hc_sr-04:
p1.2(echo)、p1.4(trig)
- atk_hc-05:
p4.4(tx)、p4.5(rx)
三、程序设计
1. motor_and_infrared_gpioinit
p3sel &= ~bit0; //右轮
p3dir |= bit0;
p3sel &= ~bit1;
p3dir |= bit1;
p3sel &= ~bit5; //左轮
p3dir |= bit5;
p3sel &= ~bit6;
p3dir |= bit6;
p3sel &=~bit4;
p3dir &=~bit4;
p3ren |=bit4;//左边
p1sel &=~bit6;
p1dir &=~bit6;
p1ren |=bit6;//右边
p6sel &=~bit6;
p6dir &=~bit6;
p6ren |=bit6;//中间
2. setpwm_init
p2dir |= bit4; //配置p2.4复用为定时器ta2.4
p2sel |= bit4; //配置p2.4为输出
ta2ctl = tassel_2+mc_1+id_3;
ta2cctl1 = outmod_7 ;
ta2ccr1 = arr;
ta2ccr0 = psc;
p2dir |= bit5; //配置p2.5复用为定时器ta2.5
p2sel |= bit5; //配置p2.5为输出
ta2ctl = tassel_2+mc_1+id_3;
ta2cctl2 = outmod_7 ;
ta2ccr2 = arr;
ta2ccr0 = psc;
3. oled_init
//oled初始化函数
void oled_init(void)
{
p2dir |= bit0; //设置引脚为输出模式
p2dir |= bit2;
p2out |=bit0; //设置为高电平
p2out |=bit2;
iic_sda_in0;
delay_ms(200);
iic_sda_in1;
//
oled_wr_byte(0xae,oled_cmd);//--turn off oled panel
oled_wr_byte(0x00,oled_cmd);//---set low column address
oled_wr_byte(0x10,oled_cmd);//---set high column address
oled_wr_byte(0x40,oled_cmd);//--set start line address set mapping ram display start line (0x00~0x3f)
oled_wr_byte(0x81,oled_cmd);//--set contrast control register
oled_wr_byte(0xcf,oled_cmd);// set seg output current brightness
oled_wr_byte(0xa1,oled_cmd);//--set seg/column mapping 0xa0脳贸脫脪路麓脰脙 0xa1脮媒鲁拢
oled_wr_byte(0xc8,oled_cmd);//set com/row scan direction 0xc0脡脧脧脗路麓脰脙 0xc8脮媒鲁拢
oled_wr_byte(0xa6,oled_cmd);//--set normal display
oled_wr_byte(0xa8,oled_cmd);//--set multiplex ratio(1 to 64)
oled_wr_byte(0x3f,oled_cmd);//--1/64 duty
oled_wr_byte(0xd3,oled_cmd);//-set display offset shift mapping ram counter (0x00~0x3f)
oled_wr_byte(0x00,oled_cmd);//-not offset
oled_wr_byte(0xd5,oled_cmd);//--set display clock divide ratio/oscillator frequency
oled_wr_byte(0x80,oled_cmd);//--set divide ratio, set clock as 100 frames/sec
oled_wr_byte(0xd9,oled_cmd);//--set pre-charge period
oled_wr_byte(0xf1,oled_cmd);//set pre-charge as 15 clocks & discharge as 1 clock
oled_wr_byte(0xda,oled_cmd);//--set com pins hardware configuration
oled_wr_byte(0x12,oled_cmd);
oled_wr_byte(0xdb,oled_cmd);//--set vcomh
oled_wr_byte(0x40,oled_cmd);//set vcom deselect level
oled_wr_byte(0x20,oled_cmd);//-set page addressing mode (0x00/0x01/0x02)
oled_wr_byte(0x02,oled_cmd);//
oled_wr_byte(0x8d,oled_cmd);//--set charge pump enable/disable
oled_wr_byte(0x14,oled_cmd);//--set(0x10) disable
oled_wr_byte(0xa4,oled_cmd);// disable entire display on (0xa4/0xa5)
oled_wr_byte(0xa6,oled_cmd);// disable inverse display on (0xa6/a7)
oled_clear();
oled_wr_byte(0xaf,oled_cmd);
}
4. bluetooth_init
p4sel |=bit4+bit5 ; // p4.5 p4.4 = usci_a1 txd/rxd
uca1ctl1 |= ucswrst; // **put state machine in reset**
uca1ctl1 |= ucssel_2; // smclk
uca1br0 = 9; // 1mhz 115200 (see user's guide)
uca1br1 = 0; // 1mhz 115200
uca1mctl |= ucbrs_1 + ucbrf_0; // modulation ucbrsx=1, ucbrfx=0
uca1ctl1 &= ~ucswrst; // **initialize usci state machine**
uca1ie |= ucrxie; // enable usci_a1 rx interrupt
__bis_sr_register(lpm0_bits + gie); // enter lpm0, interrupts enabled
5. timer_init
ta0cctl0 = ccie; //ccr0中断使能
ta0ccr0 = a*1000; //设定计数值
ta0ctl =tassel_2+mc_1+taclr;//smclk,增计数模式,清除tar
_bis_sr_register(lpm0_bits+gie);//低功耗模式0,使能中断
6. hcsr04_init
usonud_out |= trig;
usound_dir |= trig;
usound_sel |= echo ; //cci0a
7. key_init
p1dir &=~bit1;//板载按键s2设为输入
p2dir &=~bit1;//板载按键s1设为输入
p2ren =bit1;//上拉电阻
p1ren =bit1;//上拉电阻
p1out |=bit1;
p2out |=bit1;//初始状态为高电平
//低电平触发函数
8. interrupt
// echo back rxed character, confirm tx buffer is ready first,发送数据之前确定发送缓存准备好
#pragma vector=usci_a1_vector
__interrupt void usci_a1_isr(void)
{
switch(__even_in_range(uca1iv,4))
{
case 0: //无中断
break; // vector 0 - no interrupt
case 2: // vector 2 - rxifg 接受中断
while (!(uca1ifg&uctxifg)); // usci_a1 tx buffer ready? uctxifg(usci transmit interrupt flag)
uca1txbuf = uca1rxbuf; //等待数据发送完成 完成uctxifg置1 跳出循环 // tx -> rxed character
break;
case 4:
break; // vector 4 - txifg 发送中断
default: break;
}
}
// uctxifg=0x02,uca1ifg&uctxifg,当uca1ifg的uctxifg位为1时,说明uca1txbuf为空,
//跳出while循环循环;当uctxifg位为0时uca1txbuf不为空,停在循环。
四、项目源码
若需项目源码可留言评论区qq邮箱 或 私信即可。
着急的小伙伴可直接加好友联系 👇
发表评论