PIC16F1シリーズでSPIスレーブモードを使用している場合、16bitの連続データ送信は可能でしょうか。
この環境での16bit連続送信は不可能なのか、
もし可能であれば改善すべき点を、
不可能であれば別の手段(dsPICでは16bit送信ができる?など)のアドバイスを頂けないでしょうか。
前提・実現したいこと
使用しているマイコンはPIC16F1503です。XC8コンパイラを使用しています。
SPI通信をしている既存の機材があり、そのスレーブ側の動きをPICで再現し代替したいと考えております。
そのためマスター側の処理は変更ができず、スレーブ側でのみの対応となります。
マスター側は「8bitの要求コマンド」「8bitの受信用ダミーデータ」を連続で16bit送信します。
1byte目は「0x07」、「0x0F」のいずれか
2byte目は「0xFF」
スレーブ側はマスター側からの受信と同時に、「8bitの受信用ダミーデータ」「8bitの返送データ」を交換します。
1byte目は「0xFE」
2byte目は現在のステータスを返す予定です(試作ではダミーや00を送信しています)
本来はマスター側の要求により返答内容を決定しますが、その手前でコケたためより簡易なプログラムで検証しております。
試したこと
いくつかの簡単なテストプログラムを作成しました。
- A:常にダミーデータだけを送信するプログラム
SSP1IF割り込みが発生
→受信データの空読みと、次回の送信用ダミーデータを代入
- B:割り込み後に手動で2バイト送信するプログラム
SSP1IF割り込み発生
→受信データの空読みと、2byte目の送信データ(0x00)を代入
→2byte目の受信空読みと、次回1byte目のダミーデータを代入
- C, D
割り込みを停止し、A, Bのそれぞれをメインのwhile内で実行
一時的に試したためソースコードには記載しておりません
発生している問題
どのパターンでも、実際に返送しているデータには前半1byteにダミーデータがあるのみで、
後半1byteにはマスターから受信したデータをそのまま返信しているようです。
パターンBに記載している0x00の送信データはどこにも見当たりません。
該当のソースコード
c
1// PIC16F1503 Configuration Bit Settings 2// 'C' source line config statements 3 4// CONFIG1 5#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin) 6#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) 7#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) 8#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) 9#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) 10#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled) 11#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) 12 13// CONFIG2 14#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) 15#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) 16#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) 17#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled) 18#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) 19 20// #pragma config statements should precede project file includes. 21// Use project enums instead of #define for ON and OFF. 22 23#include <xc.h> 24 25const char DUMMY = 0xFE; 26unsigned char buf = 0; 27 28void __interrupt() isr(){ 29 if (PIE1bits.SSP1IE == 1 && PIR1bits.SSP1IF == 1){ 30 31 // Pattern A 32 33 // Read Receive Data 34 buf = SSP1BUF; 35 // Set Send Data 36 SSP1BUF = DUMMY; 37 38 //Clear Flag 39 PIR1bits.SSP1IF = 0; 40 41 42 // Pattern B 43 /* 44 // Read Receive Data1 45 buf = SSP1BUF; 46 // Set Send Data2 47 SSP1BUF = 0x00; 48 49 // Wait Send 50 while(!SSP1STATbits.BF); 51 52 // Read Receive Data2 53 buf = SSP1BUF; 54 // Set Next Send Data1 55 SSP1BUF = DUMMY; 56 57 //Clear Flag 58 PIR1bits.SSP1IF = 0; 59 */ 60 } 61} 62 63void main(void) { 64 // General Setup 65 OSCCON = 0b01111011; // 16MHz 66 67 // Pin Setup 68 ANSELA = 0x00; // All Digital Pin 69 ANSELC = 0x00; // All Digital Pin 70 APFCON = 0b00100000; // SDO1:RA4 71 WPUA = 0b00010000; 72 TRISA = 0b11101111; // RA4:SDO output 73 TRISC = 0b00111011; // RC2:SDO output 74 75 // SPI setup 76 SSP1STAT = 0b00000000; // SMP:must be cleared in Slave, CKE:0 Idle to Active 77 SSP1CON1 = 0b00110100; // WCOL, SSPOV:status, SSPEN:SPI Enable, CKP:1 Idle High, SSPM:0100 Slave with SS 78 SSP1BUF = DUMMY; 79 80 // Interrupt Setup 81 PIR1bits.SSP1IF = 0; 82 PIE1bits.SSP1IE = 1; 83 INTCONbits.PEIE = 1; 84 INTCONbits.GIE = 1; 85 86 while(1); 87 return; 88} 89
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/20 16:22
2021/07/20 16:27 編集
2021/07/20 16:36
2021/07/20 16:51
2021/07/20 17:05
2021/07/20 17:10
2021/07/20 23:15