1、 前进号小车设计报告一 设计方案1.自动控制寻迹在地面上任意贴出一条曲折地黑线,小车通过光电传感器能辨认出,从而能沿着黑线自动寻迹。.2. 远程控制 使小车与计算机实现串口通信,用 VC 编制一个控制界面 ,可以通过键盘上的上下左右按扭或则鼠标键实现小车实时控制和加速控制。.3 小车运行状态显示为小车添加光电编码器,单片机根据测得的小车两轮的速度,将数据发给上位机,并在上位机上实时的画出小车的运行轨迹,并显示小车运行状态。二 单片机下位机部分2.1 主控制模块本次设计采用的是美国 cygnal 公司的一款基于 8051 内核的双列直插式芯片C8051F330D,主要考虑的是该芯片调试的方便。该
2、芯片具有以下特点:高速、流水线结构的8051兼容的CIP-51内核(可达25MIPS) 全速、非侵入式的在系统调试接口(片内) 真正10位200 ksps的16通道单端/差分ADC ,带模拟多路器 10位电流输出DAC 高精度可编程的25MHz 内部振荡器 8KB可在系统编程的FLASH存储器 768字节片内RAM硬件实现的SMBus/ I2C、增强型UART和增强型SPI串行接口 4个通用的16位定时器 具有3个捕捉/比较模块和看门狗定时器功能的可编程计数器/定时器阵列 片内上电复位、VDD监视器和温度传感器 片内电压比较器 17个端口I/O(容许5V输入) P0.3/XTLA21(ID)V
3、REF4GN56Sck7d89nvstrUC_MYpfuK+W2.2 电源模块由于主芯片所需供电电压为3.3v伏,电机驱动需要9v伏,传感器为5伏,因此在这里需要两组稳压芯片,分别将电源稳压到5v和3.3v,电路图如下所示。 Baey2.3 传感器模块传感器采用的是发射和接收集成在一起的红外线光耦,用于采集、检测到小车相对于黑线的姿态,设计的电路如下所示:2314UALMN567B809CDRG偶.k+vVSE2.4 电机驱动模块本次设计选择的集成的电机驱动芯片 L298,主要考虑的是设计简单和增加系统的稳定性,而没有选择自己搭建三极管桥电路,电路图如下所示。 IOTPWatery_uFHdi
4、o下位机的程序如下所示,所有程序采用 c 语言编写,主要考虑到 c 语言具有模块化的特点,具有更好的可读性和修改性,程序如下所示:2.5 单片机串口通信部分单片机下位机部分主要负责接收上位机传过来的控制信号,并对其信号进行解码。串口控制程序一般分为查询和中断两者方式。查询方式适用于简单的应用,简单可靠,但是缺点是需要占用处理器资源,在发送或者接收数据的时候不能做其它的事情,处理器利用率低。中断方式下,在发送或者接受数据的时候处理器还可以做其它的工作,效率较高。对于稍微复杂的系统来说,中断方式管理串口程序将会更加有效。在本次设计中,考虑到单片机功能的可扩展性,减少单片机串口通信部分的压力,决定采
5、用中断方式。实现的基本原理如下:1. 硬件电路单片机和 PC 机的串行通信一般采用 RS-232、RS-422 或 B3-485 总线标准接口,也有采用非标准的 20nnJL 电流环的。为保证通信的可靠,在选择接口时必须注意:(1)通信的速率;(2) 通信距离: (3)抗干扰能力;(4)组网方式。本次设计为了简单起见,采用 RS-232 串口通信,采用 MAX232 芯片的转换接口 ,MAX232 是 MAXIM 公司生产的,包含两路驱动器和接收器的 RS-232 转换芯片。芯片内部有一个电压转换器,可以把输入的+5v 电压转换为 RS-232 接口所需的10V 电压,尤其适用于没有12V 的
6、单电源系统。电路图如下:2通信协议通信协议主要是保证单片机与电脑通信数据的有效性和无误性。整个数据考虑到问题的简单性,采用字符格式进行发送,每个字符刚好对应一个数据字节。本次设计中的通信协议为:uart0 数据桢格式 # + rc+(0 to 9)+ * 和 # + tk+(1 to 2)+ *其中#为数据桢起始字节,* 为数据桢终止字节,中间三个字节为数据字节,rc代表小车进行循线模式,tk代表小车进行远程控制模式。其中在远程控制rc 模式中,不同数据字节的含义如下:0: 停止小车1: 启动小车低速前进2: 启动小车低速后退3: 小车左转4: 小车右转5: 小车后左转6: 小车后右转7: 小
7、车原地左转8: 小车原地右转9: 小车加速在循线模式中1 启动小车循线2 结束停止小车循线#include typedef unsigned char uchar;typedef unsigned int uint;sfr16 ADC0VAL=0xbd; /ADC0 转换值=ADC0L+ADC0Hsfr16 PCA0CP0=0xfb; /CEX0 捕捉比较寄存器=PCA0CPL0+PCA0CPH0 sfr16 PCA0CP1=0xe9;sfr16 PCA0CP2=0xeb;sfr16 TMR2=0xcc; /定时器 2 计数器寄存器sfr16 TMR2RL=0xca; /定时器 2 重载寄存器
8、sfr16 TMR3=0x94; /定时器 3 计数器寄存器sfr16 TMR3RL=0x92; /定时器 3 重载寄存器#define SYSCLK 24000000 /采用外部晶振, 24M#define T2_Freq = 500 /T2 系统时基 500Hz#define BAUDRATE 9600 /串口通信波特率#define Buffer_COUNT 4 /定义接收缓冲区大小#define car_mode_front 0x0a /1010 小车后退 2#define car_mode_back 0x06 /0101 小车前进 1#define car_mode_l_resolv
9、e 0x09 /1001 小车原地左转 3#define car_mode_r_resolve 0x09 /0110 小车原地左转 4#define Car_sudu_common 30000#define Car_sudu_double 40000#define Car_sudu_half 11000/-/ 函数声明/-void Timer2_ISR (); void Timer3_ISR (); void Stop_car ();void Start_car();void Timer2_Init (uint val) ;void Timer3_Init (uint val) ;void P
10、ca_Init();void Pwm_set(uint pwm1,uint pwm2) ;void Data_Init();void uart0_Init() ;void config();void turnleft(); /小车向左转void turnright(); /小车向右转/-/ 全局变量/-uchar count_led=0; /LED 延时控制变量uchar count_pwm=0; /PWM 占空比进行数据刷新控制变量sbit P15_LED=P15;sbit P10=P10; /小车方向控制变量sbit P11=P11;sbit P12=P12;sbit P13=P13;sb
11、it SENSE1=P00; /SENSE1=0 表示传感器在黑线上sbit SENSE2=P01;sbit SENSE3=P16;sbit SENSE4=P17;uint pwm1=Car_sudu_half;uint pwm2=Car_sudu_half;static uint Car_sudu_temp=6800; / 三档速度中间变量static uint Car_sudu_traking=8600; static uint Car_run_mode=0; /小车运行方式选择,1 为寻线模式,2 为远程控制模式uchar point; / uart0 接收数据个数指示变量uchar r
12、eceive_bufferBuffer_COUNT; /定义接收数据缓冲区uchar receive_data3;static unsigned int Com_Time=0;static uchar Car_run_time=100;bit Com_Flag=0;static char new_data=0;/-/ T2 初始化/-void Timer2_Init (uint val) /2ms TMR2CN = 0x00; / 选择定时器 2 外部时钟为(SYSCLK/12 ) ,16 位自动重装载方式CKCON / Timer2 clocked based on T2XCLK;TMR2R
13、L = val+1; / Init reload valuesTMR2 = 0xffff; / set to reload immediatelyET2 = 1; / enable Timer2 interruptsTR2 = 1; / 启动定时器 2void Timer3_Init (uint val) /20ms TMR3CN = 0x00; / 选择定时器 3 外部时钟为(SYSCLK/12 ) ,16 位自动重装载方式CKCON / Timer3 clocked based on T3XCLK;TMR3RL = val+1; / Init reload valuesTMR3 = 0xf
14、fff; / set to reload immediatelyEIE1 |= 0x80; / enable Timer3 interrupts/-/ PWM 初始化,PWM 频率为 12.5M/256=93.8KHz/-void Pca_Init()PCA0MD|=0x08; /08 PCA 采用系统时钟 24M, ( 02 4 分频) PCA 溢出中断禁止 PCA0CN=0x40; /启动 PCA 计数器PCA0CPM0=0xcb; /CEX0 为 16 位 PWM 输出模式 PCA0CPM1=0xcb; /CEX1 为 16 位 PWM 输出模式void turnleft()uint i
15、;uint j;Pwm_set(Car_sudu_traking*0.2,Car_sudu_traking*3);for (i=0;i8)mid_value=(pwm2)+1;PCA0CPL1=mid_valuePCA0CPH1=(int)mid_value8)/-/ 数据初始化/-void Data_Init() /pwm1,pwm2 的范围在 0-255 内P10=0;P11=0;P12=0;P13=0; /小车停止Pwm_set(Car_sudu_traking,Car_sudu_traking);/-/ UART0 初始化 串口通信波特率 9600/ 接收数据帧格式 共 5 个字节 起
16、始位为 (0xaa),然后是四个有效数据字节/ aa |速度位 |运动方式 |运动时间| /-void uart0_Init() SCON0 = 0x10; / SCON0: 8-bit variable bit rate/ level of STOP bit is ignored/ RX enabled/ ninth bits are zeros/ clear RI0 and TI0 bitsif (SYSCLK/BAUDRATE/2/256 0OSCXCN=0x67; / 关闭 01100111 使能外部振荡器,晶体振荡器方式 24MHzfor (i=0;i1?CLKSEL=0x01; /
17、将系统时钟切换到外部振荡器/-/ 主程序/-main() config(); / 处理器配置Pca_Init(); / PWM 初始化Timer2_Init(4000);/T2 定时器溢出 1/(500Hz)=2ms,定时计数 SYSCLK/(12*T2_Freq)=4000Timer3_Init(40000);/T2 定时器溢出 1/(50Hz)=20ms,定时计数 SYSCLK/(12*T2_Freq)=40000Data_Init() ;uart0_Init() ;EA=1; /开全局中断IE|=0x10; /允许 uart0 中断while(1)/-/ 任务一/ 控制 LED 定时 1
18、 秒闪烁 1000/4=250/-if (count_led=250)count_led=0;P15_LED=P15_LED;/*if(Com_Time=20)Com_Time=0;Com_Flag=1;TI0=1;*/-/ 任务二/ 启动小车/-/*if(point=4 Car_run_time-;t3_i+; void uart0_ISR() interrupt 4 /全双工 uart 接收uchar receive_temp;if (RI0=1) /处理接收中断RI0=0; /清除中断标志位receive_temp=SBUF0; /接收串口数据if (point=0)if(receive
19、_temp=#) /判断是否起始位point+;elsepoint=0; else if (point0 else if (point=4) /判断是否接收够 4bitif(receive_temp=*)receive_data0= receive_buffer3;if(receive_buffer1=r new_data=1; if(receive_buffer1=t switch ( receive_data0)case 1: Pwm_set(Car_sudu_traking,Car_sudu_traking);P10=0;P11=1;P12=0;P13=1; break;case 2:
20、P10=0;P11=0;P12=0;P13=0; break; point=0;elsepoint=0;else point=0; /缓冲区已满,清除缓冲区内数据,重新接收 三 Pc机上位机部分: 采用 vc 编写小车控制界面实现对小车的实时控制。最初设计的界面如下:通过设置好数据参数后,鼠标点击启动按钮,向小车发送控制信号启动小车。该界面的主要缺点在于无法实现对小车的实时控制,人机交互效果较差。然后我们采用了利用键盘响应来实现对小车的控制。程序的主要关键技术:1 串口通信用 vc 实现串口通信的方法很多,这里为了简单起见,我们采用了 Visual C+为我们提供的 MSComm 控件来实现。
21、 Visual C+为我们提供了一种好用的 ActiveX控件 Microsoft Communications Control(即 MSComm)来支持应用程序对串口的访问,在应用程序中插入 MSComm 控件后就可以较为方便地实现对通过计算机串口收发数据。其实现主要包括以下几个步骤:(1)打开与设置串口接口函数;(2)获得串口设置和串口状态接口函数;(3)设置串口发送数据方式、缓冲区接口及发送数据接口函数;(4)设置与获取串口上发生的事件接口函数。其主要程序如下1 串口初始化程序(部分)m_rc_com.SetCommPort (1);if (!m_rc_com.GetPortOpen()
22、 m_rc_com.SetPortOpen(true);m_rc_com.SetInputMode (1); m_rc_com.SetSettings (“9600,n,8,1“);m_rc_com.SetRThreshold (1);m_rc_com.SetInputLen (0);2 发送数据程序 send_data13=2;CByteArray send;send.RemoveAll();send.SetSize(5);for(i = 0; i 5; i+)send.SetAt(i, send_data1i);m_rc_com.SetOutput(COleVariant(send);2
23、键盘响应:键盘响应函数,键盘消息分为两类:按键消息和字符消息。当按下一个键或松开一个键时都将产生一个按键消息。当按下键产生一个可显示的字符时产生一个字符消息。例如按一个键 A 时并松开,这一最简单的动作将产生三条消息:一个按下消息,一个字符和一个松开消息。由于实现对小车的控制,所需控制键较少,为了简单,程序中不对字符消息进行相应,通过对键盘的上下左右键实现对小车方向控制,空格键实现对小车速度控制。其主要程序如下:void CRCDLG:OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)if (nChar=VK_DOWN) /启动小车后退 if (d
24、own_pressed=0) down_pressed=1;send_data13=2;CByteArray send;send.RemoveAll();send.SetSize(5);for(i = 0; i 5; i+)send.SetAt(i, send_data1i);m_rc_com.SetOutput(COleVariant(send);2 界面的美化有好的界面,软件就成功了一半,在 vc 中通过设置对话框背景颜色和添加动画图片等技术,达到软件很好的视觉效果。其中设置对话框背景颜色通过在 InitInstance()函数中添加如下代码来实现SetDialogBkColor(RGB(
25、24, 152, 200), RGB(255, 0, 255);而动画图片通过添加一个图片类 CPictureEx 来实现,该类在互联网上免费提供,为编程提供了很大帮助。我们最后采用了基于对话框的 vc 界面,程序共有三个对话框,运行结果如下: 对话框一对话框二对话框三四 总结我们的这次设计遇到了很大的问题,一是小车的机械功能不是很好,二是芯片他、遇到了麻烦,但是在我们的努力下,基本实现了预期的功能,如循迹、上位机控制等,整体上比原计划要好一些。通过这次设计我们真正实现了理论与实践相结合,学到了不少知识:机器人、电子电路电路、单片机、控制技术等。同时也学会了合作,明白合作的重要性。我们三人分工合理,都很好地完成自己的工作,并互相帮助,精诚合作,以最高的效率顺利完成设计。总的来说,收获颇多!