您的位置:首页 > 编程语言

毕设 !!!(红色代码为电机控制,为什么按下按键电机转动一段时间以后,自己又停了呢,理论上不按停止应该一直转啊???!!!)

2013-04-06 16:54 411 查看
(红色代码为电机控制,为什么按下按键电机转动一段时间以后,自己又停了呢,理论上不按停止应该一直转啊???!!!)

#include<reg52.h>

#include <math.H>//绝对值函数abs()

#define uchar unsigned char

#define uint unsigned int

sbit YK=P3^2; //遥控

sbit DQ=P3^3; //温感

sbit FM=P3^4; //报警

sbit youdj1=P1^0;

sbit youdj2=P1^1;

sbit zuodj1=P1^2;

sbit zuodj2=P1^3;

uchar disp[6],irdata[33],ircode[4],codes,bitnum,startflag,irtime,irreceok,irprosok;

uchar tables[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
//带小数点字符表

uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//不带小数点字符表

/***********************延时函数********************************/

void delays(uchar i)

{

uchar j;

while(i--)

{

for(j=0;j<110;j++);

}

}

void delay(int us)
// 延时函数

{

int s;

for (s = 0; s < us; s++);

}

/***********************遥控模块*******************************/

void timer0init(void)
//定时器0的初始化

{

TMOD=0x02; //方式2

TH0=0x00;
//设置初值

TL0=0x00;

EA=1; //总开关打开

ET0=1; //中断打开

TR0=1; //启动定时器

}

void int0init(void) //外部中断0初始化

{

IT0=1;
//下降沿触发

EX0=1;
//打开外部中断// EA=1;

}

void irpros(void) //解码

{

uchar k=1,value,i,j;

for(j=0;j<4;j++)

{

for(i=0;i<8;i++)

{

value=value>>1;
//右移先进最低位,后进高位

if(irdata[k]>6) //时间长,判为1;时间短则判为0,直接右移填0

{

value=value|0x80;
//最右位置1,低位不变

}

k++;

}

ircode[j]=value;
//每八位一字节传递解码器

}

irprosok=1;
//大循环结束,一帧传完,置1 开显示

}

void irwork(void) //从键盘接受用户编码2字节(16位),键值数据码1字节(8位),键值数据码的反码1字节(8位),总共32位数据

{ //实际只需键值数据码,即ircode[2]

//disp[0]=ircode[0]/16; //用户编码的低八位 高4位

//disp[1]=ircode[0]%16; //用户编码的低八位 低4位

//disp[2]=ircode[1]/16; //用户编码的高八位 高4位

//disp[3]=ircode[1]%16; //用户编码的高八位 低4位

disp[0]=ircode[2]/16; //键值数据码 高四位

disp[1]=ircode[2]%16; //键值数据码 低四位

disp[2]=ircode[3]/16; //键值数据码的反码 高四位

disp[3]=ircode[3]%16; //键值数据码的反码 低四位

}

/***********************温度模块********************************/

void init(void)

{

uchar n;

DQ=1; delay(8);

DQ=0;
delay(80);

DQ=1; delay(8);

n=DQ; delay(4);

}

void write_bit(char bitval)

{

DQ = 0; // 拉低

if(bitval==1) DQ =1; // 若写1,拉高

delay(5); // 足够转换时间

DQ = 1;

}

uchar read_bit(void)

{

uchar i;

DQ = 0; // 拉低

DQ = 1; // 拉高

for (i = 0; i < 3; i++); // delay 15μs

return(DQ); // 返回数据

}

uchar read_byte(void) //读字节

{

uchar i,value = 0;

for (i = 0; i < 8; i++)

{

if(read_bit()) value|=0x01<<i;

delay(6);

}

return(value);

}

void write_byte(char val) //写字节

{

uchar i,temp;

for (i = 0; i < 8; i++)

{

temp = val>>i;

temp &= 0x01;

write_bit(temp);

}

delay(5);

}

int tem() //获得温度数据

{

int value; //存放温度数值

float t;

uint tmpvalue;

uchar low, high;

init();

write_byte(0xcc);

write_byte(0x44);

delays(5);

init();

write_byte(0xcc);

write_byte(0xbe);

low=read_byte();

high=read_byte();
//将高低两个字节合成一个整形变量

tmpvalue=high;
//计算机中对于负数是利用补码来表示的

tmpvalue<<=8;
//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value

tmpvalue|=low;

value=tmpvalue;

t=value*0.0625;

value=t*100+(value>0?0.5:-0.5); //大于0加0.5, 小于0减0.5

return value;

}

/***********************显示模块*******************************/

void display(int dd)
// 显示方法1:位单独控制

{

uchar SH,SZ,SL,GH,GL;

uchar dis[8]={10,10,10,10,10,10,10,10}; //从【5-8】的数字为10,相应的段码是0xff,即不显示

uint dda=abs(dd); //考虑温度为正,负

SH = dda/ 10000;
//正百位(使用的四位数码管,所以该位未显示)

SZ = dda % 10000 / 1000;
//正十位

SL = dda % 1000 / 100;
//正个位

GH = dda % 100 / 10;
//小数个位

GL = dda % 10;
//小数十位

dis[0]=GL;

dis[1]=GH;

dis[2]=SL;

dis[3]=SZ;

P0=0x01;

P2=table[GL];

delays(1);

P0=0x00;

P2=0xff;

P0=0x02;

P2=table[GH];

delays(1);

P0=0x00;

P2=0xff;

P0=0x04;

P2=tables[SL];

delays(1);

P0=0x00;

P2=0xff;

P0=0x08;

P2=table[SZ];

delays(1);

P0=0x00;

P2=0xff;

if(SZ>=2||(SZ<1&&SL<10))

{

FM=1; //蜂鸣报警

}

else FM=0;

}

/***********************主函数*******************************/

void main() //1,2,3,4(前进,左转,右转,后退键)对应的ircode[2]值0X10,0X11,0X12,0X14

{

int0init();

timer0init();

while(1)

{

display(tem());//温度显示

if(irreceok)//小车遥控

{

irpros();

irreceok=0;

if(irprosok)

{

irwork();

irprosok=0;

codes=ircode[2];

}

}

switch(codes)

{

case 0x10 : {youdj1=0;youdj2=1;zuodj1=1;zuodj2=0;break;} //前进

case 0x11 : {youdj1=0;youdj2=0;zuodj1=1;zuodj2=0;break;} //左拐

case 0x12 : {youdj1=0;youdj2=1;zuodj1=0;zuodj2=0;break;} //右拐

case 0x14 : {youdj1=1;youdj2=0;zuodj1=0;zuodj2=1;break;} //后退

default : {youdj1=0;youdj2=0;zuodj1=0;zuodj2=0;break;} //停止

}

}

}

/************************定时器模块******************************/

void time0() interrupt 1 //计数器T0中断

{

irtime++; //字符型,自加到255自动变为0

}

/***********************外部中断模块*******************************/

void int0() interrupt 0

{

if(startflag)

{

if(irtime>32)
//检测是否为引导码 , 引导码时间??? 引导码为第一个字节位???

{

bitnum=0;

}

irdata[bitnum]=irtime;

irtime=0;//清零

bitnum++;

if(bitnum==33)
//判断一帧数据是否接受完 ,
总共需要接受4字节(32位)数据

{

bitnum=0;

irreceok=1;
//完成一次按键数据(4字节)的接受,开启解码标记

startflag=0;
//完成一次按键数据(4字节)的接受,关闭时间数据存储

}

}

else

{

startflag=1;

irtime=0;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: