毕设 !!!(红色代码为电机控制,为什么按下按键电机转动一段时间以后,自己又停了呢,理论上不按停止应该一直转啊???!!!)
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;
}
}
#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;
}
}
相关文章推荐
- 如何用代码设置控制自己网站的网页在360浏览器打开时强制优先使用极速模式,而非兼容模式
- 内核裁剪,将自己写的驱动加入内核及按键驱动的代码(arm TQ2440)
- 基于mini2440的按键中断控制LED(裸机代码)
- 按键控制流水灯启动,停止,加速,减速
- 为什么程序员应该少写代码
- 为什么你应该停止使用EventBus
- 【转贴】为什么设计师应该学习编写代码
- 一直有个问题说不清楚,我们学习知识的时候为什么一定要按照知识点积累和理论并行?
- unity3D代码控制脚本的停止和启动
- 为什么你一直突破不了自己?
- 为什么的深搜一直不对了,先贴着以后在弄把
- stm32f4,pwm控制电机自己的疑惑
- Windows服务代码控制安装卸载、启动停止
- ASP导出excel文件的代码(自己试验成功并且一直在使用的哟)
- 2003 下的GridView的ItemDataBound 与2.0的RowDataBound 事件两段自己代码 控制弹出窗口
- 公司开发时候,使用svn进行版本控制,在提交代码的时候应该注意的问题,总结!!!!
- 为什么程序员应该少写代码?
- 遇到问题为什么应该自己动手
- MySQL 表字段唯一性约束设置方法以及为什么一定要在表中设置字段的唯一约束,而不能在自己的业务代码处理。
- 遇到问题为什么应该自己动手(刘未鹏)