こんにちは、StackOverflow!
私の質問は、下に(はるかに)貼り付けられたプログラム内で報告されているエラーに関するものです。ターゲット デバイスはPIC12LF1552で、シリアル ペリフェラルが 1 つ搭載されており、Microchip の XC8 コンパイラに付属のライブラリと組み合わせて使用できると想定しました。インターネット上の一部のソースは、PIC18 ラインのハイエンド デバイスのみがライブラリ機能をサポートすると述べていますが、他のソースは、ライブラリ機能は問題なく動作すると述べています。そのため、I2C 関数をゼロから書き直すことも、このプロジェクト用にアセンブリをまったく作成することもしないことにしました。そこで、XC8 に付属の周辺ライブラリを使用することにしました。それらをソースする方法については、コンパイラのドキュメントを読みました(i2c.h
下)。ドキュメントと私が見たいくつかの例に従って、これらのコマンドで実行するエラーチェックがいくつかあることは知っていますが、当面は、マスターとスレーブの両方が完全に動作すると仮定して、これを取り除くことができます地面。
関連するすべてのパスを含めました。そのため、コンパイル プロセスでここまで到達すると想定しています。C 言語とコンパイラの内部動作に関する私の知識レベルは非常に限られています。これらのツールを基本レベルで使用する方法しか知らないので、ここで欠けている基本的なものがあるかもしれません。
とにかく、このコードを MPLABX v1.95 でコンパイルすると、次のようになります。
:0: error: undefined symbols:
_AckI2C(dist/pickit3/production\strobe.X.production.obj) _ReadI2C(dist/pickit3/production\strobe.X.production.obj) _IdleI2C(dist/pickit3/production\strobe.X.production.obj) _OpenI2C(dist/pickit3/production\strobe.X.production.obj) _StopI2C(dist/pickit3/production\strobe.X.production.obj) _NotAckI2C(dist/pickit3/production\strobe.X.production.obj) _WriteI2C(dist/pickit3/production\strobe.X.production.obj) _StartI2C(dist/pickit3/production\strobe.X.production.obj)
Google、StackOverflow、または私の特定のコンテキストからこの問題に関連するものを見つけることができませんでした (別の人が、Microchip のレガシー C18 コンパイラから移植するときに非常によく似た問題を抱えていましたが、私はその人が彼の問題を解決するために行ったすべてのことを既に行いました) .
問題は、なぜこのコンパイラ エラーが発生するのかということです。また、C 言語または Microchip の実装でこれを引き起こしているメカニズムは何ですか?
/*
* File: i2c.h
* Author: James
*
* Created on July 23, 2014, 9:02 PM
*/
#ifndef I2C_H
#define I2C_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#include <plib\pconfig.h>
#include <plib\i2c.h>
#define SLAVE_ADDRESS 0b11110000
void Connect();
void Disconnect();
void Read(unsigned char address, unsigned char * data, unsigned char length);
void Write(unsigned char address, unsigned char * data, unsigned char length);
#endif /* I2C_H */
#include "i2c.h"
void Connect()
{
OpenI2C(MASTER, SLEW_OFF);
}
void Disconnect()
{
CloseI2C();
}
void Read(unsigned char address, unsigned char * data, unsigned char length)
{
IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
if (WriteI2C(SLAVE_ADDRESS | 0x01)) return; // Send slave address with R/W cleared for write
IdleI2C(); // Wait for ACK
if (WriteI2C(address)) return; // Send register address
IdleI2C(); // Wait for ACK
for(int i = 0; i < length; i++)
{
data[i] = ReadI2C(); // Write nth byte of data
AckI2C(); // Wait for ACK
}
NotAckI2C(); // Send NACK
StopI2C(); // Hang up, send STOP condition
}
void Write(unsigned char address, unsigned char * data, unsigned char length)
{
IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
if (WriteI2C(SLAVE_ADDRESS | 0x01)) return; // Send slave address with R/W cleared for write
IdleI2C(); // Wait for ACK
if (WriteI2C(address)) return; // Send register address
IdleI2C(); // Wait for ACK
for(int i = 0; i < length; i++)
{
WriteI2C(data[i]); // Write nth byte of data
IdleI2C(); // Wait for ACK
}
StopI2C(); // Hang up, send STOP condition
}
/*
* File: main.c
* Author: James
*
* Created on July 14, 2014, 11:00 PM
*/
/******************************************************************************/
/* Files to Include */
/******************************************************************************/
#if defined(__XC)
#include <xc.h> /* XC8 General Include File */
#endif
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
#include <stdio.h>
#include <stdlib.h>
#include <pic12lf1552.h>
#include "i2c.h"
/******************************************************************************/
/* Defines */
/******************************************************************************/
//#define SYS_FREQ 16000000L
//#define FCY SYS_FREQ/4
#define _XTAL_FREQ 500000
__CONFIG
(
MCLRE_ON &
CP_OFF &
BOREN_OFF &
WDTE_OFF &
PWRTE_OFF &
FOSC_INTOSC
);
void main(void)
{
ANSELA = 0;
TRISA = 0b101111;
OPTION_REG = 0b01111111;
APFCONbits.SDSEL = 1;
unsigned char state = 0;
unsigned char count = 0;
unsigned char data[8] = { 0 };
Connect();
Read
(
0x01, // System register
data, // Data buffer
0x01 // Read length
);
LATAbits.LATA4 = data[0];
while(1)
{
switch (state)
{
case 0: // IDLE/OFF
if (LATAbits.LATA4) LATAbits.LATA4 = 0;
break;
case 1: // ON
if (!LATAbits.LATA4) LATAbits.LATA4 = 1;
break;
case 2: // BLINK (slow)
LATAbits.LATA4 = !LATAbits.LATA4;
__delay_ms(100);
break;
case 3: // BLINK (fast)
LATAbits.LATA4 = !LATAbits.LATA4;
__delay_ms(50);
break;
case 4: // BEAT DETECT
LATAbits.LATA4 = PORTAbits.RA5;
break;
default:
state = 0;
break;
}
if (TMR0 > 0)
{
while (count < 20)
{
if (!PORTAbits.RA2) count = 0;
__delay_ms(10);
count++;
}
TMR0 = 0;
state++;
}
}
}