gpt4 book ai didi

c - XC8 收到关于 plib I2C 函数的 "undefined symbols"错误

转载 作者:行者123 更新时间:2023-12-02 01:46:43 27 4
gpt4 key购买 nike

嘿,StackOverflow!

我的问题涉及在下面粘贴(远)的程序中报告的错误。目标设备是 PIC12LF1552,它上面有一个串行外设,我认为它可以与 Microchip 的 XC8 编译器提供的库结合使用。互联网上的一些消息来源说,只有 PIC18 系列中的高端设备会支持库函数,其他消息来源说库函数工作得很好。所以我决定不想从头开始重写 I2C 函数,也不想为这个项目编写任何数量的程序集。因此,我决定使用 XC8 附带的外围库。我阅读了编译器文档以了解如何获取它们(如下面的 i2c.h 所示)。我知道根据文档和我见过的一些示例,需要对这些命令进行一些错误检查,但目前我假设主从设备都表现完美,这样我就可以解决这个问题地面。

我已经包含了所有相关路径,这就是为什么我认为它在编译过程中走到了这一步。关于 C 语言和编译器的内部工作,我的知识水平非常有限,我只知道如何在基础水平上使用这些工具,所以我可能在这里遗漏了一些基础知识。

无论如何,当我在 MPLABX v1.95 中编译这段代码时,我得到了:

:0:错误: undefined symbol :
_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++;
}
}
}

最佳答案

问题定义

这里的核心问题是 Microchip XC8 外设库,与其前身 C18 外设库一样,不支持 PIC18 系列以外的微 Controller 。因此,有一大堆正确配置外设的头文件,并且所有寄存器宏都是特定于 PIC18 系列的,尽管它们有很多相似之处。

解决方案/解决方法

但是,由于 Microchip 在此目录中提供其外设库的源代码:/path/to/xc8/install/directory/version/sources/pic18/plib

特别是在我的情况下,对于 Windows x64 机器上的 i2c 源: C:\Program Files (x86)\Microchip\xc8\v1.21\sources\pic18\plib\i2c

对于 PIC12LF1552,该芯片有一个 MSSP,因此您需要复制 i2c_*.c 源并将它们连接起来,如果您的 PC 上有任何 Linux/Unix 实用程序,您可以这样做:cat i2c_* > i2c.c

现在,首先,要么删除文件中定义的所有 I2C 版本,要么更简单地进入当前构建配置文件下的 xc8 编译器设置并设置以下定义宏:I2C_V1

之后,您需要对 v1.21 版本的源代码进行一些修改以使其与设备兼容:

  • 在您的版本的头文件中 i2c.c放:#include <pic12lf1552.h>这样剩下的代码就有了所有的寄存器定义
  • i2c.h 中添加 SDA 和 SCL 引脚的定义以便 OpenI2C() 工作或简单地更改 OpenI2C() 以特定于设备:
    • #define I2C_SCL TRISAbits.TRISA1
    • #define I2C_SDA TRISAbits.TRISA2或者 TRISAbits.TRISA3取决于你的 APFCONbits.SDSEL环境。尽管在 PIC12LF1552 上,RA3 始终设置为输入。
  • 需要更改以下寄存器字段:
    • SSPSTATbits.R_W -> SSPSTATbits.R_nW
    • PIR1bits.SSPIF -> PIR1bits.SSP1IF
    • PIR2bits.BCLIF -> PIR2bits.BCL1IF
    • 后两个我觉得很奇怪,因为数据表仍然在定义它们时没有在 IF 之前加上 1,但谁知道呢,也许 Microchip 对此有特殊的内部原因

在所有这一切之后,您仍然需要编写自己的包装器来执行主/从模式的基本完整功能,正如我在我的问题中所遇到的那样。

小意见片

整个过程可以说比拔牙还糟糕。 Microchip 的社区傲慢或不屑一顾(“使用汇编”、“自己编写”等等)。 Microchip 自己的支持也无济于事。最重要的是,实际代码需要非常小的面向细节的更改,这几乎没有意义,IF -> 1IF严重地?在所有这些之后,您需要为这些函数编写自己的包装器以进行逻辑 I2C 事务,更不用说测试整个设备以确保它不会摔倒。难怪没有自定义布局和/或成本要求的人使用 Arduinos。

关于c - XC8 收到关于 plib I2C 函数的 "undefined symbols"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25224541/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com