洪嵐峰 發表於 2023-4-17 20:10:55

PIC16F877A PIC12F508 PIC16F886

製作機器人需要設計和製造機械結構、電路連接、編寫控制程序等多方面的工作。以下是一些可能需要的零件和連接方式,以及相關的程式碼參考。

零件清單:
PIC16F877A 微控制器 x1
PIC12F508 微控制器 x1
PIC16F886 微控制器 x1
雙向直流馬達驅動器模塊 x2
直流馬達 x2
輪子 x2
9V 電池 x1
5V 電源模塊 x1
陀螺儀模塊 x1
超聲波模塊 x1
紅外線模塊 x1
其他機械結構和傳感器等
連接方式:
將三個微控制器按照需要連接,可以使用串行通信或其他方式進行通信。
馬達驅動器模塊需要與 PIC16F877A 微控制器連接,以控制馬達的轉動方向和速度。
陀螺儀、超聲波和紅外線模塊等傳感器需要與 PIC12F508 微控制器連接,以收集外部環境信息。
機械結構和其他傳感器需要與 PIC16F886 微控制器連接,以實現更複雜的控制功能。
程式碼參考:
以下是一些可能用到的控制程序示例,供參考:
馬達控制:使用 PWM 控制馬達速度和方向。

#include <16f877a.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT
#use fast_io(B)

#byte TRISB = 0x86
#byte PORTB = 0x06

#byte CCP1CON = 0x17
#byte CCPR1L = 0x15
#byte T2CON = 0x12
#byte PR2 = 0x92

void main() {
   TRISB = 0b00000000;   // B0, B1 為輸出
   CCP1CON = 0b00001100; // PWM 模式,線性輸出,P1A 為 PWM 腳位
   T2CON = 0b00000110;   // TMR2 計數器,使用 1:16 預分頻
   PR2 = 249;            // PWM 周期為 20ms,TMR2 最大值為 249
  
while(1) {
// 控制馬達 1 正轉
PORTB = 0b00000001; // B0 設為高電位
CCPR1L = 100; // PWM 脈寬設為 100/255,控制馬達轉速
delay_ms(1000); // 持續 1 秒
// 控制馬達 1 反轉
PORTB = 0b00000010; // B1 設為高電位
CCPR1L = 150; // PWM 脈寬設為 150/255,控制馬達轉速
delay_ms(1000); // 持續 1 秒
// 停止馬達 1
PORTB = 0b00000000; // B0, B1 設為低電位
CCPR1L = 0; // PWM 脈寬為 0,馬達停轉
delay_ms(1000); // 持續 1 秒
}
}

#include <16f877a.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT
#use fast_io(B)

#byte TRISB = 0x86
#byte PORTB = 0x06

#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW)

#define GYRO_ADDR 0x68

void main() {
   int16_t gyro_x = 0, gyro_y = 0, gyro_z = 0;
   int16_t gyro_x_offset = 0, gyro_y_offset = 0, gyro_z_offset = 0;
   int i = 0;
   TRISB = 0b00000000;
   i2c_start();
   i2c_write(GYRO_ADDR);
   i2c_write(0x6B);
   i2c_write(0x00);
   i2c_stop();
   delay_ms(1000);
   while(1) {
      i2c_start();
      i2c_write(GYRO_ADDR);
      i2c_write(0x43);
      i2c_start();
      i2c_write(GYRO_ADDR | 0x01);
      gyro_x = (int16_t)(i2c_read() << 8);
      gyro_x |= i2c_read();
      gyro_y = (int16_t)(i2c_read() << 8);
      gyro_y |= i2c_read();
      gyro_z = (int16_t)(i2c_read() << 8);
      gyro_z |= i2c_read();
      i2c_stop();
      if (i < 100) {
         gyro_x_offset += gyro_x;
         gyro_y_offset += gyro_y;
         gyro_z_offset += gyro_z;
         i++;
      }
      else {
         gyro_x -= gyro_x_offset / 100;
         gyro_y -= gyro_y_offset / 100;
         gyro_z -= gyro_z_offset / 100;

     // 控制動作
     if (gyro_y > 1000) {
        // 往前走
        PORTB = 0b00000011;    // B0, B1 設為高電位
        delay_ms(500);         // 持續 0.5 秒
        PORTB = 0b00000000;    // B0, B1 設為低電位
        delay_ms(500);         // 持續 0.5 秒
     }
     else if (gyro_y < -1000) {
        // 往後走
        PORTB = 0b00000110;    // B2, B3 設為高電位
        delay_ms(500);         // 持續 0.5 秒
        PORTB = 0b00000000;    // B2, B3 設為低電位
        delay_ms(500);         // 持續 0.5 秒
     }
     else if (gyro_x > 1000) {
        // 往右轉
        PORTB = 0b00000010;    // B1 設為高電位
        delay_ms(500);         // 持續 0.5 秒
        PORTB = 0b00000000;    // B1 設為低電位
        delay_ms(500);         // 持續 0.5 秒
     }
     else if (gyro_x < -1000) {
        // 往左轉
        PORTB = 0b00000001;    // B0 設為高電位
        delay_ms(500);         // 持續 0.5 秒
        PORTB = 0b00000000;    // B0 設為低電位
        delay_ms(500);         // 持續 0.5 秒
     }
     else {
        // 停止
        PORTB = 0b00000000;    // B0, B1, B2, B3 設為低電位
     }
  }
}
}
頁: [1]
查看完整版本: PIC16F877A PIC12F508 PIC16F886