0

我需要使用同一段代码来读取图片上不同引脚上的各种设备。函数调用确定设备,即设备 1 - 端口 A0 设备 2 - 端口 A1 等。

在我的代码中,我需要将端口更改为输入/输出、发送数据和接收数据。所以,在伪代码中我需要做:

函数读取设备(设备编号)

变量类型 myPortControlVariable;

变量类型 myPortVariable;

//选择我们要使用的设备端口和控件

如果(设备编号==1)

myPortControlVariable = TRISA0;

我的端口变量 = RA0;

如果(设备编号==2)

myPortControlVariable = TRISA1;

我的端口变量 = RA1;

ETC...

...在功能代码中

我的端口控制变量 = 0;//设置为输出

我的端口变量 = 1;//写一个1

暂停 myPortVariable = 0; //写一个0

ETC....

有谁知道如何实现这一目标?谢谢

4

5 回答 5

0

听起来您的外围设备使用 I2C 接口。

让我们来看看 Microchip.com 提供的服务。如果我们去这里: http: //www.microchip.com/CodeExamplesByFunc.aspx

我们可以搜索几个 I2C 代码示例。我们必须确切知道您使用哪个 PIC 才能找到最匹配的应用笔记。除非我们找到完全匹配的(PIC、编译器、库和您的物理设计),否则您将不得不进行调整。

我选择了这个应用笔记: http ://ww1.microchip.com/downloads/en/DeviceDoc/CE337%20I2C_MASTER.zip

如果您下载、解压缩此包并打开 i2c_master.c 文件,您可以看到 microchip 如何使用 PIC 24Fxxxx 系列处理器和 C30 编译器文件中的 i2c 库进行通信。如果您最近将您的 PIC SDK 放在一起,您可能正在使用较新的 XC18 编译器。这也取决于您使用的是哪个 PIC(因此了解这一点很重要。否则,您只需对这些建议保持开放的心态。)。至于从 C30 切换到更新的 XC18 编译器,我认为代码仍然可以工作。但是,正如我所说,您可能需要进行调整。

如果仔细观察,您会发现程序中没有代码可以更改 PIC 的 I2C 数据线的方向。这是因为这是 xc18 编译器文件中的 i2c.h 库从您那里抽象出来的。此外,大多数 PIC 24Fxxxx 类芯片都有多个 I2C 模块。PIC 中设计用于处理 I2C 接口和生成中断的硬件。使用内置硬件将允许您的代码在缓慢的 I2C 事务期间执行其他操作。

总结一下:是的,你可以手动完成所有这些(我认为这就是你要去的地方)。但是,根据您使用的 PIC,它可以在大多数 PIC 处理器内置的硬件中更快地完成。

注意:此示例(来自我正在谈论的 microchip.com)要求您使用 4.7K 电阻将在 PIC 和 I2C 外设之间运行的 I2C 时钟和 I2C 数据线拉高。此提醒已写入示例代码的注释中 - 只是为了您不会忘记!我认为这是因为 I2C 驱动程序(不是软件,而是处理器引脚后面的电子设备)是“集电极开路”设计。

苹果和橘子:如果您是 Arduino Uno 的粉丝,并且认为这太复杂了,请考虑一下 Arduino Uno 简单性的阴暗面:您会被 Arduino Uno 所困扰。

于 2013-10-30T14:50:18.077 回答
0

如果您使用在一条双向线路上集成时钟和数据的外设,那么我在此页面上看不到 microchip.com 示例:http: //www.microchip.com/CodeExamplesByFunc.aspx

但是如果你在网上搜索,你可能会找到很多例子。

如果您只想在需要从硬件中抽象出 I/O 代码时编写它。无论您在哪里更改、设置或清除一个引脚,您都可以调用一个带有正式参数的方法,该参数描述您正在与哪个设备通话。然后,在该方法中,您将硬编码您想要操作的 PIN。听起来您想在 select/case 语句中对许多引脚进行硬编码。

要专门解决您的伪代码......我认为我们需要看看 TRISA0 是如何定义的(这个特定的代码段来自 p24HJ128GP204.h 文件 - 还有许多其他文件可能来自这取决于您使用的 PIC ):

extern volatile unsigned int  TRISA __attribute__((__sfr__));
typedef struct tagTRISABITS {
  unsigned TRISA0:1;
  unsigned TRISA1:1;
  unsigned TRISA2:1;
  unsigned TRISA3:1;
  unsigned TRISA4:1;
  unsigned :2;
  unsigned TRISA7:1;
  unsigned TRISA8:1;
  unsigned TRISA9:1;
  unsigned TRISA10:1;
} TRISABITS;

看来TRISA0是一个结构的一部分。不仅仅是可以分配给变量的值。它会出现在同一文件中的这一行:

#define _TRISA0 TRISAbits.TRISA0

您必须将引脚称为“_TRISA0”而不是“TRISA0”。

于 2013-10-30T15:36:05.933 回答
0

您可以设置指向 LAT 寄存器的易失性指针数组,并使用要设置的位信息维护数组。我在 16 位 PIC 控制器上写了这个

请参阅http://www.microchip.com/forums/m794597.aspx

这也可以应用于 TRIS 寄存器。

于 2014-04-30T18:52:37.793 回答
0

不幸的是,您不能在 C 中传递位。查看此常见问题解答以获取更多信息:http ://www.xargs.com/pic/c-faq.html#pinarray

因此,解决方法是将一个标志传递给您的 I/O 函数,以在最低级别触发开关或 if-else:

void send_bit (char device,char value) {
    switch (device) {
        case DEVICE_1:
            // output bit value to correct port
            break;
        case DEVICE_2:
            // output bit value to correct port
            break;
    }
}

现在消除了这种丑陋,我们可以在它之上构建更简洁的代码:

// The following is just a generic example, change bit order etc
// to fit the protocol you're using.

void send_byte (char device, char value) {
    char i;
    for (i=0;i<8;i++) {
        send_bit(device,(value >> i)&0x01);
    }
}

void send_message (char device, char address, char *buffer, char length) {
    char i;
    send_byte(device,address);
    for (i=0;i<length;i++) {
        send_byte(device,buffer[i]);
    }
}

关键是将丑陋只包含在一个地方 - 最低级别的 I/O 功能。然后在它之上构建更清晰的抽象。


其他注意事项:

如果您使用双向信号,则永远不应将输出位设置为 1。如果高值发生冲突,这样做可能会损坏 PIC 的输出缓冲区或其他设备的输出缓冲区。

相反,双向信号通常实现为带有上拉电阻的集电极开路电路。这样,设备通过拉低电压来传输 0,通过将输出设置为高阻抗来传输 1。因此,与 1-wire 器件通信的正确方法是将输出引脚硬编码为 0,并在输出模式(发送 0)和输入模式(发送 1)之间切换 TRIS 位。

在某些设备上,少数 I/O 引脚可能内置了弱上拉。如果您不想使用外部上拉电阻,您可以启用它,但根据我的经验,最好使用小型(4.7k?)外部上拉电阻,特别是如果两个芯片之间的距离很长(任何长于0.5 厘米?)。

要考虑的另一件事是,您可能只使用一个引脚与两个设备进行通信,因为只有具有正确地址的设备才会响应您的 PIC。唯一的问题是大多数 1-wire 设备都有硬编码地址,所以如果您尝试与两个相同的设备通信,那么是的,您需要使用上面的技巧在运行时切换引脚。

于 2013-10-30T15:57:48.610 回答
0
  1. 在几乎所有情况下,都不会在程序中间更改 PIC 引脚的输入/输出功能。通常,它们在程序开始时设置一次,并且再也不会被触及。此外,您如何确保 PIC 和外部设备不会同时驱动线路并烧毁某些东西?

  2. 在您的伪代码中,您正在读取输入/输出寄存器的状态。我无法想象这样做的原因。你是设置这种状态的人。而且这种状态不应该改变。所以你已经知道每个引脚的输入/输出值。

我无法告诉你想在你的伪代码中做什么,所以这就是我能给出的所有建议。试着用真实的代码来写这个。

于 2013-10-29T05:15:38.327 回答