佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 2481|回复: 9

mikro c- p16f877a 問題

[复制链接]
发表于 28-9-2010 08:37 PM | 显示全部楼层 |阅读模式
本帖最后由 alwayson 于 28-9-2010 08:40 PM 编辑

i. 你要想做什么? 你的应用是什么?
----小弟想在學着用mikroc 來寫一個program . 運用兩個infrared sensor 來做increment 和decrement 然後 display 在 7-segment led(common cathode).
ii. 你想要拿到什么效果
當有物體經過sensor1 然後sensor2。7-segment 會 increment by 1 (minimum 0 可以加到 maximum 10(會display F). 如果經過 sensor2 然後sensor1 會減 1, 可以從 F 減到 0。
iii. 你做了什么
小弟目前能做到 當有物體經過sensor1 。7-segment 會 increment by 1. 可以從 0 一直加 到 10(display F). 如果經過 sensor2 會減 1, 可以減到 0. programming 方面做到了, hardware 也跑得到,順利完成。 有用 real pic simulation 來試跑 ii.
iv. 你遇到了什么问题。
想要從 iii. upgrade 到 ii. 裡提到的效果。 目前已經做好coding 接著也已經試跑, 可是還是有點不穩定,有用 real pic simulation 來 試跑 可是問題出現 在應該 increment 時會執行 decrement 的command , 應該decrement 時 執行increment 的command. 這問題會在不一定的情況發生, 如:從 1 加到 2 ,然後應該increment 到3 試 會 減到1 回去, reset pic 後 問題可能會在應該從 5 加到 6時 突然 會減到4去。
v. 你用什么MCU?
p16f877a
vi. 你用什么语言? ASM /C/PICBasic/Keil?Compiler 版本?
c language. 用mikro c compiler
vii. 有源码吗? 如是抄来的请注明出处, 请放链接。

源码1:還沒’upgrade‘ 的源碼(自己做/已經成功做到的)
void initialize(void)

{
  TRISD=0xF0;                    // Set PORTD pin 4 TO 7 as input. USE PIN 7 AS INCREMENT, PIN 5 AS DECREMENT
  TRISB=0x00;                       // Set PORTB as output
  PORTB=0x7E;                    // Set 7-segment led to zero

}

     int detected_a=0;
     int detected_b=0;
     int d_zero=0x7E, d_one=0x30, d_two=0x6D, d_three=0X79, d_four=0X33, d_five=0x5B, d_six=0x5F, d_seven=0x70, d_eight=0x7F, d_nine=0x7B, d_full=0x47;
     int count=0x00;

void main() {
  initialize();               // Call initialization function


  while(1) {               //Loop forever




if(count<1)
    {
    PORTB=d_zero;
    count=0;
  }
else if(count==1)
    {
    PORTB=d_one;
    }
else if(count==2)
    {
    PORTB=d_two;
    }
else if(count==3)
    {
    PORTB=d_three;
    }
else if(count==4)
    {
    PORTB=d_four;
    }
else if(count==5)
    {
    PORTB=d_five;
    }
else if(count==6)
    {
    PORTB=d_six;
    }
else if(count==7)
    {
    PORTB=d_seven;
    }
else if(count==8)
    {
    PORTB=d_eight;
    }
else if(count==9)
    {
    PORTB=d_nine;
    }
else if(count>9)
    {
    PORTB=d_full;
     count=10;
    }


if(Button(&PORTD,7,1,1))

    {
    detected_a = 1;    //object detected by ir sensor
    }

  if(detected_a && Button(&PORTD,7,1,0))
    {
        count++;
    detected_a = 0;

    }
   


if(Button(&PORTD,5,1,1))
     {
    detected_b = 1;
    }
   if(detected_b && Button(&PORTD,5,1,0))
        {
      if (count > 0)
    {
      count--;
              }
      detected_b = 0;
          }

    }

}


源码2:已經’upgraded‘ 的源碼(自己做/沒有成功)


int detected_a=0;
     int detected_b=0;
     int d_zero=0x7E, d_one=0x30, d_two=0x6D, d_three=0X79, d_four=0X33, d_five=0x5B, d_six=0x5F, d_seven=0x70, d_eight=0x7F, d_nine=0x7B, d_full=0x47;
     int count=0x00;
     
     

void initialize(void)

{
  TRISD=0xF0;                    // Set PORTD pin 4 TO 7 as input. WE USE PIN 7 AS INCREMENT, PIN 5 AS DECREMENT
  TRISB=0x00;                    // Set PORTB as output
  PORTB=0x7E;                    // Set 7-segment led to zero
}

void DETECTION1(void)
{

                                  //EXTRA
                                   if(Button(&PORTD,5,1,1))  //EXTRA
                                     {//EXTRA
                                  detected_b = 1; //EXTRA
                                    }//EXTRA

                                   if(detected_b && Button(&PORTD,5,1,0))  //EXTRA
                                  {
                                  count++;
                                  detected_a = 0;
                                  detected_b = 0;

                                  }
  }

  void DETECTION2(void)
  {
                                   if(Button(&PORTD,7,1,1))      //EXTRA
                                   {                             //EXTRA
                                   detected_a = 1; //EXTRA
                                     } //EXTRA
                                   if(detected_a && Button(&PORTD,7,1,0))   //EXTRA
                                       {
                                          if (count > 0)
                                               {
                                             count--;
                                             }
                                          detected_b = 0;
                                          detected_a = 0;

                                         }
  }




     
     

     
     
     

void main() {
  initialize();               // Call initialization function


  while(1) {               //Loop forever




if(count<1)
    {
    PORTB=d_zero;
    count=0;
  }
else if(count==1)
    {
    PORTB=d_one;
    }
else if(count==2)
    {
    PORTB=d_two;
    }
else if(count==3)
    {
    PORTB=d_three;
    }
else if(count==4)
    {
    PORTB=d_four;
    }
else if(count==5)
    {
    PORTB=d_five;
    }
else if(count==6)
    {
    PORTB=d_six;
    }
else if(count==7)
    {
    PORTB=d_seven;
    }
else if(count==8)
    {
    PORTB=d_eight;
    }
else if(count==9)
    {
    PORTB=d_nine;
    }
else if(count>9)
    {
    PORTB=d_full;
     count=10;
    }


          if(Button(&PORTD,7,1,1)&& Button(&PORTD,5,1,0) )

                        {
                        detected_a = 1;    //object detected by ir sensor
                        }

          if(detected_a && Button(&PORTD,7,1,0))
  
                            {
                                 DETECTION1(); //SWITCH2 DETECTED
                            }

                         //EXTRA






          if(Button(&PORTD,5,1,1)&& Button(&PORTD,7,1,0))
         
                       {
                     detected_b = 1;
                      }
                     
          if(detected_b && Button(&PORTD,5,1,0))
                              {
                              DETECTION2();   //SWITCH1  DETECTED
                              }    //EXTRA



viii. 有电路图吗?
沒有
ix. 你google 了吗? 你的搜索关键字是什么?
沒有google
x. 有照片证明你做的东西吗?还是只是概念性的空谈?
如果一定要照片, 小弟過後會post 上來。

评分

参与人数 1积分 +15 收起 理由
pic + 15 谢谢尊重帮规。

查看全部评分

回复

使用道具 举报


ADVERTISEMENT

发表于 29-9-2010 11:19 AM | 显示全部楼层
可以看电路图吗?
我不熟悉Mickro C, Button() 是怎样用的?
还有, 你的Code 可以大大减化的, 现在忙, 迟些才仔细看你的code。
回复

使用道具 举报

 楼主| 发表于 29-9-2010 06:21 PM | 显示全部楼层
本帖最后由 alwayson 于 29-9-2010 06:53 PM 编辑

可以看电路图吗?
我不熟悉Mickro C, Button() 是怎样用的?
还有, 你的Code 可以大大减化的, 现在忙, ...
pic 发表于 29-9-2010 11:19 AM


這 Button() 是用在雙位開關的, <這裡小弟用infrared sensor 來替代一般的 開關(on/off switch)>. 當 sensor 感應到物體,signal會 從 1 降 到0 (falling edge)時,某某command 會被執行,這裡小弟用來做 increment 或decrement.

if (Button(&ORTB, 0, 1, 1)){ oldstate = 1;}   
if (oldstate && Button(&ORTB, 0, 1, 0))   
{
     這兩行都會用在一起的, 是為了確保 sensor 測到 物體 然後 離開sensor 範圍外(或者switch 被release 後)才可以執行command.
}
switch on= sensor 測到前方有物體 (1)
switch off=sensor 沒測到任何物體 / 物體離開了(0)


第一個源碼 每次detection 只是用一次這個 function
第二個源碼 每次detection 用了兩次, function 在function裡面。。。。(對不起,解釋到很亂水一下






這是小弟使用的硬件。



這是infrared sensor




這是小弟剛畫的電路圖。(剛開始接觸proteus, 看起來很好用,可是不大會用







謝謝 pic 老大 關注。。感激
回复

使用道具 举报

发表于 29-9-2010 06:50 PM | 显示全部楼层
本帖最后由 pic 于 29-9-2010 06:53 PM 编辑

Button() , 是MikroC 的build in Function?
Button(&PORTD,7,1,0)  是什么意思?
Pord D? 7,1,0 是什么?
其实我是要问这个, 要知道这个function 有做Debounce 吗。。

看了你的电路图, Port D button 哪里没有Pull high 吗?如没有, 用4.7K pull high。
回复

使用道具 举报

 楼主| 发表于 29-9-2010 06:59 PM | 显示全部楼层
本帖最后由 alwayson 于 29-9-2010 07:02 PM 编辑
Button() , 是MikroC 的build in Function?
Button(&ampORTD,7,1,0)  是什么意思?
Pord D? 7,1,0 是什 ...
pic 发表于 29-9-2010 06:50 PM



對對, 這就是debounce. 也是mikroc build in function,. 小弟直接 copy/paste help 哪裡的解說吧。



unsigned short Button(unsigned short *port, unsigned short pin, unsigned short time, unsigned short active_state);
【Parameter port specifies the location of the button;

parameter pin is the pin number on designated port and goes from 0..7;
parameter time is a debounce period in milliseconds;

parameter active_state can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.】





example:

reads RB0, to which the button is connected; on transition from 1 to 0 (release of button), PORTD is inverted:
do {
  if (Button(&PORTB, 0, 1, 1)) oldstate = 1;  
if (oldstate && Button(&PORTB, 0, 1, 0)) {  
  PORTD = ~PORTD;    oldstate = 0;  }
} while(1);
回复

使用道具 举报

 楼主| 发表于 29-9-2010 07:44 PM | 显示全部楼层
回复 5# alwayson

是這樣子嗎?


那麼sensor 的那邊也要改了,sensor 沒放電阻。。
回复

使用道具 举报

Follow Us
发表于 1-10-2010 10:35 AM | 显示全部楼层
首先, 感谢你尊重版规,尊重版主,  我回馈你的方法, 就是教你如何用Task Scheduler, State machine, Debouncing.

我没有用你的Mikro C code, 我用CCS C 写了一个, 这个code 对你来说, 应该会有很多疑问, 但是, 一旦大家学会后, 肯定用帮助, 而且, 可以写很复杂的code。, 读Sensor Input 是一个Task, 显示 也是一个task, 你还可以控制什么时候跑那个Task。
他不是真的Multi Tasking, 只是Round Robin Task Scheduler, 但是已经很好用了。


你可以参考, 不明白可以问。




  1. // By pic@cArI
  2. // Date : 1 Oct 2010
  3. #include <16F877A.H>
  4. #fuses   HS,NoPROTECT,noWDT,put,nobrownout
  5. #use delay(clock=20000000)

  6. #use fast_io ( B )
  7. #use fast_io ( d )

  8. #byte PORT_A=0x05
  9. #byte PORT_B=0x06
  10. #byte PORT_C=0x07
  11. #byte PORT_D=0x08
  12. #byte PORT_E=0x09


  13. ///////////////////////////////////////////////////////////////
  14. // I/O Defination
  15. #bit    iInc        =   Port_D.5  // DECREMENT
  16. #bit    iDec        =   Port_D.7  // INCREMENT


  17. // LED Map
  18. byte CONST LED_MAP[11] = {0x7E, 0x30, 0x6D, 0X79, 0X33,0x5B, 0x5F, 0x70, 0x7F,0x7B,0x47};

  19. // GLOBALS
  20. char gc_sensor_timer;
  21. char gc_Display_timer;
  22. int Counter;
  23. int1 fiInc;
  24. int1 fiDec;
  25. ///////////////////////////////////////////////////////////////
  26. //Timer DEFINES
  27. ///////////////////////////////////////////////////////////////
  28. // With a 20 MHz oscillator, a RTCC pre-scaler of 256, and a RTCC
  29. // preload of 195,  we get an rtcc interrupt rate of 100 Hz
  30. // This will be our "tick" clock that we use for various event timers.
  31. // RTCC interrupt rate = Fosc / (4 * rtcc pre-scaler * rtcc pre-load
  32. //                     = 20000000 Hz / (4 * 256*195)
  33. //                     = 100.1 Hz

  34. #define RTCC_PRELOAD (256 - 39)
  35. // Multiply the following values x 10 ms to get the delay times,
  36. // since each timer tick is 10 ms.
  37. #define Sensor_TIMER_TICKS         2       // 20 ms
  38. #define DISPLAY_TIMER_TICKS        10     //  100 ms

  39. //--------------------------------------------------------
  40. // The rtcc interrupt occurs when the rtcc rolls over from FF to 00.
  41. // We it to interrupt at a 100 Hz rate.
  42. //
  43. #int_rtcc
  44. void rtcc_isr(void)
  45. {
  46.    // Reload the RTCC, so it will keep overflowing every 10 ms.
  47.    set_rtcc(RTCC_PRELOAD);

  48.    // Decrement any timers that are running.
  49.    if(gc_sensor_timer)
  50.       gc_sensor_timer--;

  51.    if(gc_Display_timer)
  52.       gc_Display_timer--;

  53. }



  54. void check_sensor(void)
  55. {
  56.    char new_status;
  57.    #define  SwCounterSize 2
  58.    static int debounce_counter_iInc;
  59.    static int debounce_counter_iDec;

  60.    if(gc_sensor_timer)
  61.       return;
  62.    else
  63.      gc_sensor_timer = sensor_TIMER_TICKS;

  64.    // Check Increment Sensor input and debounce
  65.    if(iInc)                                          
  66.    {
  67.       if(bit_test(++debounce_counter_iInc,SwCounterSize))  
  68.       {
  69.          --debounce_counter_iInc;                        
  70.          fiInc=1;                                       
  71.       }
  72.    }
  73.    else
  74.    {
  75.       if(--debounce_counter_iInc==0)                     
  76.       {
  77.          ++debounce_counter_iInc;                        
  78.          fiInc=0;                                         
  79.       }
  80.    }

  81.    // Check Decrement Sensor input and debounce
  82.    if(iDec)                                          
  83.    {
  84.       if(bit_test(++debounce_counter_iDec,SwCounterSize))  
  85.       {
  86.          --debounce_counter_iDec;                        
  87.          fiDec=1;                                       
  88.       }
  89.    }
  90.    else
  91.    {
  92.       if(--debounce_counter_iDec==0)                     
  93.       {
  94.          ++debounce_counter_iDec;                        
  95.          fiDec=0;                                         
  96.       }
  97.    }
  98. }


  99. int Inc_State=0;
  100. int Dec_State=0;
  101. int fUpdateRequire;
  102. int fiIncOld;
  103. //--------------------------------------------------------
  104. void check_Display(void)
  105. {
  106.    if(gc_DISPLAY_timer)
  107.       return;
  108.    else
  109.       gc_DISPLAY_timer  = DISPLAY_TIMER_TICKS;

  110.    Switch (Inc_State)
  111.    {
  112.       case 0:  // wait for signal
  113.          if(fiInc==1)
  114.          {
  115.             Inc_State=1;
  116.          }
  117.          break;

  118.       case 1:  // signal high, wait it go low
  119.          if(fiInc==0)
  120.          {
  121.             Inc_State=2;
  122.          }
  123.          break;   

  124.       case 2:  // We get the signal, increase it
  125.             
  126.             Counter++;
  127.             if(Counter>10)counter=10;
  128.             Inc_State=0; // back, wait for next signal
  129.          break;   
  130.    
  131.    }


  132.    Switch (Dec_State)
  133.    {
  134.       case 0:  // wait for signal
  135.          if(fiDec==1)
  136.          {
  137.             Dec_State=1;
  138.          }
  139.          break;

  140.       case 1:  // signal high, wait it go low
  141.          if(fiDec==0)
  142.          {
  143.             Dec_State=2;
  144.          }
  145.          break;   

  146.       case 2:  // We get the signal, increase it
  147.             
  148.             if(Counter>0)Counter--;
  149.             
  150.             Dec_State=0; // back, wait for next signal
  151.          break;   
  152.    
  153.    }
  154.    
  155.    // Display to 7Seg
  156.    Port_B=LED_MAP[Counter];

  157. }



  158. void main()
  159. {
  160. //              76543210
  161.    set_tris_b(0b00000000);
  162.    set_tris_D(0b10100000);
  163.    Port_B=0;
  164.    Port_D=0;

  165.    gc_sensor_timer = sensor_TIMER_TICKS;
  166.       gc_DISPLAY_timer  = DISPLAY_TIMER_TICKS;

  167.    // Setup the RTCC.
  168.    setup_counters(RTCC_INTERNAL, RTCC_DIV_256);
  169.    set_rtcc(RTCC_PRELOAD);

  170.    enable_interrupts(INT_RTCC);
  171.    enable_interrupts(GLOBAL);

  172.    Counter=0;// reset to 0
  173.    while(1)
  174.    {
  175.       check_sensor();
  176.       check_Display();
  177.    }
  178. }

复制代码
回复

使用道具 举报

 楼主| 发表于 2-10-2010 11:20 AM | 显示全部楼层
回复 7# pic


    哇。。需要一段時間來消化, ccs c 的 format 真的很不同。。
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 2-10-2010 11:57 AM | 显示全部楼层
小弟剛剛成功做到 ii 的效果了,是用mikro c。 很有滿足感




請問pic 老大,那個c compiler 會比較好用?小弟只接觸過 visual basic 和 mikroc, Hi-tech 看起來有點難用。。每個compilere 好像都用不一樣的format
回复

使用道具 举报

 楼主| 发表于 2-10-2010 05:21 PM | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 4-6-2024 06:32 PM , Processed in 0.067677 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表