|
cuihaodianzi 發表于 2019-10-22 19:17 程序來了,大神 #include<reg52.h>//51單片機頭文件 #define uchar unsigned char//宏定義 #define uint unsigned int uchar code digit[]="0123456789";//定義字符數組數字 uchar disp[8];//存儲拆開的數 uint cnt;//中斷次數 uchar v;//電機0速度 uchar s;//電機1速度 uchar flag; //計滿1秒鐘標志位 ///////// sbit rs=P2^6;//數據命令選擇 sbit rw=P2^5;//讀寫控制信號 sbit e=P2^7;//使能信號 /////////////// void delay_50us(uint t)//50us延時函數 { uchar j; for(;t>0;t--) for(j=19;j>0;j--); } ///////////// /* void delay_50ms(uint t)//50ms延時函數 { uint j; for(;t>0;t--) for(j=6245;j>0;j--); } ///////// */ void write_com(uchar com)//寫地址 { e=0; rs=0; rw=0; P0=com; delay_50us(10); e=1; delay_50us(10); e=0; } /////// void write_data(uchar dat)// 寫數據 { e=0; rs=1; rw=0; P0=dat; delay_50us(10); e=1; delay_50us(10); e=0; } ////// void init(void)//液晶初始化 { delay_50us(300); write_com(0x38); delay_50us(100); write_com(0x38); delay_50us(100); write_com(0x38); write_com(0x38); write_com(0x08); write_com(0x01); write_com(0x06); write_com(0x0c); } ///////////// void writeaddress(uchar x)//指定字符的實際地址 { write_com(x|0x80);//顯示位置的確定方法規定為“80h+地址碼x“ } ////////// void display_sym(void)//顯示速度提示符 { writeaddress(0x00);//寫顯示地址第一行第一列 write_data('v');//寫數據v write_data('=');//寫數據= writeaddress(0x00+0x40);//寫顯示地址第一行第一列 write_data('s');//寫數據v write_data('=');//寫數據= } ////// void dispose()// { disp[0]=v/1000; disp[1]=(v%1000)/100; disp[2]=(v/100)/10; disp[3]=v%10; disp[4]=s/1000; disp[5]=(s%1000)/100; disp[6]=(s/100)/10; disp[7]=s%10; } ///////////// void display_val(void) { writeaddress(0x02);//寫顯示地址,第一行第三列 write_data(digit[disp[0]]);//千 write_data(digit[disp[1]]);//百 write_data(digit[disp[2]]);//時 write_data(digit[disp[3]]);//個 writeaddress(0x02+0x40);//寫顯示地址,第2行第三列 write_data(digit[disp[4]]);//千 write_data(digit[disp[5]]);//百 write_data(digit[disp[6]]);//時 write_data(digit[disp[7]]);//個 } //////// void display_uint(void)//顯示速度單位 { writeaddress(0x06);//第1行第7列 write_data('r');//千 write_data('/');//百 write_data('m');//時 write_data('i');//個 write_data('n');//個 writeaddress(0x06+0x40);//第2行第7列 write_data('r');//千 write_data('/');//百 write_data('m');//時 write_data('i');//個 write_data('n');//個 } void initial()//初始化 { TMOD=0x55; //定時器T1工作與計數器模式1,定時器T0工作于計數器模式1 RCAP2H=(65536-50000)/256; RCAP2L=(65536-50000)%256; ET2=1; TR2=1; EA=1; } /////// void main() { init(); v=0; s=0; initial(); cnt=0; display_sym(); display_uint(); while(1) { TR1=1; TR0=1; TH1=0; TL1=0; TH0=0; TL0=0; flag=0; // 時間還未滿1分鐘 while(flag==1); // 時間未滿等待 v=(TH1*256+TL1)*60/20; // 計算速度,每周產生20個脈沖 s=(TH0*256+TL0)*60/20; // 計算速度,每周產生20個脈沖 dispose(); display_val(); } } ////// void time2() interrupt 5//定時器T2中斷服務程序 { TF2=0; cnt++; if(cnt==20) { flag=1; cnt=0; } } |
csmyldl 發表于 2019-10-22 18:35 大神,不是這樣的吧,我們是用電機風扇葉來測的,有間隙的啊 |
cuihaodianzi 發表于 2019-10-22 19:17 #include<reg52.h>//51單片機頭文件 #define uchar unsigned char//宏定義 #define uint unsigned int uchar code digit[]="0123456789";//定義字符數組數字 uchar disp[8];//存儲拆開的數 uint cnt;//中斷次數 uchar v;//電機0速度 uchar s;//電機1速度 uchar flag; //計滿1秒鐘標志位 ///////// sbit rs=P2^6;//數據命令選擇 sbit rw=P2^5;//讀寫控制信號 sbit e=P2^7;//使能信號 /////////////// void delay_50us(uint t)//50us延時函數 { uchar j; for(;t>0;t--) for(j=19;j>0;j--); } ///////////// /* void delay_50ms(uint t)//50ms延時函數 { uint j; for(;t>0;t--) for(j=6245;j>0;j--); } ///////// */ void write_com(uchar com)//寫地址 { e=0; rs=0; rw=0; P0=com; delay_50us(10); e=1; delay_50us(10); e=0; } /////// void write_data(uchar dat)// 寫數據 { e=0; rs=1; rw=0; P0=dat; delay_50us(10); e=1; delay_50us(10); e=0; } ////// void init(void)//液晶初始化 { delay_50us(300); write_com(0x38); delay_50us(100); write_com(0x38); delay_50us(100); write_com(0x38); write_com(0x38); write_com(0x08); write_com(0x01); write_com(0x06); write_com(0x0c); } ///////////// void writeaddress(uchar x)//指定字符的實際地址 { write_com(x|0x80);//顯示位置的確定方法規定為“80h+地址碼x“ } ////////// void display_sym(void)//顯示速度提示符 { writeaddress(0x00);//寫顯示地址第一行第一列 write_data('v');//寫數據v write_data('=');//寫數據= writeaddress(0x00+0x40);//寫顯示地址第一行第一列 write_data('s');//寫數據v write_data('=');//寫數據= } ////// void dispose()// { disp[0]=v/1000; disp[1]=(v%1000)/100; disp[2]=(v/100)/10; disp[3]=v%10; disp[4]=s/1000; disp[5]=(s%1000)/100; disp[6]=(s/100)/10; disp[7]=s%10; } ///////////// void display_val(void) { writeaddress(0x02);//寫顯示地址,第一行第三列 write_data(digit[disp[0]]);//千 write_data(digit[disp[1]]);//百 write_data(digit[disp[2]]);//時 write_data(digit[disp[3]]);//個 writeaddress(0x02+0x40);//寫顯示地址,第2行第三列 write_data(digit[disp[4]]);//千 write_data(digit[disp[5]]);//百 write_data(digit[disp[6]]);//時 write_data(digit[disp[7]]);//個 } //////// void display_uint(void)//顯示速度單位 { writeaddress(0x06);//第1行第7列 write_data('r');//千 write_data('/');//百 write_data('m');//時 write_data('i');//個 write_data('n');//個 writeaddress(0x06+0x40);//第2行第7列 write_data('r');//千 write_data('/');//百 write_data('m');//時 write_data('i');//個 write_data('n');//個 } void initial()//初始化 { TMOD=0x55; //定時器T1工作與計數器模式1,定時器T0工作于計數器模式1 RCAP2H=(65536-50000)/256; RCAP2L=(65536-50000)%256; ET2=1; TR2=1; EA=1; } /////// void main() { init(); v=0; s=0; initial(); cnt=0; display_sym(); display_uint(); while(1) { TR1=1; TR0=1; TH1=0; TL1=0; TH0=0; TL0=0; flag=0; // 時間還未滿1分鐘 while(flag==1); // 時間未滿等待 v=(TH1*256+TL1)*60/20; // 計算速度,每周產生20個脈沖 s=(TH0*256+TL0)*60/20; // 計算速度,每周產生20個脈沖 dispose(); display_val(); } } ////// void time2() interrupt 5//定時器T2中斷服務程序 { TF2=0; cnt++; if(cnt==20) { flag=1; cnt=0; } } |
|
程序呢 ? 這樣問貌似沒法回答 |
| 應該是傳感器位置裝的不對,從圖上看是紅外對管進行檢測,需在飛輪上鉆一個孔,光從孔中通過,當飛輪轉動時測出對管產生的脈沖間隔時間來計算速度的 |