0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PIC32MX+OV7670カメラ カラートラッキング高速化 ステッピングモータ駆動をI2Cクライアント化

Last updated at Posted at 2024-11-13

I2C Client2台で、ステッピングモータを駆動して、トラッキング

今回の概要

前回、ステッピングモータで水平、垂直方向のカラートラッキングを行いました。

このとき、PIC32MXで直接ステッピングモータ2台を制御していました。

それを、2つのPIC16F1827をI2C Client(slave)として、ステッピングモータの励磁信号の出力を分担させました。

移動速度も速くなり、かなり滑らかにトラッキングできるようになり、手の動きに同期して、トラッキングできるようになりました。

IMG_5127.JPG

I2Cクライアントを用いたステッピングモーター駆動。

トラッキング概略図.jpg

RAM上でのグラフィック描画

RAM解説.jpg

垂直方向のコード抜粋

PIC16F1827 I2C Cilentサイド I2C処理関連
#include "Peripheral.h"
#include "I2C_MSSP1_Slave.h"

_i2cStruct i2cInfo;

void I2C1_Reg_Init_Slave(void)
{
    uint8_t val;
    SSP1STAT=0xC0;
    SSP1CON1=0x36;          //slave mode , 7bit address
    //SSP1CON1=0x3E;        //slave mode , 7bit address with interrupts
    SSP1CON2bits.SEN=1;     //0:Clock stretching is disable
    SSP1CON3bits.PCIE=0;
    SSP1CON3bits.SCIE=0;
    SSP1CON3bits.AHEN=0;
    SSP1CON3bits.DHEN=0;
    SSP1ADD=0x36;
    val=SSP1BUF;
    PIE1bits.SSP1IE=1;
   
}

void I2C1_Slave_Interrupt(void)
{
    uint8_t I2c1stat,i,buf;
    //---------MSSP1 ステータス読み出し---------
        PIR1bits.SSP1IF=0;
        I2c1stat=SSP1STAT & 0b00111101;
        
        /*1.--------I2c Writeモード 
                 スタートコンディション検出&スレーブアドレス読み出し--------- */
        if(I2c1stat==0b00001001)
        {
            i2cInfo.index=0;
            for(i=0; i<=3; i++) i2cInfo.rxData[i]=0;
            i2cInfo.rxData[i2cInfo.index++]=SSP1BUF;    
            if(SSP1CON2bits.SEN==1)
                    SSP1CON1bits.CKP=1;
        }
        /*2.--------I2c Writeモード 受信データバイト読み出し---------*/
        if(I2c1stat==0b00101001)
        {
            i2cInfo.rxData[i2cInfo.index++]=SSP1BUF;
            /*if(i2cInfo.index==3)
            {//ストップビット検出ができない場合、ここで受信完了とする。
               i2cInfo.flag=true;//mainループで処理。
            }*/
            if(SSP1CON2bits.SEN==1)
                SSP1CON1bits.CKP=1;
        }
        /*3.--------I2c Readモード スタートコンディション検出&
                            データバイトバッファ出力 送信(アドレス部)--------- */
        if(I2c1stat==0b00001101)
        {
           
        }
        /*4.--------I2c Readモード データバイトバッファ出力 送信(データ部)---------*/
        if(I2c1stat==0b00101100)
        {
           
        }
        /*5-1.--------I2c Writeモードストップビット検知---------*/
        if(I2c1stat==0b00110000)
        {
            if(i2cInfo.index==3)
            {
               i2cInfo.flag=true;//mainループで処理。
            }
            if(SSP1CON2bits.SEN==1)
            {
                SSP1CON1bits.CKP=1;
            }
        }
        /*5-2.---------I2c Readモードストップビット検知---------*/
        if(I2c1stat==0b00110100)
        {
             if(SSP1CON2bits.SEN==1)
                SSP1CON1bits.CKP=1;               
        }
}

PIC16F1827 I2C Cilentサイド main.c

// PIC16F1827 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
//#pragma config FOSC = HS      // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP =ON      // Low-Voltage Programming Enable (Low-voltage programming enabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdlib.h>
#include <stdio.h>
#include "Interrupt.h"
#include "Peripheral.h"
#include "I2C_MSSP1_Slave.h"
#include "stepping.h"

#define _XTAL_FREQ  16000000

void Oscillator_Init(void);
void Port_Init(void);
void delay_ms(uint16_t time);






void main(void)
{    
    uint8_t cnt=0;
    uint8_t i,j,temp;
    uint8_t rxData;
    uint8_t  direction[2];
    
    //Basic Hard Initialize
    Oscillator_Init();
    Port_Init(); 
    //Peripheral 
    //Timer0_INIT();
    Timer2_INIT();
    //USART_INIT();
    //ADC_INIT();
    I2C1_Reg_Init_Slave();
    
    //famiconInit();
    //割り込み許可
    Interrupt_START();
    
    while(1)
    {
        //USART interrupt processing
        /*if(usart.rxCompleted)
        {
            usart.rxCompleted=false;
            printf("%s\n",usart.rxBuf);
            usart.length=0;
            PIE1bits.RCIE=1;
        }*/
        
        if(i2cInfo.flag)
        {
            i2cInfo.flag=false;
           
            rxData = i2cInfo.rxData[1];
           
            //printf("rcvData: %X %X\n",rcvdata[1],rcvdata[2]);
            //printf("RES:%02X\n",buttonState);
            if((rxData&0x04)==0x04)//Up
            {               
                st1UpMoving(1);
            }

            if((rxData&0x08)==0x08)//Down
            {               
                
                st1DownMoving(1);
            }
            
            if((rxData&0x10)==0x10)
            {
                LATAbits.LATA0=0;
                LATAbits.LATA1=0;
                LATAbits.LATA2=0;
                LATAbits.LATA3=0;
            }
            
        }
    }
    return;
}

void Oscillator_Init(void)
{
    OSCCONbits.SPLLEN=0;
    OSCCONbits.IRCF=0b1111;//16Mhz
    OSCCONbits.SCS=0b10;//InternalOscillator
}

void Port_Init(void)
{
    TRISA=0x00;
    ANSELA=0x00;
    TRISB=0x00;     //RX:RB2
    ANSELB=0x00;
    PORTA=0x00;
    PORTB=0x00;  
    //Altanative Pin Selective
    /*APFCON0bits.RXDTSEL=1;  //RX:RB2
    APFCON1bits.TXCKSEL=1;  //TX:RB5*/
    //I2Cinitialize
    TRISBbits.TRISB1=1;     //RB1
    TRISBbits.TRISB4=1;     //RB4
}


ステッピングモータの励磁

#include "stepping.h"
#include "Peripheral.h"
unsigned int halfStep0[9]={0x0000,0x0001,0x0003,0x0002,0x0006,0x0004,0x000C,0x0008,0x0009};
unsigned int halfStep1[9]={0x0000,0x0010,0x0030,0x0020,0x0060,0x0040,0x00C0,0x0080,0x0090};




void st1UpMoving(uint8_t leftCount)
{
    uint8_t i;
    unsigned int j;
    for(i=0; i<leftCount; i++)
        for(j=1; j<=8; j++)
        {   
            LATA&=0xF0;
            LATA|=(uint8_t)halfStep0[j];
            __delay_us(stDelayUS);
            __delay_ms(20);
        }  
}

void st1DownMoving(uint8_t rightCount)
{
    uint8_t i;
    unsigned int j;
    for(i=0; i<rightCount; i++)
        for(j=8; j>=1; j--)
        {    
            LATA&=0xF0;
            LATA|=(uint8_t)halfStep0[j];
            __delay_us(stDelayUS);
            __delay_ms(20);
        }
}




0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?