作者vincentno1 (Vincent老頭)
看板ASM
標題[問題] 用c語言寫8051 腳踏車測速器
時間Sat Jun 13 13:06:54 2009
我試著想用8051寫一個腳踏車測速器
大概的設計是這樣:
使用at89c51晶片
用keil uVision3寫c語言
腳踏車車輪每轉一圈會經由Schmitt trigger送一個負源觸發到8051的pin12(外源中斷)
然後利用8051計算其周期而算出速率
再由8051的P2輸出二位數到兩個7447在到7段LED數字顯示器
現在Schmitt trigger與7447的部份都沒有問題
問題是我用keil uVision3寫的程式燒進去都不會WORK
(就連寫最簡單的跑馬燈也不WORK)
是不是我在寫C程式的時候少了些什麼?
請高手幫我看看
-----------------------------------------------------------------
#include <regx51.h>
int counter,i; //counter為計時器; i為輪胎圈數;
int a,b,c,d,e; //A作為總數值(速率) B輸出暫存 C十位數暫存 D個位數暫存 E延遲用變
數
float period,r,p; //period周期; r為輪胎半徑;
main()
{
//計時器
TMOD=0x00; //mode 0
TH0=(8192-1000)/12; //1000us=1ms
TL0=(8192-1000)%12;
TR0=1; //timer start
//中斷器
IE=0x83; // EX0=1; ET0=1; EA=1;
TCON=0x01; // 使外源中斷1為負源處發;
//速率計算and二位數顯示
a=0x00; //將速率設0
P2=a; //先使兩個七段都顯示0
for(e=0;e<3200;e++); //延遲
while(1)
{
r=0.0005; //設r為0.0005 km
p=period/1000/3600; //把周期單位改成hr
a=2*3.14*r/p; //計算出速率(km/hr)
if(a>99) a=99; //防暴表
c=a/10; //將總數除以10取商數得到十位
d=a%10; //將總數除以10取餘數得到個位
c=c<<4; //將十位數(二進制)左移4位數
d=d&0x0f; //將各位數的上面四位數清為零
b=c+d; //將十位及個位數合併成8BIT BCD
P2=b; //將有個位十位數的BCD碼由P2輸出
for(e=0;e<15000;e++); //延遲
}
}
void timer0_int(void)interrupt 1 //計時器中斷0的副程式
{
TH0=(8192-1000)/12;
TL0=(8192-1000)%12;
counter++;
}
void int0(void)interrupt 0 //外源中斷0副程式
{
i++;
if(i==1) counter=0; //開始計時
if(i==6) //取五圈的平均周期
{
period=counter/5; //周期單位為ms
i=0;
}
}
-----------------------------------------------------------------
謝謝...
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.214.71
1F:推 ruemann:我沒用過這顆,是用他的ISP downlaod吧,看有沒有範例可試 06/13 16:24
2F:推 hayden0828:C51沒有ISP吧= ="如果跑馬燈等程式也不能燒,應該先從 06/13 17:58
3F:→ hayden0828:燒錄界面開始檢查吧 06/13 17:59
4F:→ MasterChang:有沒有ISP介面跟ISP燒錄沒啥關係....XD 06/13 19:22
5F:→ vincentno1:可是我燒書上附的hex檔是可以燒的 但我自己用c寫的都不 06/13 19:45
6F:→ vincentno1:行 不知道是不是我寫c哪裡寫錯還是軟體用不對 06/13 19:46
7F:→ vincentno1:因為我跑馬燈的程式都是抓網路上別人寫的 06/13 19:46
8F:→ vincentno1:不知有沒有有經驗的高手可以指點一下 06/13 19:46
9F:→ ksmrt0123:既然最簡單的跑馬燈也不WORK, 怎不先debug跑馬燈? 06/14 01:05
10F:→ ksmrt0123:而且跑馬燈並不簡單. 可考慮用更簡單的程式try 06/14 01:08
11F:→ vincentno1:有...我一直在debug...就是沒半法才來請問大家 06/14 01:43
12F:推 stool100:住哪?一小時 500 可以請我 06/14 01:56
13F:→ vincentno1:QQ 我再自己試試 不行在拜託樓上 我在台北市.. 06/14 15:58
14F:→ ksmrt0123:有可能是keil設定問題... memory model選錯? 06/14 21:03
15F:→ vincentno1:可能是樓上說的耶?謝謝你 我去看看 06/15 03:01
16F:→ vincentno1:不過我剛才用組語寫已經成功了 06/15 03:01
17F:→ vincentno1:謝謝大家 06/15 03:34
18F:噓 danny789:你發的問題,雖自己解決了,也有義務將如何解決的說明吧? 06/15 16:33
19F:推 around0423:那也用不著噓吧...推回來 06/16 16:01
20F:→ vincentno1:唔 其實我沒有解決...我只是放棄c語言而改用組合語言寫 06/17 00:49
21F:→ vincentno1:如果大家知道我c語言到底問題出在哪 感激不盡 06/17 00:50
22F:推 ruemann:你把編譯過的hex反組譯回去大概就能找出問題了 06/17 01:37
23F:→ vincentno1:哦!還有這招 好 我周末來試試 謝謝樓上 06/17 20:25
24F:推 utility:你的程式可能被最佳化把一部份被省略掉了 06/17 22:26
25F:推 wuonline:應該被樓上說中了 06/17 23:39
26F:→ wuonline:for(e=0;e<15000;e++); //延遲 06/17 23:40
27F:→ wuonline:這一行的延遲 單只有一層for迴圈的話 編譯的時候就會被省 06/17 23:41
28F:→ wuonline:略掉了 所以通常看到的都使用兩層for迴圈來做延遲的動作 06/17 23:41
29F:推 wuonline:void delay1ms(int count) 06/17 23:44
30F:→ wuonline:{ int i,j; 06/17 23:44
31F:→ wuonline: for(i=0;i<count;i++) 06/17 23:44
32F:→ wuonline: for(j=0;j<122;j++); } 06/17 23:45
33F:→ wuonline:上面是比較常見使用for迴圈來做延遲的程式寫法 06/17 23:45
34F:→ vincentno1:好 我明天下午就去試試 感謝 06/18 21:32
35F:→ utility:把list檔弄出來看.或是先設定不要做最佳化看看. 06/18 21:51