Proteus设计汽车速度控制系统
1、Proteus版本及使用芯片
1、proteus版本:8.0
2、使用芯片: 并行接口芯片8255A、模数转换芯片ADC0808、锁存器74HC373、译码器74HC138、或非门74HC02
2、设计思路
1、采用滑动变阻器模拟油门大小,电压表显示电阻的电压,通过ADC0808将其转化为数字信号,然后用8个LED灯显示出来。
2、通过一个8255A芯片实现档位的改变,读取与五个按钮连接的8255A芯片的PA口,判断按下的是哪个按钮,实现对应的功能。通过按钮来模拟档位,分为前进一、前进二、前进三、后退、停止五个档位。
3、根据档位和油门计算出对应的速度,输出到与数码管连接的8255A芯片,然后由PA口输出速度大小,PB口控制数码管显示。在某个档位速度的大小有一定的范围,汽车速度为0-9。
前进一:1-4;
前进二:4-7;
前进三:7-9;
后退:2(恒速)
停止:0;
3、芯片连接
1、74HC138译码器Y0引脚与74HC02连接控制锁存器74HC373来保存ADC0808芯片输出的数据,故其端口地址为 8000H
2、74HC138译码器Y1引脚与连接数码管的8255A芯片相连,故与数码管连接的8255A芯片的PA、PB、PC、命令口地址分别为9000H、9002H、9004H、9006H。
3、74HC138译码器Y6引脚与连接按钮的8255A芯片相连,故连接按钮的8255A芯片的PA、PB、PC、命令口地址分别为0A000H、0A002H、0A004H、0A006H。
4、原理图
5、c源程序代码
/* Main.c file generated by New Project wizard
*
* Created: 周三 1月 1 2020
* Processor: 8086
* Compiler: Digital Mars C
*
* Before starting simulation set Internal Memory Size
* in the 8086 model properties to 0x10000
*/
#define ADC0809 0E002H
#define OUT373 8000H
// 档位
#define STOP 0xef
#define BACKWARD 0xf7
#define FORWARD1 0xfb
#define FORWARD2 0xfd
#define FORWARD3 0xfe
// 8255芯片1
#define IOCON 0A006H
#define IOA 0A000H
#define IOB 0A002H
#define IOC 0A004H
// 8255芯片2
#define IOCON2 9006H
#define IOA2 9000H
#define IOB2 9002H
void outp(unsigned int addr, char data)
// Write a byte to the specified I/O port
{ __asm
{ mov dx, addr
mov al, data
out dx, al
}
}
char inp(unsigned int addr)
// Read a byte from the specified I/O port
{ char result;
__asm
{ mov dx, addr
in al, dx
mov result, al
}
return result;
}
// 获得速度大小
unsigned int getSpeed(unsigned char dangwei, unsigned char youmen)
{
unsigned int accelerator = (unsigned int)youmen;
unsigned int delay = 0;
unsigned int speed = 0;
//速度越慢,delay时间越长
if(dangwei==FORWARD1)
{
delay = accelerator/4 + 150;
if(accelerator<64) speed=4;
else if(accelerator<128) speed=3;
else if(accelerator<192) speed=2;
else speed=1;
}
else if(dangwei==FORWARD2)
{
delay = accelerator/4 + 50;
if(accelerator<64) speed=7;
else if(accelerator<128) speed=6;
else if(accelerator<192) speed=5;
else speed=4;
}
else if(dangwei==FORWARD3)
{
delay = accelerator/4 + 10;
if(accelerator<64) speed=9;
else if(accelerator<128) speed=8;
else if(accelerator<192) speed=7;
else speed=6;
}
else if(dangwei==BACKWARD)
{
delay = 200;
speed = 2; // 倒车恒速
}
for(unsigned int i=0; i<delay; i++)
{
}
return speed;
}
void main(void)
{
unsigned char youmen,youmen2; // 转换成的数字信号
unsigned char dangwei=0; // 汽车的档位
//速度0-9
unsigned char speed[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//用于获取档位以及模拟车速
//第一个8255A芯片,命令字10010000B A组0方式 PA输入 PC4-7输出 B组0方式 PB输入 PC0-3输出
outp(IOCON,0x92);
//第二个8255A芯片,命令字10000000B A组0方式 PA输出 PC4-7输出 B组0方式 PB输出 PC0-3输出
outp(IOCON2, 0x80);
while(1)
{
//读第一个芯片8255的A口,检测指令
dangwei=inp(IOA);
if(dangwei==FORWARD1) // 前进 1
{
while(1)
{
//关闭锁存器
outp(ADC0809,0);
//获取油门,非写,非Y0 打开锁存器
youmen=inp(ADC0809);
outp(OUT373,youmen);
//计算速度
youmen2=inp(IOB);
unsigned int speed2 = getSpeed(FORWARD1, youmen2);
//显示速度
outp(IOA2, speed[speed2]);
outp(IOB2, 0x01);
//再次读取 读三次
dangwei=inp(IOA);
dangwei=inp(IOA);
dangwei=inp(IOA);
if(dangwei==BACKWARD||dangwei==STOP||dangwei==FORWARD2||dangwei==FORWARD3)
break;
}
}
if(dangwei==FORWARD2) // 前进 2
{
while(1)
{
//关闭锁存器
outp(ADC0809,0);
//获取油门,非写,非Y0 打开锁存器
youmen=inp(ADC0809);
outp(OUT373,youmen);
//计算速度
youmen2=inp(IOB);
unsigned int speed2 = getSpeed(FORWARD2, youmen2);
//显示速度
outp(IOA2, speed[speed2]);
outp(IOB2, 0x01);
dangwei=inp(IOA);
dangwei=inp(IOA);
dangwei=inp(IOA);
if(dangwei==BACKWARD||dangwei==STOP||dangwei==FORWARD1||dangwei==FORWARD3)
break;
}
}
if(dangwei==FORWARD3) // 前进 3
{
while(1)
{
//关闭锁存器
outp(ADC0809,0);
//获取油门,非写,非Y0 打开锁存器
youmen=inp(ADC0809);
outp(OUT373,youmen);
//计算速度
youmen2=inp(IOB);
unsigned int speed2 = getSpeed(FORWARD3, youmen2);
//显示速度
outp(IOA2, speed[speed2]);
outp(IOB2, 0x01);
//再次读取
dangwei=inp(IOA);
dangwei=inp(IOA);
dangwei=inp(IOA);
if(dangwei==BACKWARD||dangwei==STOP||dangwei==FORWARD1||dangwei==FORWARD2)
break;
}
}
if(dangwei==BACKWARD) // 倒车
{
while(1)
{
//关闭锁存器
outp(ADC0809,0);
//获取油门,非写,非Y0 打开锁存器
youmen=inp(ADC0809);
outp(OUT373,youmen);
//计算速度
youmen2=inp(IOB);
unsigned int speed2 = getSpeed(BACKWARD, youmen2);
//显示速度
outp(IOA2, speed[speed2]);
outp(IOB2, 0x01);
dangwei=inp(IOA);
dangwei=inp(IOA);
dangwei=inp(IOA);
//有其他变化
if(dangwei==FORWARD1||dangwei==STOP||dangwei==FORWARD2||dangwei==FORWARD3)
break;
}
}
if(dangwei==STOP) // 停车
{
outp(IOA2,speed[0]);
outp(IOB2, 0x01);
}
}
}