当前位置:文档之家› 跑步机控制器

跑步机控制器

通达学院2016/2017 学年第一学期课程设计实验报告模块名称51单片机课程设计专业通信工程学生班级130006学生学号********学生姓名陈扬指导教师林建中报告内容一、实验目的:本课程设计是在理论课程学习和软件设计的基础上,对51单片机硬件系统进行了解和研究,使学生更深入的掌握51单片机开发技术,培养学生面对实际课题,发现问题、分析问题和解决问题,提高学生的实验动手能力。

设计根据实验大纲提供的题目要求,选择适当的课题,并通过课题资料收集、原理分析、理论计算、实际编程、系统调试、测试和故障排除,解决在实际设计中的问题,使设计系统能正常工作,有能力的同学可以超出题目要求任意发挥设计。

二、实验要求:基本要求:●观察和了解一台实际跑步机的功能和状态,设计一模拟跑步机●用键设定跑步速度(用两位LED/LCD)●跑步启动后计算和显示跑步时间和距离●设计启动,停止,加速/减速,升高/降底,紧急停止等键●用LED/LCD合理安排数据显示●具有倒计时运行功能发挥部分:●速度变化编成运行模式●高度变化编成运行模式●速度+高度混合编程运行模式●计数热量消耗参数显示格式:8LED数码管显示格式见下图LCD屏显示方法自定三、实验设备以及软件:1.微型计算机一台2.Proteus;Keil3.德飞莱51单片机实验板四、实验原理1.AT89C51单片机引脚及其功能AT89C51有40条引脚,与其他51系列单片机引脚是兼容的。

这40条引脚可分为I/O 端口线、电源线、控制线、外接晶体线四部分。

其封装形式有两种:双列直插封装(DIP)形式和方形封装形式,如图所示。

2.1 I/O 端口功能 1.P0口P0口有八条端口线,命名为P0.0~P0.7,其中P0.0为低位,P0.7为高位。

每条线的结构组成如图2-3所示。

它由一个输出锁存器,两个三态缓冲器,输出驱动电路和输出控制电路组成。

P0口是一个三态双向I/O 口,它有两种不同的功能,用于不同的工作环境。

2. P1口P1口有八条端口线,命名为P1.0~P1.7,每条线的结构组成如图所示。

P1口是一个准双向口,只作普通的I/O 口使用,其功能与P0口的第一功能相同。

作输出口使用时,由于其内部有上拉电阻,所以不需外接上拉电阻;作输入口使用时,必须先向锁存器写入“1”,使场效应管T 截止,然后才能读取数据。

3. P2口P2口有八条端口线,命名为P2.0~P2.7,每条线的结构如图所示。

P2口也是一个准双向口,它有两种使用功能:一种是当系统不扩展外部存储器时,作普通I/O 口使用,其功能和原理与P0口第一功能相同,只是作为输出口时不需外接上拉电阻;另一种是当系统外扩存储器时,P2口作系统扩展的地址总线口使用,输出高8位的地址A 7~A 15,与P0口第二功能输出的低8位地址相配合,共同访问外部程序或数据存储器(64 KB),但它只确定地址并不能像P0口那样还可以传送存储器的读写数据。

4. P3口P3口有八条端口线,命名为P3.0~P3.7,每条线的结构如图所示。

P3口是一个多用途的准双向口。

第一功能是作普通I/O 口使用,其功能和原理与P1口相同。

第二功能是作控制和特殊功能口使用,这时八条端口线所定义的功能各不相同,如表1所示。

表1 P3口各位的第二功能(T 2(T 2(TXD)P3.1(T1)P3.5(TNT0)P3.2(TNT1)P3.3(WR)P3.6(RD)P3.7(TXD)P3.1(INT0)P3.2(INT1)P3.31.41.31.21.1(T 2E X )1.0(T 2)C C C0.0(A D 0)0.1(A D 1)0.2(A D 2)0.3(A D 3)(W R )P (R D )P X T A X T A G N N (A 8)P (A 9)P (A 10)P (A 11)P (A 12)P (a )(b )5.I/O 口的读写P0~P3口都可作为普通I/O 口来使用。

当作为输入口使用时,必须先向该口的锁存器中写入“1”,然后再从读引脚缓冲器中读入引脚状态,这样的读入结果才正确。

2.2 控制线AT89C51单片机的控制线有以下几种:(1) RST :复位输入端,高电平有效。

(2) ALE/ :地址锁存允许/编程线。

(3):外部程序存储器的读选通线。

(4) /V PP :片外ROM 允许访问端/编程电源端 2.LCD 管脚说明LCD 通常有14条引脚线或16条引脚线的LCD ,多出来的2条线是背光电源线 VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD 完全一样,其中: 引脚 符号 功能说明 1 VSS 一般接地 2 VDD 接电源(+5V )3 V0 液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K 的电位器调整对比度)。

4 RSRS 为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。

5 R/WR/W 为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。

+6 E E(或EN)端为使能(enable)端,写操作时,下降沿使能。

读操作时,E 高电平有效7 DB0 低4位三态、 双向数据总线 0位(最低位)PROG PSEN EA8 DB1 低4位三态、双向数据总线 1位9 DB2 低4位三态、双向数据总线 2位10 DB3 低4位三态、双向数据总线 3位11 DB4 高4位三态、双向数据总线 4位12 DB5 高4位三态、双向数据总线 5位13 DB6 高4位三态、双向数据总线 6位14 DB7 高4位三态、双向数据总线 7位(最高位)(也是busy flag)15 BLA 背光电源正极16 BLK 背光电源负极实验原理框图:五、程序代码:#include<reg51.h>#include"lcd.h"sbit key_1 = P1^0; //开始按键sbit key_2 = P1^1; //停止按键sbit key_3 = P1^2; //加速sbit key_4 = P1^3; //减速sbit key_5 = P1^4; //升高sbit key_6 = P1^5; //降低sbit key_7 = P1^6; //紧急停止sbit key_8 = P1^7; //倒计时unsigned int count_1=0; //计数标量unsigned int time_1 = 0; //按键1的计数时间char start = 0; //开始char sudu_flag = 0; //速度变量char high_flag = 0; //速度变量void delay10us(char c) //误差 0us{unsigned char a,b;for(b=c;b>0;b--)for(a=2;a>0;a--);}void delay10ms(char d) //误差 0us{unsigned char a,b,c;for(c=d;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);}void main(){TMOD = 0X01; //设置定时器T0 16位EA = 1; //打开中断ET0 = 1; //打开TO定时器TR0 = 1; //关闭中断TH0 = (65536-50000)/256;TL0 = (65536-50000)%256;LcdInit(); //初始化液晶显示屏while(1){if(key_1==0) //按键1按下{while(key_1==0); //等待K1抬起start = 1;}if(key_2==0) //按键2按下{while(key_2==0); //等待K2抬起start = 0;time_1=0;}if(key_3==0) //按键3按下{while(key_3==0); //等待K3抬起sudu_flag++;if(sudu_flag>=4)sudu_flag=4;}if(key_4==0) //按键4按下{while(key_4==0); //等待K4抬起sudu_flag--;if(sudu_flag<=0)sudu_flag=0;}if(key_5==0) //按键5按下{while(key_5==0); //等待K5抬起high_flag++;if(high_flag>=4)high_flag=4;}if(key_6==0) //按键6按下{while(key_6==0); //等待K6抬起high_flag--;if(high_flag<=0)high_flag=0;}if(key_7==0) //按键2按下{while(key_7==0); //等待K2抬起start = 0;time_1 = 0;}if(key_8==0) //按键2按下{while(key_8==0); //等待K2抬起time_1 += 60;}//显示开始if(start==1){LcdWriteCom(0x80); //显示坐标LcdWriteData('S'); //在lcd1602进行显示LcdWriteData('T'); //在lcd1602进行显示LcdWriteData('A'); //在lcd1602进行显示LcdWriteData('R'); //在lcd1602进行显示LcdWriteData('T'); //在lcd1602进行显示LcdWriteData(' '); //在lcd1602进行显示}else{LcdWriteCom(0x80); //显示坐标LcdWriteData('S'); //在lcd1602进行显示LcdWriteData('T'); //在lcd1602进行显示LcdWriteData('O'); //在lcd1602进行显示LcdWriteData('P'); //在lcd1602进行显示LcdWriteData(' '); //在lcd1602进行显示LcdWriteData(' '); //在lcd1602进行显示}//显示速度switch(sudu_flag){case 0:LcdWriteCom(0x87); //显示坐标LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示LcdWriteData('/'); //在lcd1602进行显示LcdWriteData('s'); //在lcd1602进行显示break;case 1:LcdWriteCom(0x87); //显示坐标LcdWriteData('1'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示LcdWriteData('/'); //在lcd1602进行显示LcdWriteData('s'); //在lcd1602进行显示break;case 2:LcdWriteCom(0x87); //显示坐标LcdWriteData('2'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示LcdWriteData('/'); //在lcd1602进行显示LcdWriteData('s'); //在lcd1602进行显示break;case 3:LcdWriteCom(0x87); //显示坐标LcdWriteData('3'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示LcdWriteData('/'); //在lcd1602进行显示LcdWriteData('s'); //在lcd1602进行显示break;case 4:LcdWriteCom(0x87); //显示坐标LcdWriteData('4'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示LcdWriteData('/'); //在lcd1602进行显示LcdWriteData('s'); //在lcd1602进行显示break;}//高度显示switch(high_flag){case 0:LcdWriteCom(0x8c); //显示坐标LcdWriteData('1'); //在lcd1602进行显示LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('c'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示break;case 1:LcdWriteCom(0x8c); //显示坐标LcdWriteData('2'); //在lcd1602进行显示LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('c'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示break;case 2:LcdWriteCom(0x8c); //显示坐标LcdWriteData('3'); //在lcd1602进行显示LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('c'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示break;case 3:LcdWriteCom(0x8c); //显示坐标LcdWriteData('4'); //在lcd1602进行显示LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('c'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示break;case 4:LcdWriteCom(0x8c); //显示坐标LcdWriteData('5'); //在lcd1602进行显示LcdWriteData('0'); //在lcd1602进行显示LcdWriteData('c'); //在lcd1602进行显示LcdWriteData('m'); //在lcd1602进行显示break;}LcdWriteCom(0xc0); //显示坐标LcdWriteData('T'); //在lcd1602进行显示LcdWriteData('I'); //在lcd1602进行显示LcdWriteData('M');LcdWriteData('E');LcdWriteData(':');LcdWriteData(' ');LcdWriteData('0' + (time_1/60)/10); //分钟十位LcdWriteData('0' + (time_1/60)%10); //分钟个位LcdWriteData(':');LcdWriteData('0' + (time_1%60)/10); //秒十位LcdWriteData('0' + (time_1%60)%10); //秒个位LcdWriteData(' ');delay10ms(10);}}//中断函数void delay1s(void) interrupt 1{TH0 = (65536-50000)/256; //10ms产生一次中断用于数码管动态扫描TL0 = (65536-50000)%256; //10ms产生一次中断用于数码管动态扫描count_1++;if((time_1>0)&&(start==1)){if(count_1>=20) //1s时间{count_1 = 0;time_1--; //时间倒计时if(time_1==0){start = 0; //倒计时结束,时间停止}}}}#include"lcd.h"/******************************************************************** ************ 函数名: Lcd1602_Delay1ms* 函数功能: 延时函数,延时1ms* 输入: c* 输出: 无* 说名: 该函数是在12MHZ晶振下,12分频单片机的延时。

相关主题