質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.10%

picマイコンでシリアル受信割込みが機能しません

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 661

ITSUKING

score 12

 前提・実現したいこと

・c言語、picマイコン初心者です。
android端末からarduinoに値を送信し、その値をシリアル通信でpicマイコンに送ります。
ここでpicマイコンが値(A○○ or B○○ ○○は2桁の数字)を判定し、信号を作り出してモータコントローラに送信するプログラムです。

 発生している問題・エラーメッセージ

arduinoから値が送信されていることはシリアルモニタで確認済みですが、picマイコンが信号を作り出すことができていません。書き込みは完了したと出ているので書き込めていると思います。また、arduinoとpicマイコンの接続はオシロスコープで確認済みです。

 該当のソースコード

#include "pic.h"

//    Setup configure register
//__CONFIG(FOSC_INTRC_NOCLKOUT & LVP_OFF & DEBUG_ON & WDTE_OFF & BOREN_OFF & PWRTE_OFF & CP_OFF & CPD_OFF );
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config LVP = OFF
#pragma config DEBUG = ON
#pragma config WDTE = OFF
#pragma config BOREN = OFF
#pragma config PWRTE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
// Constants
#define    RXBUFSIZE    96    // Serial buffer size
#define    TXBUFSIZE    32    // Serial buffer size
// Work vars
char Servo1; // Servo1 position (0 to 99)
char Servo2; // Servo2 position (0 to 99)
char RxBuf[RXBUFSIZE];    // Recieve queue
char TxBuf[TXBUFSIZE];    // Transmit queue
char Digit[8];    // Digit buffer
char Reply[16];    // Reply data buffer
char Index;    // Result store index

char PortB; // PORTB image copy for asynchronous bit operation
volatile char Tick; // PORTB copy for bit operation
volatile char RxIn;    // Receive queue entry pointer
volatile char RxOut;    // Receive queue output pointer
volatile char TxIn;    // Receive queue entry pointer
volatile char TxOut;    // Receive queue output pointer


//
//    Common Interrupt handler
//
static void interrupt InterruptHandler(void)
{
    char i;
    signed char j;
    if(T0IF) // TIMER 0 interrupts?
    {
        T0IF = 0; // Clear TIMER0 interrupts
        T0IE = 0; // Disable TIMER2 interrupts
        PortB |= 0x10; // Set servo2 port (servo2 signal will be low)
        PORTB = PortB; // Out port data
    }
    if(TMR1IF) // TIMER1 interrupts?
    {
        TMR0 = 110 + Servo2; // Set TIMER0 counter again (Range must be 110 - 210)
        TMR1IF = 0; // Clear TIMER1 interrupt flag
        T0IF = 0; // Clear TIMER0 interrupts
        T0IE = 1; // Enable TIMER0 interrupts
        PR2 = 145 - Servo1; // Set TIMER0 counter again (Range must be 145 - 45)
        TMR2 = 0; // Clear TIMER2 counter
        TMR2IF = 0; // Clear TIMER0 interrupts
        TMR2IE = 1; // Disable TIMER2 interrupts
        TMR1H = 0x63; // Set TIMER1 interval timer high (interval will be 20mS)
        TMR1L = 0xc0; // Set TIMER1 interval timer low(interval will be 40000 * 5uS)
        PortB &= 0x0f; // Clear both servo port(servo signal will be high)
        PORTB = PortB; // Out port data
        Tick++;    // Advance internal timer
    }
    if(TMR2IF) // TIMER 2 interrupts?
    {
        TMR2IF = 0; // Clear TIMER2 interrupts
        TMR2IE = 0; // Disable TIMER2 interrupts
        PortB |= 0x20; // Ser servo1 port (servo1 signal will be low)
        PORTB = PortB; // Out port data
    }
    if(RCIF)    // Serial receive interrupts?
    {
        RCIF = 0;    // Clear interrupt source
        i = RCREG;    // Get received char
        j = RxIn - RxOut;    // Get queued data count
        if(j < 0)    // If negative number?
            j += RXBUFSIZE;    // Make it plus
        if(j < RXBUFSIZE - 1)    // Dose queue have space to put received data?
        {
            RxBuf[RxIn] = i;    // Save received char
            if(RxIn == RXBUFSIZE - 1)    // Reach to the end of the queue?
                RxIn = 0;    // Go to top again (ring buffer)
            else
                RxIn++;
        }
    }
    if(TXIF)    // Serial transmit interrupts?
    {
        TXIF = 0;    // Clear interrupt source
        if(TxOut == TxIn)    // Check data exists in send queued
            TXIE = 0;    // Disable TX interrupts if no data
        else    // TX data is queued
        {
            TXREG = TxBuf[TxOut];    // Set TX data from queue
            if(TxOut == TXBUFSIZE - 1)    // Reach to the end of the queue?
                TxOut = 0;    // Go to top again (ring buffer)
            else
                TxOut++;    // Advance TX get pointer
        }
    }
}

//
// Sense incoming serial data
//
char RxSense(void)
{
    signed char i;
    i = RxIn - RxOut;    // Check queued number
    if(i < 0)    // Negative? (may wraped queue index)
        i += RXBUFSIZE;    // Make it plus
    return i;    // Return with queued number
}

//
// Get serial data from queue
//
char GetChar(void)
{
    char    i;
    while(!RxSense());    // Wait untill receive data has come
    i = RxBuf[RxOut];    // Get queued data
    if(RxOut == RXBUFSIZE - 1)    // Reach to the end of the queue?
        RxOut = 0;    // Go to top again (ring buffer)
    else
        RxOut++;    // Advance get pointer
    return i;    // Return with received data
}

//
// Put serial char data and send
//
void PutChar(char ch)
{
    signed char    i;
    i = TxIn - TxOut;    // Get queued data count
    if(i < 0)    // If negative number?
        i += TXBUFSIZE;    // Make it plus
    if(i < TXBUFSIZE - 1)    // Dose queue have space to put send data?
    {
        TxBuf[TxIn] = ch;    // Save received char
        if(TxIn == TXBUFSIZE - 1)    // Reach to the end of the queue?
            TxIn = 0;    // Go to top again (ring buffer)
        else
            TxIn++;    // Advance Tx input queue pointer
        TXIE = 1;    // Enable interrupts
    }
}

//
// Put serial string data and send
//
void PutStr(const unsigned char *str)
{
    char i;
    for(;;)
    {
        i = *str++;    // Fetch char
        if(i == 0)    // EOS encountered?
            break;    // Exit string send loop
        PutChar(i);    // Send 1 char
    }
}

//
// Put serial string data and wait CR
//
//void PutStrWait(const unsigned char *str)
//{
//    char i;
//    for(;;)
//    {
//        i = *str++;    // Fetch char
//        if(i == 0)    // EOS encountered?
//            break;    // Exit string send loop
//        PutChar(i);    // Send 1 char
//    }
//    while(GetChar() != '\r');    // Wait CR
//}

//
//    Sleep timer
//
void Sleep(char time)
{
    char    i;
    char ticksave;
    for(i = 0; i < time; i++)    // Repeat for delay time
    {
        ticksave = Tick;    // Clear tick save
        while(Tick == ticksave);    // Wait until tick change(wait 20mS)
    }
}

//
//    Get A/D data
//
unsigned int GetAd(char ch)
{
    ADCON0 = 0x83 | (ch << 2);    // Specify conversion channel
    while(ADCON0 & 0x02);    // Wait until A/D conversion finish
    return (ADRESH << 8) | ADRESL;    // Get A/D result
}

//
//    Make reply data
//
//void MakeReply(unsigned int val)
//{
//    unsigned int    k = 10000;    // loop 10000, 1000, 100, 10. 1
//    char i = 0;
//    for(;k;)    // Repeat untill k has value
//    {
//        Digit[i++] = val / k + '0';    // Create target digit
//        val = val % k;    // Get modulo
//        k /= 10;    // Get next digit division
//    }
//    for(i = 0; i < 4; i++)    // Skip leading 0
//        if(Digit[i] != '0')    // Some digit except '0' found?
//            break;    // Exit loop
//    for(; i < 5; i++)    // Copy digit string to reply buffer
//        Reply[Index++] = Digit[i];    // Copy 1 digit
//    Reply[Index++] = ',';    // Insert delimiter
//}
//
////
////    Get address data
////
unsigned int GetValue()
{
    unsigned int i = 0;
    char j;
    for(;;)
    {
        j = GetChar();          //????????
        if(j < '0' || j > '9')
            break;
        i = i * 10 + j - '0';    //?????
    }
    return i;
}

//
//    Main
//
main()
{
    char i;
    while(!(OSCCON & 0x04)); // Wait untill HFINTOSC is stabled

// Clock setup
    OSCCON = 0x71; // Set prescaler 8MHz and use internal clock

// Set port direction & purpose
    ANSEL = 0x00; // Set PA0 & PA1 is analog input 0x03
    PORTA = 0x00;    // Clear PORTA
    PortB = 0x30;    // Clear PORTB & set servo ports
    PORTB = PortB;    // Set PORT B data
    PORTC = 0x00;    // Clear PORTC
    TRISA = 0x0f; // Set PA4,5,6,7 output
    TRISB = 0xc0; // Set PB0,1,2,3,4,5 output
    TRISC = 0xc0; // Set PC0,1,2,3,4,5 output

//    Setup variables
    Servo1 = 50;    // Set default servo1 position
    Servo2 = 50;    // Set default servo2 position
    RxIn = 0; RxOut = 0;    // Clear receive queue pointers
    TxIn = 0; TxOut = 0;    // Clear tansmit queue pointers

// Setup serial port
    SPBRG = 12; // Set 9600bps of 8MHz clock
    RCSTA = 0x80; // Enable TX & RX pin
    TXEN = 1; // Enable TX
    CREN = 1;    // Enable RX
    RCIE = 1;        // Enable serial receive interrupts

//    Set A/D converter
    ADCON0 = 0x81;    // A/D clock source is FOSC/32 & enable A/D logic
    ADCON1 = 0x80;    // Set A/D result format is right justified

//    Setup TIMER
    OPTION_REG = 0x84; // Prescaler = 64 TIMER0 tick will 16uS OSC 8MHz/4/32
    TMR1ON = 1; // Enable TIMER1
    TMR1IE = 1; // Enable TIMER1 interrupts
    T2CON = 0x0f; // Enable TIMER2 & prescaler 1:4 & postscaler 1:8

//    Enable interrupts
    PEIE = 1; // Enable peripheral interrupts
    GIE = 1; // Enable global interrupts

//    Init XBee WiFi
//     Sleep(200);                             //Wait Start XBee
//    PutStrWait("+++");                      //Send Comand Mode
//    PutStrWait("ATRE\r");                   //Send Reset
//        PutStrWait("ATEE 0\r");                 //Send Security Mode?0=no security 1=WPA 2=WPA2 3=WEP
//        PutStrWait("ATAH 1\r");                 //Send Network Type?0=joiner 1=creator 2=infrastructuer
//    PutStrWait("ATID XBEE\r");            //Send SSID
//        PutStrWait("ATMA 1\r");                 //Send IP Addressing Mode    0=DHCP  1=static
//        PutStrWait("ATMY 192.168.0.2\r");    //Send My IP Address 192.168.0.2
//        PutStrWait("ATMK 255.255.255.0\r");     //Send IP Mask
//        PutStrWait("ATDL 192.168.0.20\r");    //Send IP Address 192.168.0.2
//        PutStrWait("ATCH 1\r");                 //Send Chanel
//    PutStrWait("ATCN\r");                   //Send return

//    Start main loop
    for(;;)
    {

//    Receive process
        if(RxSense())
        {
                    if(RXBUFSIZE != 0){
                    // Serial data has come from WiFi module
            i = GetChar();    // Get one byte
            switch(i)    // Only ACT A,B,C
            {
            case 'A':    // Servo 1?
                Servo1 = GetValue();    // Get servo 1 value
                break;
            case 'B':    // Servo 1?
                Servo2 = GetValue();    // Get servo 2 value
                break;
//            case 'D':    // Temperture ?
//            case 'E':    // Variable register??
//                GetValue();    // Get value and skip
//                break;

            }
                }
        }
             }
        }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

いきなり受信割り込みを実装しようとせず、まずはポーリングでシリアル受信を実装し、きちんと受信しているのを確認してはどうでしょう。

まずは、どこまで動いているのか、を確認することです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/23 11:29

    回答ありがとうございます。
    ポーリングでシリアル受信を実装する。
    試してみたいと思います。恥ずかしながらポーリングのことも知らなかったのでとても助かります。

    キャンセル

  • 2018/08/23 11:37

    ポーリング、と言っても、ソフトで受信フルをチェックして受信データ読み出すだけです

    で、PICマイコンと一口に言っても、PICの型番が違えば各レジスタの割当や動作も変わる場合がありますんで、本当に提示するコードから不具合を見つけてもらおうとするなら、詳しい型番が必要になります
    #私はそこまでマメではないので解決策だけ

    キャンセル

  • 2018/08/23 17:44

    わざわざ丁寧にありがとうございます。今後質問を投稿する際に気を付けたいと思います:)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る