欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
單片機(jī)自行車碼表+PWM調(diào)速程序問(wèn)題
[打印本頁(yè)]
作者:
小龍林呀
時(shí)間:
2019-5-19 13:10
標(biāo)題:
單片機(jī)自行車碼表+PWM調(diào)速程序問(wèn)題
自行車速度里程測(cè)量,使用的是外部中斷0計(jì)數(shù)里程脈沖,定時(shí)器0計(jì)算時(shí)間
PWM調(diào)速,使用定時(shí)器1產(chǎn)生PWM波形
兩個(gè)程序單獨(dú)使用都沒(méi)問(wèn)題,
但是合在一起,兩個(gè)定時(shí)器一起用就出現(xiàn)問(wèn)題,錯(cuò)誤首先在數(shù)碼管位選端出現(xiàn)流水燈效果,第一次切割后恢復(fù)正常,沒(méi)有了流水燈效果,速度測(cè)量失效。里程測(cè)量還能用
附程序代碼:
//速度:?jiǎn)挝粸?m/h 里程單位cm
#include<reg51.h>
#define duan P0 //段選
#define wei P2 //位選P2^4-P2^7
#define zhouchang 200 //車輪周長(zhǎng)200cm
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
uchar code display1[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管驅(qū)動(dòng)信號(hào)0---9,共陽(yáng)
uchar code bitcode[]={0x7f,0xbf,0xdf,0xef}; //數(shù)碼管位選掃描信號(hào) 0111 1111
sbit change = P3^4; //切換按鍵
bit flag = 1; //切換標(biāo)記
bit flag1=0; //第一次切割
uchar point1 = 0; //小數(shù)點(diǎn)標(biāo)記,速度
uchar buf1[]={0,0,0,0}; //數(shù)碼管該顯示的數(shù)字,高-----低,速度
uchar point2 = 0; //小數(shù)點(diǎn)標(biāo)記,里程
uchar buf2[]={0,0,0,0}; //數(shù)碼管該顯示的數(shù)字,高------低,里程
uchar num = 4; //數(shù)碼管第num位
uint time_counter = 0; //每10次切割時(shí)差,定時(shí)計(jì)數(shù)
uint time_counter8 = 0; //8s定時(shí)計(jì)數(shù)
uint external_counter = 0; //外部中斷計(jì)數(shù)
ulong s = 0;//里程
ulong speed = 0;//速度
sbit PWM=P1^0; //PWM所使用的一些量
sbit key1=P1^1;
sbit key2=P1^2;
uchar zkb,w;// zkb指占空比
void delay1m(uchar x)//MS級(jí)延時(shí)函數(shù)
{
uchar i,j;
for(i = 0;i < x;i++) //連續(xù)x次,約 x ms
for(j=0;j<120;j++); //數(shù)120 次,約1 ms
}
void keyscan() //鍵盤(pán)掃描
{
P1=0XFF;
while(1)
{
if(key1==0)
{
delay1m(5);
if(key1==0)
{
if(zkb<10)
{
zkb++;
zkb++;
}
while(!key1);
}
}
if(key2==0)
{
delay1m(5);
if(key2==0)
{
if(zkb>0)
{
zkb--;
}
while(!key2);
}
}
}
}
void init_display() //初始顯示0.0.0.0
{
uchar i;
for(i = 0;i < 4;i++)
{
wei = bitcode[num - 1];
duan = display1[buf1[num--]];
delay1m(1);
if(num == 0)num = 4;
}
}
void time0_int0_init() //定時(shí)器0和外部中斷0的初始化函數(shù)
{
TMOD |= 0x11;
TH1=(65536-10)/256;
TL1=(65536-10)%256;
TL0 = (65536 - 5000) % 256;//12M晶振,5ms定時(shí)
TH0 = (65536 - 5000) / 256;
IT0 = 1;//外部中斷0,負(fù)跳變觸發(fā)方式
TR0 = 0;
ET0 = 1;
EX0 = 1;
EA = 1;
ET1=1;
TR1=1;
}
void display_function() //顯示函數(shù)
{
if(flag == 0)//顯示速度
{
switch(point1)
{
case 0:wei = bitcode[num-1];
duan = display1[buf1[num-1]];
num--;
break;//速度顯示 0
case 1:if(num == 1)
{ wei = bitcode[num-1];
duan = 0x7f&display1[buf1[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf1[num-1]];
num--;
}
break;//最高位小數(shù)點(diǎn)亮
case 2:if(num == 2)
{
wei = bitcode[num-1];
duan = 0x7f&display1[buf1[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf1[num-1]];
num--;
}
break;//第二高位小數(shù)點(diǎn)亮
case 3:if(num == 3)
{
wei = bitcode[num-1];
duan = 0x7f&display1[buf1[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf1[num-1]];
num--;
}
break;//第三高位小數(shù)點(diǎn)亮
default:break;
}
if(num == 0)num = 4;
}
else if(flag == 1)//顯示里程
{
switch(point2)
{
case 0:wei = bitcode[num-1];
duan = display1[buf2[num-1]];
num--;
break;//里程顯示 0
case 1:if(num == 1)
{
wei = bitcode[num-1];
duan = 0x7f&display1[buf2[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf2[num-1]];
num--;
}
break;//最高位小數(shù)點(diǎn)亮
case 2:if(num == 2)
{
wei = bitcode[num-1];
duan = 0x7f&display1[buf2[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf2[num-1]];
num--;
}
break;//第二高位小數(shù)點(diǎn)亮
case 3:if(num == 3)
{
wei = bitcode[num-1];
duan = 0x7f&display1[buf2[num-1]];
num--;
}
else
{
wei = bitcode[num-1];
duan = display1[buf2[num-1]];
num--;
}
break;//第三高位小數(shù)點(diǎn)亮
default:break;
}
if(num == 0)num = 4;
}
}
//====================================主函數(shù)=========================================================
void main()
{
time0_int0_init();//定時(shí)器0和外部中斷0的初始化
while(!TR0) //上電一直未切割時(shí)就顯示 0.0.0.0
{
init_display();
}
zkb=4;
while(1)
{
keyscan();
if(!change)//按下切換按鍵顯示里程
{
delay1m(5);
if(!change)
{
flag = ~flag;
}
while(!change);
}
}
}
//==================================定時(shí)器0中斷函數(shù)================================
void time0_interrupt() interrupt 1
{
TL0 = (65536 - 5000) % 256;// 12M晶振,5ms定時(shí)
TH0 = (65536 - 5000) / 256;
display_function();
time_counter++;
time_counter8++;
if(time_counter8 >= 1600)//大于8s沒(méi)切割,車子視為停下了,速度為:0,但里程還記著
{
time_counter8 = 0;
speed = 0;//速度為 0
point1 = 0;
buf1[3] = speed%10; //顯示數(shù)組賦值
buf1[2] = speed/10%10;
buf1[1] = speed/100%10;
buf1[0] = speed/1000%10;
}
}
void time1() interrupt 3 //定時(shí)器1中斷函數(shù)
{
TH1=(65536-10)/256;
TL1=(65536-10)%256;
++w;
if(w>10)
{
w=0;
};
if(w<=zkb)
{
PWM=1;
}
else PWM=0;
}
//==================================外部中斷0中斷函數(shù)=========================
void int0_interrupt()interrupt 0
{
external_counter++;
if(external_counter ==1 )TR0 = ~TR0; //第一次切割打開(kāi)定時(shí)器0
if(external_counter == 65535)external_counter = 0;
time_counter8 = 0; //只要8秒內(nèi)有切割,車子就一直在運(yùn)行
if(external_counter % 10 == 0)//切割10次 更新下速度
{ //*5是因?yàn)橹袛嘁淮问?MS
if(flag1==0) //第一次切割更新速度
{
speed =((ulong)(36000)*zhouchang)/(time_counter * 5);
flag1=1;
}
else if(flag1==1){speed =((ulong)(36000)*10*zhouchang)/(time_counter * 5);} //不是第一次切割
if((speed >= 100)&&(speed < 1000)) //100 ---- 1000 3位整數(shù)
{
point1 = 1;
buf1[3] = speed%10;
buf1[2] = speed/10%10;
buf1[1] = speed/100%10;
buf1[0] = 0;
}
else if((speed >= 1000)&&(speed < 10000)) //1000 ---- 10000 4位整數(shù)
{
point1 = 1;
speed = (uint)speed;
buf1[3] = speed%10;
buf1[2] = speed/10%10;
buf1[1] = speed/100%10;
buf1[0] = speed/1000%10;
}
else if((speed >= 10000)&&(speed < 100000)) //10000 ----- 100000 5位整數(shù)
{
point1 = 2;
buf1[3] = speed/10%10;
buf1[2] = speed/100%10;
buf1[1] = speed/1000%10;
buf1[0] = speed/10000%10;
}
else if((speed >= 100000)&&(speed < 1000000)) //100000 ------ 1000000 6位整數(shù)
{
point1 = 3;
buf1[3] = speed/100%10;
buf1[2] = speed/1000%10;
buf1[1] = speed/10000%10;
buf1[0] = speed/100000%10;
}
time_counter = 0;
}
if(external_counter % 10 == 0)//每切割10次 更新下里程
{
s = (ulong)external_counter * zhouchang; //里程:?jiǎn)挝粸?nbsp; cm
if((s >= 1000)&&(s < 10000))
{
point2 = 1; // 0.012 001212
buf2[3] = s/100%10;
buf2[2] = s/1000%10;
buf2[1] = 0;
buf2[0] = 0;
}// 4位整數(shù)
else if((s >= 10000)&&(s < 100000))
{
point2 = 1;
buf2[3] = s/100%10;
buf2[2] = s/1000%10;
buf2[1] = s/10000%10;
buf2[0] = 0;
}// 5位整數(shù) 0.123 012345
else if((s >= 100000)&&(s < 1000000))
{
point2 = 1;
buf2[3] = s/100%10;
buf2[2] = s/1000%10;
buf2[1] = s/10000%10;
buf2[0] = s/100000%10;
} // 6位整數(shù) 1.234 1234 56
else if((s >= 1000000)&&(s < 10000000))
{
point2 = 2;
buf2[3] = s/1000%10;
buf2[2] = s/10000%10;
buf2[1] = s/100000%10;
buf2[0] = s/1000000%10;
}// 7位整數(shù) 1234 567
else if((s >= 10000000)&&(s < 100000000))
{
point2 = 3;
buf2[3] = s/10000%10;
buf2[2] = s/100000%10;
buf2[1] = s/1000000%10;
buf2[0] = s/10000000%10;
} // 8位整數(shù) 1234 5678
}
}
復(fù)制代碼
作者:
yzwzfyz
時(shí)間:
2019-5-20 08:48
1、延時(shí)不要用DELAY硬件延時(shí)程序做!
2、中斷服務(wù)程序中:不要做顯示、復(fù)雜的計(jì)算!
你能做到以上兩點(diǎn)就可以了。
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1