题目:基于STC15W4K32S4的蓝牙智能小车课程名称:学院(系):专业:班级:学号:实验序号:学生姓名:成绩:2016 年11月4日成绩评定电子安装实验室安全守则(请在下一页手抄一份安全守则)1、每次实验前,认真预习准备,仔细阅读实验安全守则,严格按照安全规范进行实验,确保实验安全;2、桌面要保持整洁,不允许有杂物,禁止将水杯、瓶装水放在桌面;3、电烙铁在使用前,必须检查电源线有无烫损漏线情况,一经发现,立即找老师进行安全处理;4、电烙铁长时间不使用,应将电源线拔掉;电烙铁使用后,应放回烙铁架中,以免烫伤物品;5、实验结束后,必须拔掉电烙铁的电源线;已经加热的电烙铁,必须冷却后再放入抽屉中;6、焊锡中含铅,不要含在口中,实验结束后要洗手;7、稳压电源在使用前,应先调好要使用的电压,再进行线路连接,并确保连接的极性正确;8、抢救触电人员时,应首先切断电源或用绝缘物体挑开电源线,使触电者脱离电源,千万不要用手拖拉触电人员,以免连环触电;9、实验结束后,必须关闭桌面电源开关,将桌面收拾干净,工具物品整理好。
题目:1 设计要求以STC15W4K32S4单片机为核心,设计焊接并且调试一个实际的单片机控制系统,通过蓝牙实现用手机控制小车的动作状态。
(一)焊接:在实现基本功能的前提下焊接好设计的系统,尽量使其稳定焊点稳定,焊接美观。
(二)最小系统与电源:利用7505稳压芯片实现输入电压转为五伏稳压电源输出。
(三)功能实现:实现用手机自制app或者蓝牙串口助手控制小车前进方向以及行驶速度。
2 设计分析及系统方案设计围绕STC15W4K32S4单片机,把系统的设计规划分为两部分硬件部分:(一)设计并且绘制原理图(二)按照原理图焊接电路板软件部分:(一)编写实验程序(二)系统调试将单片机的p0口用于驱动lcd1602,p4.5,p2.7,p2.3,p2.2用于输出pwm控制电机。
P3.0与p3.1用于与主机通信并且用于蓝牙串口通信。
3 各功能模块硬件电路设计(一)最小系统由于STC15W4K32S4的性能已经进行了优化,所以不同于以往所接触的单片机,它的晶振已经集成化,不用再搭建最小系统电路。
(二)电源电路将输入电压转为5v稳压电源输出(三)LCD液晶屏电路使用P1.0~P1.7与D0~D7相接,EN,RW,RS分别与P0.7,P0.6,P0.5相接(四)蓝牙与单片机连接这里直接用P3.0,P3.1与主机的串口通信和与蓝牙共用串口。
(五)LN298模块4 系统软件设计#include "reg51.h"#include "intrins.h"#include "stdio.h"#include "stdlib.h"#define MAIN_Fosc 11059200L //定义主时钟/************* 变量声明**************/typedef unsigned char u8;typedef unsigned int u16;typedef unsigned long u32;typedef unsigned char BYTE;typedef unsigned int WORD;#define uchar unsigned char#define uint unsigned int#define elif else if#define PWMC (*(unsigned int volatile xdata *)0xfff0) #define PWMCH (*(unsigned char volatile xdata *)0xfff0) #define PWMCL (*(unsigned char volatile xdata *)0xfff1) #define PWMCKS (*(unsigned char volatile xdata *)0xfff2) #define PWM2T1 (*(unsigned int volatile xdata *)0xff00) #define PWM2T1H (*(unsigned char volatile xdata *)0xff00) #define PWM2T1L (*(unsigned char volatile xdata *)0xff01) #define PWM2T2 (*(unsigned int volatile xdata *)0xff02) #define PWM2T2H (*(unsigned char volatile xdata *)0xff02) #define PWM2T2L (*(unsigned char volatile xdata *)0xff03) #define PWM2CR (*(unsigned char volatile xdata *)0xff04) #define PWM3T1 (*(unsigned int volatile xdata *)0xff10) #define PWM3T1H (*(unsigned char volatile xdata *)0xff10) #define PWM3T1L (*(unsigned char volatile xdata *)0xff11) #define PWM3T2 (*(unsigned int volatile xdata *)0xff12) #define PWM3T2H (*(unsigned char volatile xdata *)0xff12)#define PWM3T2L (*(unsigned char volatile xdata *)0xff13) #define PWM3CR (*(unsigned char volatile xdata *)0xff14) #define PWM4T1 (*(unsigned int volatile xdata *)0xff20) #define PWM4T1H (*(unsigned char volatile xdata *)0xff20) #define PWM4T1L (*(unsigned char volatile xdata *)0xff21) #define PWM4T2 (*(unsigned int volatile xdata *)0xff22) #define PWM4T2H (*(unsigned char volatile xdata *)0xff22) #define PWM4T2L (*(unsigned char volatile xdata *)0xff23) #define PWM4CR (*(unsigned char volatile xdata *)0xff24) #define PWM5T1 (*(unsigned int volatile xdata *)0xff30) #define PWM5T1H (*(unsigned char volatile xdata *)0xff30) #define PWM5T1L (*(unsigned char volatile xdata *)0xff31) #define PWM5T2 (*(unsigned int volatile xdata *)0xff32) #define PWM5T2H (*(unsigned char volatile xdata *)0xff32) #define PWM5T2L (*(unsigned char volatile xdata *)0xff33) #define PWM5CR (*(unsigned char volatile xdata *)0xff34) #define PWM6T1 (*(unsigned int volatile xdata *)0xff40) #define PWM6T1H (*(unsigned char volatile xdata *)0xff40) #define PWM6T1L (*(unsigned char volatile xdata *)0xff41) #define PWM6T2 (*(unsigned int volatile xdata *)0xff42) #define PWM6T2H (*(unsigned char volatile xdata *)0xff42) #define PWM6T2L (*(unsigned char volatile xdata *)0xff43) #define PWM6CR (*(unsigned char volatile xdata *)0xff44) #define PWM7T1 (*(unsigned int volatile xdata *)0xff50) #define PWM7T1H (*(unsigned char volatile xdata *)0xff50) #define PWM7T1L (*(unsigned char volatile xdata *)0xff51) #define PWM7T2 (*(unsigned int volatile xdata *)0xff52) #define PWM7T2H (*(unsigned char volatile xdata *)0xff52) #define PWM7T2L (*(unsigned char volatile xdata *)0xff53) #define PWM7CR (*(unsigned char volatile xdata *)0xff54) sfr PWMCFG = 0xf1;sfr PWMCR = 0xf5;sfr PWMIF = 0xf6;sfr PWMFDCR = 0xf7;sfr TH2 = 0xD6;sfr TL2 = 0xD7;sfr IE2 = 0xAF;sfr INT_CLKO = 0x8F;sfr AUXR = 0x8E;sfr AUXR1 = 0xA2;sfr P_SW1 = 0xA2;sfr P_SW2 = 0xBA;sfr PIN_SW2 =0xBA;sfr S2CON = 0x9A;sfr S2BUF = 0x9B;sfr P4 = 0xC0;sfr P5 = 0xC8;sfr P6 = 0xE8;sfr P7 = 0xF8;sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull sfr P1M0 = 0x92; // =10--->pure input, 11--->open drain sfr P0M1 = 0x93;sfr P0M0 = 0x94;sfr P2M1 = 0x95;sfr P2M0 = 0x96;sfr P3M1 = 0xB1;sfr P3M0 = 0xB2;sfr P4M1 = 0xB3;sfr P4M0 = 0xB4;sfr P5M1 = 0xC9;sfr P5M0 = 0xCA;sfr P6M1 = 0xCB;sfr P6M0 = 0xCC;sfr P7M1 = 0xE1;sfr P7M0 = 0xE2;sbit P00 = P0^0;sbit P01 = P0^1;sbit P02 = P0^2;sbit P03 = P0^3;sbit P04 = P0^4;sbit P05 = P0^5;sbit P06 = P0^6;sbit P07 = P0^7;sbit P10 = P1^0;sbit P11 = P1^1;sbit P12 = P1^2;sbit P13 = P1^3;sbit P14 = P1^4;sbit P15 = P1^5;sbit P16 = P1^6;sbit P17 = P1^7;sbit P20 = P2^0;sbit P21 = P2^1;sbit P22 = P2^2;sbit P23 = P2^3;sbit P24 = P2^4;sbit P25 = P2^5;sbit P26 = P2^6;sbit P27 = P2^7;sbit P30 = P3^0;sbit P31 = P3^1;sbit P32 = P3^2;sbit P33 = P3^3;sbit P34 = P3^4;sbit P35 = P3^5;sbit P36 = P3^6;sbit P37 = P3^7;sbit P40 = P4^0;sbit P41 = P4^1;sbit P42 = P4^2;sbit P43 = P4^3;sbit P44 = P4^4;sbit P45 = P4^5;sbit P46 = P4^6;sbit P47 = P4^7;sbit P50 = P5^0;sbit P51 = P5^1;sbit P52 = P5^2;sbit P53 = P5^3;sbit P54 = P5^4;sbit P55 = P5^5;sbit P56 = P5^6;sbit P57 = P5^7;/************* 收发定义**************/#define Baudrate1 9600L //波特率#define UART1_BUF_LENGTH 32u8 TX1_Cnt; //发送计数u8 RX1_Cnt; //接收计数bit B_TX1_Busy; //发送忙标志void UART1_config(u8 brt); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.void PrintString1(u8 *puts);u8 idata RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲/************* IO口定义**************/sbit P_HC595_SER = P4^0; //pin 14 SER data inputsbit P_HC595_RCLK = P5^4; //pin 12 RCLk store (latch) clock sbit P_HC595_SRCLK = P4^3; //pin 11 SRCLK Shift data clock/************* 本地变量声明**************/void delay_ms(u8 ms);void DisableHC595(void);void Initialize_LCD(void);void Write_AC(u8 hang,u8 lie);void Write_DIS_Data(u8 DIS_Data);void ClearLine(u8 row);u8 BIN_ASCII(u8 tmp);void PutString(u8 row, u8 column, u8 *puts);void WriteChar(u8 row, u8 column, u8 dat);/************* 变量声明**************/#define CYCLE 0x1000L //定义PWM周期(最大值为32767)u8 DirLeft[15]={"Dir Left"};u8 DirRight[15]={"Dir Right"};u8 DirUp[15]={"Dir Up"};u8 DirDown[15]={"Dir Down"};u8 HSpeed[15]={"Speed Normal"};u8 NSpeed[15]={"Speed Hight"};int flag = 0;sbit Pdir1 =P2^1;sbit Pdir2 =P2^2;sbit Pfir1 =P2^3;sbit Pfir2 =P2^7;void IoInit(void);void SendMegBack(void);void ENpwm(WORD DUTY1,WORD DUTY2,WORD outch,WORD outen);void closepwm();WORD Speed1=75L;WORD Speed2=80L;WORD Fspeed1=75l;WORD Fspeed2=80L;bit Dir=0;//===========================================void main(void){IoInit(); //初始化端口Initialize_LCD();//初始化端口lcdUART1_config(1); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.EA = 1; //允许总中断while(1){flag=SBUF;SendMegBack();switch(flag){case '0': ClearLine(1);PutString(1,0,DirLeft);Fspeed1=Speed1;Fspeed2=18*Speed2/32;break;case '1': ClearLine(1);PutString(1,0,DirRight);Fspeed1=19*Speed1/32;Fspeed2=Speed2;break;case '2': ClearLine(1);PutString(1,0,DirUp);Fspeed1=Speed1;Fspeed2=Speed2;Dir=0;break;case '3': ClearLine(1);PutString(1,0,DirDown);Fspeed1=Speed1;Fspeed2=Speed2;Dir=1;break;case '4': ClearLine(0);PutString(0,0,NSpeed);Speed1=95L;Speed2=100L;Fspeed1=Speed1;Fspeed2=Speed2;break;case '5': ClearLine(0);PutString(0,0,HSpeed);Speed1=75L;Speed2=80L;Fspeed1=Speed1;Fspeed2=Speed2;break;case '6': ClearLine(0);PutString(0,0,NSpeed);Speed1=Speed1-2l;Speed2=Speed2-2l;Fspeed1=Speed1;Fspeed2=Speed2;break;case '7': ClearLine(0);PutString(0,0,NSpeed);Speed1=Speed1+2l;Speed2=Speed2+2l;Fspeed1=Speed1;Fspeed2=Speed2;break;default: ClearLine(0);PutString(0,0,HSpeed);Speed1=75L;Speed2=80L;Fspeed1=Speed1;Fspeed2=Speed2;break;}if(Dir==0){ENpwm(Fspeed1,Fspeed2,0x00,0x0a);Pdir2=0;Pfir2=0;}else{ENpwm(Fspeed1,Fspeed2,0x00,0x05);Pdir1=0;Pfir1=0;}delay_ms(20);}}/**********************************************/void IoInit(void){P0M1 = 0; P0M0 = 0; //设置为准双向口P1M1 = 0; P1M0 = 0; //设置为准双向口P2M1 = 0; P2M0 = 0; //设置为准双向口P3M1 = 0; P3M0 = 0; //设置为准双向口P4M1 = 0; P4M0 = 0; //设置为准双向口P5M1 = 0; P5M0 = 0; //设置为准双向口P6M1 = 0; P6M0 = 0; //设置为准双向口P7M1 = 0; P7M0 = 0; //设置为准双向口}void SendMegBack(void){if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy)) //收到数据, 发送空闲SBUF = RX1_Buffer[TX1_Cnt]; //把收到的数据远样返回B_TX1_Busy = 1;if(++TX1_Cnt >= UART1_BUF_LENGTH) TX1_Cnt = 0;}void ENpwm(WORD DUTY1,WORD DUTY2,WORD outch,WORD outen){PIN_SW2 |= 0x80; //使能访问XSFRPWMCFG = 0x00; //配置PWM的输出初始电平为低电平PWMCKS = 0x00; //选择PWM的时钟为Fosc/(0+1)PWMC = CYCLE; //设置PWM周期PWM3T1 = CYCLE * DUTY1/ 100; //设置PWM2第1次反转的PWM计数PWM4T1 = CYCLE * DUTY1/ 100; //设置PWM2第2次反转的PWM计数PWM5T1 = CYCLE * DUTY2 / 100; //设置PWM3第1次反转的PWM计数PWM2T2 =CYCLE * DUTY1/ 100 ; //设置PWM3第2次反转的PWM计数PWM2CR = 0x08; //选择PWM2输出引脚,不使能PWM2中断PWM3CR = 0x00;PWM4CR = 0x00;PWM5CR = 0x00;PWMCR = outen; //使能PWM信号输出PWMCR |= 0x80; //使能PWM模块PIN_SW2 &= ~0x80; //占空比为(PWM2T2-PWM2T1)/PWMC }void closepwm(){PIN_SW2 |= 0x80; //使能访问XSFRPWMCR = 0x00; //使能PWM信号输出PWMCR |= 0x80; //使能PWM模块PIN_SW2 &= ~0x80;Pfir1=0;Pfir2=0;Pdir1=0;Pdir2=0;}void delay_ms(u8 ms){unsigned int i;do{i = MAIN_Fosc / 13000;while(--i) ; //14T per loop}while(--ms);}void DisableHC595(void){u8 i;P_HC595_SER = 1;for(i=0; i<20; i++){P_HC595_SRCLK = 1;P_HC595_SRCLK = 0;}P_HC595_RCLK = 1;P_HC595_RCLK = 0; //锁存输出数据P_HC595_RCLK = 1;P_HC595_RCLK = 0; //锁存输出数据}// 函数: void RTC(void)// 描述: RTC演示函数// 参数: none.// 返回: none.// 版本: VER1.0// 日期: 2013-4-1// 备注://============================================================ ============/************* LCD1602相关程序*****************************************************///8位数据访问方式LCD1602 标准程序梁工编写2014-2-21#define LineLength 16 //16x2/************* Pin define *****************************************************/sfr LCD_BUS = 0x90; //P0--0x80, P1--0x90, P2--0xA0, P3--0xB0sbit LCD_B7 = LCD_BUS^7; //D7 -- Pin 14 LED- -- Pin 16sbit LCD_B6 = LCD_BUS^6; //D6 -- Pin 13 LED+ -- Pin 15sbit LCD_B5 = LCD_BUS^5; //D5 -- Pin 12 V o -- Pin 3sbit LCD_B4 = LCD_BUS^4; //D4 -- Pin 11 VDD -- Pin 2sbit LCD_B3 = LCD_BUS^3; //D3 -- Pin 10 VSS -- Pin 1sbit LCD_B2 = LCD_BUS^2; //D2 -- Pin 9sbit LCD_B1 = LCD_BUS^1; //D1 -- Pin 8sbit LCD_B0 = LCD_BUS^0; //D0 -- Pin 7sbit LCD_ENA = P0^7; //Pin 6sbit LCD_RW = P0^6; //Pin 5 //LCD_RS R/W DB7--DB0 FOUNCTIONsbit LCD_RS = P0^5; //Pin 4 // 0 0 INPUT write the command to LCD model// 0 1 OUTPUT read BF and AC pointer from LCD model// 1 0 INPUT write the data to LCD model// 1 1 OUTPUT read the data from LCD model/*total 2 lines, 16x2= 32first line address: 0~15second line address: 64~79*/#define C_CLEAR 0x01 //clear LCD#define C_HOME 0x02 //cursor go home#define C_CUR_L 0x04 //cursor shift left after input#define C_RIGHT 0x05 //picture shift right after input#define C_CUR_R 0x06 //cursor shift right after input#define C_LEFT 0x07 //picture shift left after input#define C_OFF 0x08 //turn off LCD#define C_ON 0x0C //turn on LCD#define C_FLASH 0x0D //turn on LCD, flash#define C_CURSOR 0x0E //turn on LCD and cursor#define C_FLASH_ALL 0x0F //turn on LCD and cursor, flash#define C_CURSOR_LEFT 0x10 //single cursor shift left#define C_CURSOR_RIGHT 0x10 //single cursor shift right#define C_PICTURE_LEFT 0x10 //single picture shift left#define C_PICTURE_RIGHT 0x10 //single picture shift right#define C_BIT8 0x30 //set the data is 8 bits#define C_BIT4 0x20 //set the data is 4 bits#define C_L1DOT7 0x30 //8 bits,one line 5*7 dots#define C_L1DOT10 0x34 //8 bits,one line 5*10 dots#define C_L2DOT7 0x38 //8 bits,tow lines 5*7 dots#define C_4bitL2DOT7 0x28 //4 bits,tow lines 5*7 dots#define C_CGADDRESS0 0x40 //CGRAM address0 (addr=40H+x)#define C_DDADDRESS0 0x80 //DDRAM address0 (addr=80H+x)#define LCD_DelayNop() _nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();\_nop_();#define LCD_BusData(dat) LCD_BUS = dat//============================================================ void CheckBusy(void){u16 i;for(i=0; i<5000; i++) {if(!LCD_B7) break;} //check the LCD busy or not. With time out// while(LCD_B7); //check the LCD busy or not. Without time out}void IniSendCMD(u8 cmd){LCD_RW = 0;LCD_BusData(cmd);LCD_DelayNop();LCD_ENA = 1;LCD_DelayNop();LCD_ENA = 0;LCD_BusData(0xff);}void Write_CMD(u8 cmd){LCD_RS = 0;LCD_RW = 1;LCD_BusData(0xff);LCD_DelayNop();LCD_ENA = 1;CheckBusy(); //check the LCD busy or not.LCD_ENA = 0;LCD_RW = 0;LCD_BusData(cmd);LCD_DelayNop();LCD_ENA = 1;LCD_DelayNop();LCD_ENA = 0;LCD_BusData(0xff);}void Write_DIS_Data(u8 dat){LCD_RS = 0;LCD_RW = 1;LCD_BusData(0xff);LCD_DelayNop();LCD_ENA = 1;CheckBusy(); //check the LCD busy or not.LCD_ENA = 0;LCD_RW = 0;LCD_RS = 1;LCD_BusData(dat);LCD_DelayNop();LCD_ENA = 1;LCD_DelayNop();LCD_ENA = 0;LCD_BusData(0xff);}void Initialize_LCD(void){LCD_ENA = 0;LCD_RS = 0;LCD_RW = 0;delay_ms(100);IniSendCMD(C_BIT8); //set the data is 8 bitsdelay_ms(10);Write_CMD(C_L2DOT7); //tow lines 5*7 dots delay_ms(6);Write_CMD(C_CLEAR); //clear LCD RAMWrite_CMD(C_CUR_R); //Curror Shift RightWrite_CMD(C_ON); //turn on LCD}void ClearLine(u8 row){u8 i;Write_CMD(((row & 1) << 6) | 0x80);for(i=0; i<LineLength; i++) Write_DIS_Data(' ');}void WriteChar(u8 row, u8 column, u8 dat){Write_CMD((((row & 1) << 6) + column) | 0x80);Write_DIS_Data(dat);}void PutString(u8 row, u8 column, u8 *puts){Write_CMD((((row & 1) << 6) + column) | 0x80);for ( ; *puts != 0; puts++) //遇到停止符0结束{Write_DIS_Data(*puts);if(++column >= LineLength) break;}}//******************** LCD20 Module END *************************** //******************** 串口部分***************************//============================================================ ============// 函数: void PrintString1(u8 *puts)// 描述: 串口1发送字符串函数。