主题中讨论的其他器件:ADS7142、
您好!
由于使用轮询方法配置 ADS7142并使其采样失败、我已转到使用中断方法与器件通信。 到目前为止、我的代码是:
//
//
// ADS7142_ManualMode_CH0Scan.c -演示简单 I2C 的示例
//传输和接收。
//
//版权所有(c) 2010-2016 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
//重新分发源代码必须保留上述版权
//注意、此条件列表和以下免责声明。
//
//二进制形式的重新分发必须复制上述版权
//注意、中的条件列表和以下免责声明
//随提供的文档和/或其他材料
//分布。
//
//德州仪器公司的名称和的名称都不是
//其贡献者可用于认可或推广衍生产品
//未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//
//这是 Tiva 固件开发包的版本2.1.3.156的一部分。
//
//
#include
#include
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/i2c.c"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "ADS7142registermap.h"
#include "ocf_include.h"
#include "driverlib/interrupt.h"
#include "driverlib/interrupt.c"
//
//
//! \addtogroup i2c_examples_list
//!
//!
//! 此示例展示了如何配置 I2C8模块以进行连接/通信
//! 与 ADS7142 BoosterPack 配合使用。
//! 这包括设置主模块和从模块。 回送模式
//! 在内部将主从数据线和时钟线连接在一起。 此示例
//! 不使用环回模式是指正在与外部器件进行通信
//! 连接到 TM4C1294NCPDT 微控制器。
//! 为了从中读取数据、设置从机模块的地址
//! 主器件。 然后检查数据以确保接收到的数据匹配
//! 传输的数据。 本示例使用的轮询方法
//! 发送和接收数据。
//!
//! 此示例使用以下外设和 I/O 信号。 您必须执行的操作
//! 查看这些内容并根据您自己的董事会的需要进行更改:
//! I2C8外设
//! - GPIO 端口 A 外设(用于 I2C8引脚)
//! I2C8SCL - PA2
//! I2C8SDA - PA3
//!
//! 此示例使用以下中断处理程序。 来使用该示例
//! 在您自己的应用程序中、您必须将这些中断处理程序添加到
//! 矢量表。
//! -无。
//
//
//
//
//设置从机模块的地址。 这是在中发送的7位地址
//以下格式:
//[A6:A5:A4:A3:A2:A1:A0:RS]
//
//第一个字节"RS"位置的零表示主器件
//将数据发送(发送)到所选的从器件,并在该位置发送一个数据
//表示主器件从从器件接收数据。 的从器件地址
//本示例中的 ADS7142由 ADS7142boosterpack 上的硬件设置
//
//
typedef 枚举
{
State_Idle = 0、
State_WRITE_NEXT = 1、
State_WRITE_final = 2、
State_Wait_ACK = 3、
State_send_ACK = 4、
State_Read_One = 5、
State_Read_First = 6、
State_Read_Next = 7、
State_Read_final = 8、
State_Read_Wait = 9
}状态;
//
//
//中断处理程序状态机的当前状态。
//
//
静态易失性状态 TM4C1294_STATE = State_IDLE;
//
//
//跟踪要发送或接收的数据的变量。
//
//
静态无符号长整型*i2cdata = 0;
静态无符号长整型计数= 0;
空 SetState (状态)
{
TM4C1294_STATE =状态;
}
无效
I2C8Handler()//映射到 Tiva I2C8模块
{
//
//清除 I2C 中断。
//
I2CMasterIntClear (I2C8_BASE);
//
//根据当前状态确定要执行的操作。
//
开关(TM4C1294_STATE)
{
//
//空闲状态。
//
案例 State_Idle:
{
// AtState();
//
//没有任何事情要做。
//
中断;
}
//
//猝发写入中间的状态。
//
案例 State_WRITE_NEXT:
{
// AtState();
//
//将下一个字节写入数据寄存器。
//
I2CMasterDataPut (I2C8_BASE、* i2cdata++);
计数--;
//
//继续突发写入。
//
I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//
//如果剩余一个字节,将下一个状态设置为最终写入
//状态。
//
if (count ==1)
{
SetState (State_write_final);
}
//
//此状态已完成。
//
中断;
}
//
//突发序列最终写入的状态。
//
案例 State_WRITE_final:
{
// AtState();
//
//将最后一个字节写入数据寄存器。
//
I2CMasterDataPut (I2C8_BASE、0);
计数--;
//
//完成猝发写入。
//
I2CMasterControl (I2C8_BASE、
I2C_MASTER_CMD_BURST_SEND_FINISH);
//
//下一个状态是等待猝发写入完成。
//
SetState (State_send_ACK);
//
//此状态已完成。
//
中断;
}
//
//写入后等待读取的 ACK。
//
案例 State_Wait_ACK:
{
// AtState();
//
//查看先前发布的读取是否有错误。
//
if (I2CMasterErr (I2C8_BASE)== I2C_MASTER_ERR_NONE)
{
//
//读取接收到的字节。
//
I2CMasterDataGet (I2C8_BASE);
//
//没有错误,因此状态机现在处于空闲状态。
//
SetState (State_Idle);
//
//此状态已完成。
//
中断;
}
//
//进入 State_send_ACK。
//
}
//
//发送读取请求,寻找 ACK 以指示写入
//完成。
//
案例 State_send_ACK:
{
// AtState();
//
//将 I2C 主设备置于接收模式。
//
I2CMasterSlaveAddrSet (I2C8_BASE、ADS7142_I2C_ADDRESS、TRUE);
//
//执行单字节读取。
//
I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_SINGLE_Receive);
//
//下一个状态是等待 ACK。
//
SetState (State_Wait_ACK);
//
//此状态已完成。
//
中断;
}
//
//读取单个字节的状态。
//
案例 State_Read_One:
{
// AtState();
//
//将 I2C 主设备置于接收模式。
//
I2CMasterSlaveAddrSet (I2C8_BASE、ADS7142_I2C_ADDRESS、TRUE);
//
//执行单字节读取。
//
I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_SINGLE_Receive);
//
//下一个状态是等待最终读取状态。
//
SetState (State_Read_Wait);
//
//此状态已完成。
//
中断;
}
//
//开始突发读取的状态。
//
案例 State_Read_First:
{
// AtState();
//
//将 I2C 主设备置于接收模式。
//
I2CMasterSlaveAddrSet (I2C8_BASE、ADS7142_I2C_ADDRESS、TRUE);
//
//开始突发接收。
//
I2CMasterControl (I2C8_BASE、
I2C_MASTER_CMD_BURST_Receive_start);
//
//下一个状态是突发读取的中间状态。
//
SetState (State_Read_next);
//
//此状态已完成。
//
中断;
}
//
//猝发读取中间的状态。
//
案例 State_Read_Next:
{
//
//读取接收到的字符。
//
*i2cdata++= I2CMasterDataGet (I2C8_BASE);
计数--;
//
//继续进行猝发读取。
//
I2CMasterControl (I2C8_BASE、
I2C_MASTER_CMD_BURST_Receive_CONT);
//
//如果还有两个字符要读取,请执行下一个操作
//状态是突发读取状态的结束。
//
if (count == 2)
{
SetState (State_Read_final);
}
//
//此状态已完成。
//
中断;
}
//
//突发读取结束时的状态。
//
案例 State_Read_final:
{
//
//读取接收到的字符。
//
*i2cdata++= I2CMasterDataGet (I2C8_BASE);
计数--;
//
//完成突发读取。
//
I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_Receive_finish);
//
//下一个状态是等待最终读取状态。
//
SetState (State_Read_Wait);
//
//此状态已完成。
//
中断;
}
//
//此状态用于单次或突发读取的最终读取。
//
案例 State_Read_Wait:
{
//
//读取接收到的字符。
//
*i2cdata++= I2CMasterDataGet (I2C8_BASE);
计数--;
//
//状态机现在空闲。
//
SetState (State_Idle);
//
//此状态已完成。
//
中断;
}
}
}
无效
ADS7142SingleRegisterWrite (uint8_t RegisterAddress、uint8_t RegisterData)
{
//
//保存要写入的数据缓冲区。
//
i2cdata[0]= single_write;
i2cdata[1]= RegisterAddress;
i2cdata[2]= RegisterData;
计数= 3;
//
//根据的数量设置中断状态机的下一个状态
//要写入的字节。
//
if (count!= 1)
{
SetState (State_write_next);
}
其他
{
SetState (State_write_final);
}
//
//设置从器件地址并设置发送操作。
//
I2CMasterSlaveAddrSet (I2C8_BASE、ADS7142_I2C_ADDRESS、false);
//
//将要写入的地址放在数据寄存器中。
//
I2CMasterDataPut (I2C8_BASE、i2cdat[0]);
//
//开始突发周期,将地址写入第一个字节。
//
I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//
//等待 I2C 中断状态机空闲。
//
while (TM4C1294_State!= State_Idle)
{
}
}
无效
TM4C1294Init (空)
{
//
//
//配置 I2C8主设备和从设备并将它们连接到 ADS7142 BoosterPack
//
//
#if defined (target_IS_TM4C129_RA0)||\
已定义(TARGET_IS_TM4C129_RA1)||\
已定义(TARGET_IS_TM4C129_RA2)
uint32_t ui32SysClock;
#endif
//
//将时钟设置为直接从外部晶振/振荡器运行。
// TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值
板上的//晶体。
//
#if defined (target_IS_TM4C129_RA0)||\
已定义(TARGET_IS_TM4C129_RA1)||\
已定义(TARGET_IS_TM4C129_RA2)
ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_OSC)、25000000);
其他
SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHz);
#endif
//
//使用前必须启用 I2C8外设。
//
SysCtlPeripheralEnable (SYSCTL_Periph_I2C8);
//
//在本示例中,I2C8与 Porta[3:2]一起使用。 实际端口和
//使用的引脚可能与您的器件不同、请参阅的数据表
//更多信息。 GPIO 端口 A 需要启用、以便这些引脚可以
//使用。
// TODO:将其更改为您正在使用的 GPIO 端口。
//
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
//
//为端口 A2和 A3上的 I2C8功能配置引脚复用。
//如果您的器件不支持引脚复用、则无需执行此步骤。
// TODO:更改此选项以选择您正在使用的端口/引脚。
//
GPIOPinConfigure (GPIO_PA2_I2C8SCL);
GPIOPinConfigure (GPIO_PA3_I2C8SDA);
//
//为这些引脚选择 I2C 功能。 此函数也会
//为 I2C 操作配置 GPIO 引脚,将其设置为
//开漏操作,弱上拉。 请参阅数据表
//查看每个引脚分配了哪些功能。
// TODO:更改此选项以选择您正在使用的端口/引脚。
//
GPIOPinTypeI2CSCL (GPIO_Porta_base、GPIO_PIN_2);
GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_3);
//
//启用主中断。 此函数将启用所有中断
//可用于 I2C 主设备。
// I2CMasterIntEnable (I2C8_BASE);
// I2CSlaveIntEnable (I2C8_BASE);
#if defined (target_IS_TM4C129_RA0)||\
已定义(TARGET_IS_TM4C129_RA1)||\
已定义(TARGET_IS_TM4C129_RA2)
I2CMasterInitExpClk (I2C8_BASE、ui32SysClock、false);
其他
I2CMasterInitExpClk (I2C8_BASE、SysCtlClockGet ()、false);
#endif
//启用 I2C 主设备
I2CMasterEnable (I2C8_BASE);
//
//启用处理器中断。
//
IntMasterEnable();
//启用 I2C 中断。
IntEnable (INT_I2C8_TM4C129);
//注册 I2C8Handler 以处理 I2C8模块中断
内部寄存器(INT_I2C8_TM4C129、I2C8Handler);
//
//启用 I2C 主设备中断
//
I2CMasterIntEnable (I2C8_BASE);
}
内部
main (空)
{
//初始化主 MCU
TM4C1294Init();
//Let's Put the ADS7142 into Manual Mode (I2C 命令模式)、with a Single Channel enabled in Single-ended Configuration (在单端配置中启用单通道)
////选择通道输入配置
ADS7142SingleRegisterWrite (ADS7142_REG_CHANNEL_INPUT CFG、ADS7142_VAL_CHANNEL_INPUT_CFG_1_CHANNEL_SINGLE_ENDended);
//
////确认输入通道配置
//ADS7142SingleRegisterRead (ADS7142_REG_CHANNEL_INPUT_CFG);
//
////选择器件的运行模式
//ADS7142SingleRegisterWrite (ADS7142_REG_OPMODE_SEL、ADS7142_VAL_OPMODE_SEL_I2C_CMD_MODE_W_CHANGE_0);
//
////确认操作模式选择
//ADS7142SingleRegisterRead (ADS7142_REG_OPMODE_SEL);
//
////开始手动模式操作
////开始采样通道0
//StartSampling();
返回(0);
}
我启用我认为与此应用相关的中断(处理器中断、I2C 中断和 I2C 主中断)、但在主代码初始化后进行第一个函数调用时、会调用故障 ISR。 在 ADS7142SingleRegisterWrite()中,我初始化要写入的 i2cdata 的三个片段,但在初始化第二个数据片段后,错误 ISR 会被调用,之后它无限循环且不响应。 导致故障 ISR 的原因可能是什么?
此致、
将会