完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
下面是个人写的子程序:
void timer0() interrupt 1 //TO定时器控制 { ET0=0; TH0=(65536-5000)/256; TL0=(65536-5000)%256; sendChangeCmd();//这二个是调用转换温度子程序 getTmpValue(); if(sign_temp>=35)//sign_temp是获得的温度 sign_temp=35 if(sign_temp>=20) { MA=1;MB=0; if(sign_temp==20) { PWM=0; DelayXus(30);return; } // else if(sign_temp==35) { PWM=1; DelayXus(30);return; } PWM=1; DelayXus(sign_temp-20); PWM=0; DelayXus(35-sign_temp); } else { MA=0; MB=0; } } void InitTimer0() { TMOD=0x01; TH0=(65536-5000)/256; TL0=(65536-5000)%256; EA=1; ET0=1; TR0=1; } 我的程序可能有问题,求大神帮写一个L298PWM控制风扇的程序,,功能:大于35度时全速正转,低于20度停止转动,在20-35度之间转速随着温度的提高而提高。。求修改程序或者提供下程序,,如果需要全部的程序,,麻烦您加下QQ:540163420.。求帮忙,急!!!! |
|
相关推荐
10个回答
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include
#include #include #define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位) #define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位) #define KeyPort P1 //定义按键端口 char sign_temp; ***it MA=P2^5; ***it MB=P2^6; ***it PWM=P2^7; ***it beep=P3^7; //定义蜂鸣器端口 ***it RS = P2^0; //定义1602数据/命令选择端(H/L)端口 ***it LCDEN = P2^1; //定义1602使能端 ***it DQ = P1^7; //可位寻址变量定义,DQ为DS18B20总线端口,用DQ表示P3^2口 int tempH,tempL; //定义高低温度上下限 tempH=350,tempL=200; //定义高温度上限为23℃,低温下限位-10℃ uchar datas[] = {"0123456789"};//表格预存储数据 void delayMs(uint a) //Ms级延时子程序 { uint i, j; for(i = a; i > 0; i--) for(j = 100; j > 0; j--); } void DelayUs2x(unsigned char t) //us级延时子程序 { while(--t); } void DelayXus(int x) { uchar i; while(x--) for (i=0;i<200;i++); } //写命令 void writeComm(uchar comm) { RS = 0; //RS拉低,写指令 P0 = comm;//指令通过P1口传输 LCDEN = 1;//1602LCD使能端拉高允许接收指令 _nop_(); //稍微延时,让指令传输进P1口 LCDEN = 0; //使能端拉低 delayMs(1); //延时约1MS可省略LCD忙检测 } //写数据 void writeData(uchar dat) { RS = 1; //RS拉高,写数据 P0 = dat;//数据通过P1口传输 LCDEN = 1;//1602LCD使能端拉高允许接收数据 nop_();//稍微延时,让数据传输进P1口 LCDEN = 0;//使能端拉低 delayMs(1);//延时约1MS可省略LCD忙检测 } /**//*****************************初始化1602液晶显示*******************************/ void init() { writeComm(0x38);//设置16×2显示,5×7点阵,8位数据借口 writeComm(0x0c); //开LCD显示,不显示光标,光标不闪烁 writeComm(0x06);//当读或写一个字符后光标向后地址指针加一,且光标加一 writeComm(0x01); //显示清屏,清除lcd默认显示数据 } /**************************连续写N个字节*********** str为要连续写入的数据的首地址 length为正数X,表示我们这字符串写入前X位*/ void writeString(uchar * str, uchar length) { uchar i; for(i = 0; i < length; i++) { writeData(str[i]); } } /**//*****************************初始化DS18B20*******************************/ bit Init_DS18B20() { bit tempData; DQ=1; //DQ复位 DelayUs2x(5); //稍做延时 DQ=0; //单片机将DQ拉低 DelayUs2x(200);//精确延时 DelayUs2x(200); DQ=1; //拉高总线 DelayUs2x(50); //15~60us后接收60-240us的存在脉冲 tempData=DQ; //如果tempData=0则初始化成功, tempData=1则初始化失败 DelayUs2x(25); //稍作延时返回 return tempData; } /**//*****************************读取DS18B20*******************************/ uchar read_DS18B20(void) { uchar i=0;//循环辅助 uchar dt=0; //定义接收的数据 for(i=0;i<8;i++)//for循环用于读取总线的八位数据, { DQ=0; //拉低DS18B20总线 dt>>=1; //由于从低位开始接受数据,所以将每次接收到的数据右移一位, DQ=1;//释放总线 if(DQ) //若DS18B20将总线拉高,则读取到的数据为1,进入程序,若为0则将dt右移一位 { dt|=0x80;//将dt与ox80相或后赋给dt,实现一位数据的读取 } DelayUs2x(25);//延时45us } return dt; //返回读取的数据 } /*******************************写数据进DS18B20*******************************/ void writeByte(uchar dat) { uchar j; bit b; for(j = 0; j < 8; j++) { b = dat & 0x01;//取出要写入的数据dat中的一位并赋值给b dat >>= 1; //dat右移一位 if(b) //若取出的数据是1,则进入if语句 { DQ = 0; //将总线拉低 _nop_(); _nop_(); //稍作延时 DQ = 1; //将总线拉高 DelayUs2x(25); //延时约45us } else //若写入的数据是0,则 { DQ = 0; //将总线拉低 DelayUs2x(25); //延时约45us DQ = 1;//释放总线 _nop_(); } } } /*******************************向DS18B20发送温度转换指令*******************************/ void sendChangeCmd() { Init_DS18B20(); // 复位DS18B20 delayMs(1); //稍作延时 writeByte(0xcc); //单点测温,跳过ROM指令 writeByte(0x44); //开始转换温度,转换好的温度存储在暂存器字节0和1 } /*******************************向DS18B20发送温度读取指令*******************************/ void sendReadCmd() { Init_DS18B20();// 复位DS18B20 delayMs(1); //稍作延时 writeByte(0xcc); //单点测温,跳过ROM指令 writeByte(0xbe); //读暂存器 } /*************************将DS18B20取出的温度转换成十进制数并对温度值进行预警判断*******************************/ int getTmpValue() { uint value; //定义无符号整形变量value,16位 int value1; //定义有符号整形变量value1,8位 uchar TL,TH; //定义无符号字符变量TH、TL,8位 sendReadCmd(); //向DS18B20发送读取温度指令 TL=read_DS18B20();//读取的温度的低八位存储在TL TH=read_DS18B20();//读取的温度的高八位存储在TH value=TH; //将高八位数据赋值给value value<<=8;//value左移八位在赋值给value value=value|TL; //与低八位数据相或,将高低两个字节合成一个整形变量 if(value<0x0fff) { value1=value*(0.625); //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度 //温度为正值则直接乘以0.625,温度值扩大10倍,精确到1位小数 }else { value=~value+1; //温度为负值,则取反加一后 value1=value*(-0.625);//温度值扩大10倍,精确到1位小数 } if(value1>=tempH|value1<=tempL)//判断温度是否超过预警值,若超过则蜂鸣器报警 { beep=0; } else{beep=1;} return(value1); //返回读取的温度值 } /*************************对读取得温度进行显示*******************************/ void display(int v) { uchar bai,shi,ge,xiao1; uint temp; uchar flag=0; temp = abs(v); if(v < 0) writeData('-'); else writeData('+'); bai = temp / 1000;//参数temp对1000取整,取出百位数 shi = temp % 1000 / 100; //参数temp对1000取余后对100取整,取出十位数 ge = temp % 100 / 10;//参数temp对100取余后对10取整,取出个位数 xiao1 = temp % 10 ; //参数temp对10取余,取出小数点后一位数 if(bai!= 0) //若百位数不为零,则显示百位数 writeData(datas[bai]); if(shi!=0) //若十位数不为零,则显示十位数 writeData(datas[shi]); if(ge!=0) //若个位数不为零,则显示个位数 writeData(datas[ge]) ; else writeData('0'); //若整数位为零,则小数点前显示0 _nop_(); writeData('.'); //显示小数点 writeData(datas[xiao1]); //显示小数后一位 sign_temp=flag?-temp:temp; } /*************************键盘扫描*******************************/ uchar KeyScan(void) { uchar keyvalue; if(KeyPort!=0xff) //判断是否有键按下 { delayMs(10); //稍微延时 if(KeyPort!=0xff) //判断是否确实有键按下 { keyvalue=KeyPort; //将有键按下后P1口的值赋值给keyvalue while(KeyPort!=0xff); //松手后判断哪个键被按下 switch(keyvalue) { case 0xfe:return 1;break; //P1^0口为低电平,相应定义第1个键被按下 case 0xfd:return 2;break; //P1^1口为低电平,相应定义第2个键被按下 case 0xfb:return 3;break; //P1^2口为低电平,相应定义第3个键被按下 case 0xf7:return 4;break; //P1^3口为低电平,相应定义第4个键被按下 default:return 0;break; //默认返回0 } } } return 0;//没有键被按下时返回0 } /*************************修改报警值*******************************/ void dangerReset() { uchar num,biao; num=KeyScan();//调用键盘扫描程序,读取被按下键的位置 if(num!=0) //有键按下时,进行修改报警值操作 { switch(num) { case 1:if(tempH<1250)tempH++;writeComm(0xc3);display(tempH);break;//第一个键被按下时,若高温预警值不超过125℃,则高温预警值加一并显示 case 2:if(tempH>-550)tempH--;writeComm(0xc3);display(tempH);break;//第二个键被按下时,若高温预警值低于-55℃,则高温预警值减一并显示 case 3:if(tempL<1250)tempL++;writeComm(0xc0+11);display(tempL);break;//第三个键被按下时,若低温预警值不超过125℃,则高温预警值加一并显示 case 4:if(tempL>-550)tempL--;writeComm(0xc0+11);display(tempL);break; //第四个键被按下时,若低温预警值低于-55℃,则高温预警值减一并显示 default:break; } biao=1; //若报警值修改过,则标志位置1 } if(num==0) { if(biao==0) //若没有键被按下,且报警值没有修改过,则显示默认报警值 { writeComm(0xc3); //LCD写指令,显示位置为第二行第四列 display(tempH); //显示高温报警值 writeComm(0xc0+11); //LCD写指令,显示位置为第二行第12列 delayMs(5); //稍作延时 display(tempL);//显示低温报警值 } } } void timer0() interrupt 1 //TO定时器控制 { ET0=0; TH0=(65536-5000)/256; TL0=(65536-5000)%256; sendChangeCmd(); sendReadCmd(); getTmpValue(); if(sign_temp>=35) sign_temp=35; if(sign_temp>=20) { MA=1;MB=0; if(sign_temp==20) { PWM=0; DelayXus(30);return; } // else if(sign_temp==35) { PWM=1; DelayXus(30);return; } PWM=1; DelayXus(sign_temp-20); PWM=0; DelayXus(35-sign_temp); } else { MA=0; MB=0; } ET0=1; } void Inittimer0() //定时器0中断初始化子程序 { TMOD=0x01; TH0=(65536-5000)/256; TL0=(65536-5000)%256; EA=1; ET0=1; TR0=1; } /*******************************主程序*******************************/ void main() { uchar table[] = "T:"; uchar table1[] ="H: L:"; sendChangeCmd(); //发送温度转换指令 init(); //1602初始化 writeComm(0x80); //在第一行显示 writeString(table, 2); writeComm(0xc0); //在第二行显示 writeString(table1, 11); while(1) { delayMs(1000); //延时约1S,温度转换时间需要750ms以上 dangerReset(); //修改报警值报警值 writeComm(0x80+3);//在液晶屏第一行第四列显示 display(getTmpValue());//显示当前温度 sendChangeCmd(); ////发送温度转换指令 Inittimer0(); } } 上面的是我全部的程序,目前仿真实现的是温度显示,上下限温度报警按键设置,,可以驱动电机,但是电机的转速不能控制。求大神修改下,能控制电机的转速。。 |
|
|
|
|
|
#include
#include #include #define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位) #define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位) #define KeyPort P1 //定义按键端口 char sign_temp; ***it MA=P2^5; ***it MB=P2^6; ***it PWM=P2^7; ***it beep=P3^7; //定义蜂鸣器端口 ***it RS = P2^0; //定义1602数据/命令选择端(H/L)端口 ***it LCDEN = P2^1; //定义1602使能端 ***it DQ = P1^7; //可位寻址变量定义,DQ为DS18B20总线端口,用DQ表示P3^2口 int tempH,tempL; //定义高低温度上下限 tempH=350,tempL=200; //定义高温度上限为23℃,低温下限位-10℃ uchar datas[] = {"0123456789"};//表格预存储数据 void delayMs(uint a) //Ms级延时子程序 { uint i, j; for(i = a; i > 0; i--) for(j = 100; j > 0; j--); } void DelayUs2x(unsigned char t) //us级延时子程序 { while(--t); } void DelayXus(int x) { uchar i; while(x--) for (i=0;i<200;i++); } //写命令 void writeComm(uchar comm) { RS = 0; //RS拉低,写指令 P0 = comm;//指令通过P1口传输 LCDEN = 1;//1602LCD使能端拉高允许接收指令 _nop_(); //稍微延时,让指令传输进P1口 LCDEN = 0; //使能端拉低 delayMs(1); //延时约1MS可省略LCD忙检测 } //写数据 void writeData(uchar dat) { RS = 1; //RS拉高,写数据 P0 = dat;//数据通过P1口传输 LCDEN = 1;//1602LCD使能端拉高允许接收数据 nop_();//稍微延时,让数据传输进P1口 LCDEN = 0;//使能端拉低 delayMs(1);//延时约1MS可省略LCD忙检测 } /**//*****************************初始化1602液晶显示*******************************/ void init() { writeComm(0x38);//设置16×2显示,5×7点阵,8位数据借口 writeComm(0x0c); //开LCD显示,不显示光标,光标不闪烁 writeComm(0x06);//当读或写一个字符后光标向后地址指针加一,且光标加一 writeComm(0x01); //显示清屏,清除lcd默认显示数据 } /**************************连续写N个字节*********** str为要连续写入的数据的首地址 length为正数X,表示我们这字符串写入前X位*/ void writeString(uchar * str, uchar length) { uchar i; for(i = 0; i < length; i++) { writeData(str[i]); } } /**//*****************************初始化DS18B20*******************************/ bit Init_DS18B20() { bit tempData; DQ=1; //DQ复位 DelayUs2x(5); //稍做延时 DQ=0; //单片机将DQ拉低 DelayUs2x(200);//精确延时 DelayUs2x(200); DQ=1; //拉高总线 DelayUs2x(50); //15~60us后接收60-240us的存在脉冲 tempData=DQ; //如果tempData=0则初始化成功, tempData=1则初始化失败 DelayUs2x(25); //稍作延时返回 return tempData; } /**//*****************************读取DS18B20*******************************/ uchar read_DS18B20(void) { uchar i=0;//循环辅助 uchar dt=0; //定义接收的数据 for(i=0;i<8;i++)//for循环用于读取总线的八位数据, { DQ=0; //拉低DS18B20总线 dt>>=1; //由于从低位开始接受数据,所以将每次接收到的数据右移一位, DQ=1;//释放总线 if(DQ) //若DS18B20将总线拉高,则读取到的数据为1,进入程序,若为0则将dt右移一位 { dt|=0x80;//将dt与ox80相或后赋给dt,实现一位数据的读取 } DelayUs2x(25);//延时45us } return dt; //返回读取的数据 } /*******************************写数据进DS18B20*******************************/ void writeByte(uchar dat) { uchar j; bit b; for(j = 0; j < 8; j++) { b = dat & 0x01;//取出要写入的数据dat中的一位并赋值给b dat >>= 1; //dat右移一位 if(b) //若取出的数据是1,则进入if语句 { DQ = 0; //将总线拉低 _nop_(); _nop_(); //稍作延时 DQ = 1; //将总线拉高 DelayUs2x(25); //延时约45us } else //若写入的数据是0,则 { DQ = 0; //将总线拉低 DelayUs2x(25); //延时约45us DQ = 1;//释放总线 _nop_(); } } } /*******************************向DS18B20发送温度转换指令*******************************/ void sendChangeCmd() { Init_DS18B20(); // 复位DS18B20 delayMs(1); //稍作延时 writeByte(0xcc); //单点测温,跳过ROM指令 writeByte(0x44); //开始转换温度,转换好的温度存储在暂存器字节0和1 } /*******************************向DS18B20发送温度读取指令*******************************/ void sendReadCmd() { Init_DS18B20();// 复位DS18B20 delayMs(1); //稍作延时 writeByte(0xcc); //单点测温,跳过ROM指令 writeByte(0xbe); //读暂存器 } /*************************将DS18B20取出的温度转换成十进制数并对温度值进行预警判断*******************************/ int getTmpValue() { uint value; //定义无符号整形变量value,16位 int value1; //定义有符号整形变量value1,8位 uchar TL,TH; //定义无符号字符变量TH、TL,8位 sendReadCmd(); //向DS18B20发送读取温度指令 TL=read_DS18B20();//读取的温度的低八位存储在TL TH=read_DS18B20();//读取的温度的高八位存储在TH value=TH; //将高八位数据赋值给value value<<=8;//value左移八位在赋值给value value=value|TL; //与低八位数据相或,将高低两个字节合成一个整形变量 if(value<0x0fff) { value1=value*(0.625); //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度 //温度为正值则直接乘以0.625,温度值扩大10倍,精确到1位小数 }else { value=~value+1; //温度为负值,则取反加一后 value1=value*(-0.625);//温度值扩大10倍,精确到1位小数 } if(value1>=tempH|value1<=tempL)//判断温度是否超过预警值,若超过则蜂鸣器报警 { beep=0; } else{beep=1;} return(value1); //返回读取的温度值 } /*************************对读取得温度进行显示*******************************/ void display(int v) { uchar bai,shi,ge,xiao1; uint temp; uchar flag=0; temp = abs(v); if(v < 0) writeData('-'); else writeData('+'); bai = temp / 1000;//参数temp对1000取整,取出百位数 shi = temp % 1000 / 100; //参数temp对1000取余后对100取整,取出十位数 ge = temp % 100 / 10;//参数temp对100取余后对10取整,取出个位数 xiao1 = temp % 10 ; //参数temp对10取余,取出小数点后一位数 if(bai!= 0) //若百位数不为零,则显示百位数 writeData(datas[bai]); if(shi!=0) //若十位数不为零,则显示十位数 writeData(datas[shi]); if(ge!=0) //若个位数不为零,则显示个位数 writeData(datas[ge]) ; else writeData('0'); //若整数位为零,则小数点前显示0 _nop_(); writeData('.'); //显示小数点 writeData(datas[xiao1]); //显示小数后一位 sign_temp=flag?-temp:temp; } /*************************键盘扫描*******************************/ uchar KeyScan(void) { uchar keyvalue; if(KeyPort!=0xff) //判断是否有键按下 { delayMs(10); //稍微延时 if(KeyPort!=0xff) //判断是否确实有键按下 { keyvalue=KeyPort; //将有键按下后P1口的值赋值给keyvalue while(KeyPort!=0xff); //松手后判断哪个键被按下 switch(keyvalue) { case 0xfe:return 1;break; //P1^0口为低电平,相应定义第1个键被按下 case 0xfd:return 2;break; //P1^1口为低电平,相应定义第2个键被按下 case 0xfb:return 3;break; //P1^2口为低电平,相应定义第3个键被按下 case 0xf7:return 4;break; //P1^3口为低电平,相应定义第4个键被按下 default:return 0;break; //默认返回0 } } } return 0;//没有键被按下时返回0 } /*************************修改报警值*******************************/ void dangerReset() { uchar num,biao; num=KeyScan();//调用键盘扫描程序,读取被按下键的位置 if(num!=0) //有键按下时,进行修改报警值操作 { switch(num) { case 1:if(tempH<1250)tempH++;writeComm(0xc3);display(tempH);break;//第一个键被按下时,若高温预警值不超过125℃,则高温预警值加一并显示 case 2:if(tempH>-550)tempH--;writeComm(0xc3);display(tempH);break;//第二个键被按下时,若高温预警值低于-55℃,则高温预警值减一并显示 case 3:if(tempL<1250)tempL++;writeComm(0xc0+11);display(tempL);break;//第三个键被按下时,若低温预警值不超过125℃,则高温预警值加一并显示 case 4:if(tempL>-550)tempL--;writeComm(0xc0+11);display(tempL);break; //第四个键被按下时,若低温预警值低于-55℃,则高温预警值减一并显示 default:break; } biao=1; //若报警值修改过,则标志位置1 } if(num==0) { if(biao==0) //若没有键被按下,且报警值没有修改过,则显示默认报警值 { writeComm(0xc3); //LCD写指令,显示位置为第二行第四列 display(tempH); //显示高温报警值 writeComm(0xc0+11); //LCD写指令,显示位置为第二行第12列 delayMs(5); //稍作延时 display(tempL);//显示低温报警值 } } } void timer0() interrupt 1 //TO定时器控制 { ET0=0; TH0=(65536-5000)/256; TL0=(65536-5000)%256; sendChangeCmd(); sendReadCmd(); getTmpValue(); if(sign_temp>=35) sign_temp=35; if(sign_temp>=20) { MA=1;MB=0; if(sign_temp==20) { PWM=0; DelayXus(30);return; } // else if(sign_temp==35) { PWM=1; DelayXus(30);return; } PWM=1; DelayXus(sign_temp-20); PWM=0; DelayXus(35-sign_temp); } else { MA=0; MB=0; } ET0=1; } void Inittimer0() //定时器0中断初始化子程序 { TMOD=0x01; TH0=(65536-5000)/256; TL0=(65536-5000)%256; EA=1; ET0=1; TR0=1; } /*******************************主程序*******************************/ void main() { uchar table[] = "T:"; uchar table1[] ="H: L:"; sendChangeCmd(); //发送温度转换指令 init(); //1602初始化 writeComm(0x80); //在第一行显示 writeString(table, 2); writeComm(0xc0); //在第二行显示 writeString(table1, 11); while(1) { delayMs(1000); //延时约1S,温度转换时间需要750ms以上 dangerReset(); //修改报警值报警值 writeComm(0x80+3);//在液晶屏第一行第四列显示 display(getTmpValue());//显示当前温度 sendChangeCmd(); ////发送温度转换指令 Inittimer0(); } } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
程序已经上传,,目前实行的功能有实时显示温度,上下限报警温度可调,电机可以驱动都是转速不能在指定的范围内变动。。想实现的功能:大于35度时全速正转,低于20度停止转动,在20-35度之间转速随着温度的提高而提高。。求大神们修改下程序
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
【瑞萨RA6E2】瑞萨E2S软件安装过程,等待过程玩下97_e2 studio_ZGZZ
331 浏览 0 评论
532 浏览 0 评论
【原创】【RA4M2-SENSOR开发板评测】低功耗+USB综合测试
842 浏览 0 评论
1383 浏览 2 评论
824 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
16912 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-3 14:14 , Processed in 0.895887 second(s), Total 90, Slave 71 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
3742