“线程”中讨论的其它部件:TMP1075, TMP175, 测试
您好,
我一直在用一个 tmp1075来让 I2C 正常运行的墙上敲打着我的头。 我从 TI 示例 I2C_Ex5_MASTER_SLAVE_INTERRUPT 开始,开发了以下代码,这些代码在某种程度上奏效:
//########################################################
//
//文件:I2C_TMP1075.c
//
//标题:I2C 设置并接收来自 TMP1075/TMP175设备的温度值
//
//! 使用 driverib 函数,并且非常松散地基于 TI 演示代码 i2c_Ex5_MASTER_SLAVE_INTERRUPT
//!
//! 该程序使用 I2CA 模块实现外部
//! 来自 TMP1075的数据。 I2CA RX FIFO 与一起使用
//! 中断。 它可以工作,但需要进一步的工作。
//!
//! 设备延迟功能的使用与实时操作不兼容.....
//!
//! 设备最初配置为接收正确的温度值
//! 由于当前延迟在代码中处于联机状态,因此需要对时间和顺序进行正确排序,以确保 I2C 有时间发送
//! 获得这些值后,芯片的温度转换时间约为220毫秒,目前,如果延迟设置为< 30毫秒
//! 设备似乎已锁定,数据表指定的超时为20毫秒左右,这可能是此处所看到的
//! 存储的温度值可以在大约1/30毫秒的时间读取,但只能在1/220毫秒的时间内进行内部更新
//!
//! 必须使用一些更好的 I2C 握手技术,但目前还没有找到正确的方法。
//! 读取温度的顺序是传输一个指针代码00,然后切换到接收模式并在之后触发启动
//! 温度传感器将发送触发中断的数据
//! 建议使用计时器嵌入此代码以触发正确的 I2C 序列,并留出时间让设备做好响应准备
//########################################################
//仅用于硬件测试
//监视变量 RDATA,temp,fiforx,F,result, Example_Passcount
//注意,example_PassCount 应该是 fifforx 的两倍,如果它工作正常,但它是 fifforx 的四倍,不清楚为什么...
//$
//########################################################
//
//包含的文件
//
#include "driverlib.h"
#include "device.h"
//
//定义
//
#define slave 地址0x48
#define pointer_TEMP 0x00
#define pointer_config 0x01
#define pointer_Tlow 0x02
#define pointer_大腿0x03
//TMP175设置配置:
#define TMP175_config 0x68
//D7-一次激发-0-连续转换。
//D6,D5 -分辨率-全12位分辨率11 (220ms 转换时间)
//D4,D3 -噪声滤波器-跳闸01连续出现2个故障
//D2 - Polatiry -活动低0
//D1 - TM -比较器模式0
//D0 - SD -连续转换0
#define TMP175_Tlow 0x68
#define TMP175_大腿0x68
//
//全球
//
UINT16_t RDATA[2]={0};//接收数据缓冲区
UINT16_t rDataPoint =0;//跟踪我们在中的位置
//数据流以检查接收到的数据
内部结果= 0;//temp 结果
浮动温度= 0;//转换结果
INT F = 0;//测试值
内菲弗克斯=0;
//
//函数原型
//
ininitI2CFIFO(void);
使 initTMP1075无效(void);
中断 void i2cFIFO ISR(void);
//
//主页
//
主无效(无效)
{
UINT16_t i;
//
//初始化设备时钟和外围设备
//
device_init();
//
//禁用引脚锁定并启用内部上拉。
//
device_initGPIO ();
//
//初始化 GPIOs 91和92,分别用作 SDA 和 SCL A
//
GPIO 设置引脚配置(GPIO_91_SDAA);
GPIO 设置 PadConfig(91,GPIO 引脚类型上拉);
GPIO 设置限定模式(91,GPIO Qual_Async);
GPIO 设置引脚配置(GPIO_92_SCLA);
GPIO 设置 PadConfig(92,GPIO 引脚_type_pullup);
GPIO 设置限定模式(92,GPIO Qual_Async);
//
//将 GPIO 93初始化为 GPIO 以发出警报
//
GPIO 设置引脚配置(GPIO_93_GPIO93);
GPIO 设置 PadConfig(93,GPIO 引脚_type_pullup);
GPIO 设置限定模式(93,GPIO Qual_Async);
//
//将 GPIO 31初始化为 LED 的 GPIO
//
GPIO 设置 PadConfig (device_GPIO _PIN_LED1,GPIO _PIN_TYPE_STD);
GPIO 设置导向模式(device_GPIO _PIN_LED1,GPIO _DIR_MODE_OUT);
//
//将 GPIO 34初始化为 LED 的 GPIO
//
GPIO 设置 PadConfig (device_GPIO _PIN_LED2,GPIO _PIN_TYPE_STD);
GPIO 设置导向模式(device_GPIO _PIN_LED2,GPIO _DIR_MODE_OUT);
//
//初始化饼图并清除饼图寄存器。 禁用 CPU 中断。
//
interrup_initModule();
//
//使用指向 shell Interrupt 的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrup_initVectorTable();
//
//本示例中使用的中断将重新映射到 ISR 功能
//在此文件中找到。
//
中断寄存器(INT_I2CA_FIFO,&i2cFIFO;
//
//设置 I2C 使用,将其初始化为 FIFO 模式
//
initI2CFIFO();
//
//初始化数据缓冲区
//
对于(i = 0;i < 2;I++)
{
RDATA[I]= 0;
}
//
//启用此示例所需的中断
//
Interrup_enable (INT_I2CA_FIFO);
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
initTMP1075();//设置 TMP1075
//
//永远循环。 暂停或放置断点以观察缓冲区。
//
While (1)(同时)
{
//将为每个基于 Rx 的 Rx 生成 FIFO 中断
//两个字节到达时。
//这里的想法是第一个设定指针的路径和第二个读取温度的路径,
GPIO 写入引脚(device_GPIO _PIN_LED1,0);//打开 LED1
GPIO 写入引脚(device_GPIO _PIN_LED2,0);//打开 LED2
Example_PassCount++;
如果(F=0)为{
I2C_setConfig (I2CA_BASE,I2C_MASTER_SEND_MODE);
I2C_SendStartCondition (I2CA_BUS);//发送配置
I2C_PUData (I2CA_BASE,0x00);//将 TMP175指针设置为读取温度
F=1;
}
否则
{
//
//延迟。
//device_delay_US (2000);//从主发送模式切换到主接收模式时,似乎需要这种方法来避免锁定
GPIO 写入引脚(device_GPIO _PIN_LED2,1);//关闭 LED2
I2C_setConfig (I2CA_BASE,I2C_MASTER_receive_mode);//
I2C_SendStartCondition (I2CA_base);//发送读取开始
F=0;
}
DEVICE_DELAY _US (50000);//如果这小于30000,设备将锁定(怀疑 Ttimout 是这里的罪魁祸首)
}
}
//
//在 FIFO 模式下配置 I2C A 的功能。
//
ininitI2CFIFO()无效
{
//
//必须在配置 I2C 之前重置 I2C
//
I2C_disableModule (I2CA_BASE);
//
// I2C 配置。 使用工作周期为50%的400kHz I2CCLK。
//
I2C_INITMaster (I2CA_BASE,DEVICE_SYSCLK_FREQ,200000,I2C_DUTYCYCLE_50);
I2C_setConfig (I2CA_BASE,I2C_MASTER_SEND_MODE);
//I2C_setDataCount (I2CA_BASE,1);
I2C_setDataCount (I2CA_BASE,2);
I2C_setBitCount (I2CA_BASE,I2C_BICOUNT_8);
//
//配置温度传感器
//
I2C_setSlaveAddress (I2CA_BASE,从属地址);
I2C_setEmulationMode (I2CA_BASE,I2C_Emulation_free 运行);
//
// FIFO 和中断配置
//
I2C_enableFIFO (I2CA_BASE);
I2C_ClearInterruptStatus (I2CA_BASE,I2C_INT_TXFF);
I2C_ClearInterruptStatus (I2CA_BASE,I2C_INT_RXFF);
//
//传输 FIFO 中断级别设置为生成中断
//当16字节 TX fifo 包含2个或更小字节的数据时。
//
I2C_SET FIFO InterruptLevel (I2CA_BASE,I2C_FIF_TX2,I2C_FIF_RX2);//当 FIFO 有两个字节时设置为中断
//
I2C_enableInterrupt (I2CA_BASE,I2C_INT_RXFF);仅限//启用 RX 中断
//
//配置完成。 启用模块。
//
I2C_enableModule (I2CA_BASE);
}
//
// I2C TX 和设置 TMP1075
//
inittMP1075()无效
{
//设置 TMP175配置寄存器
I2C_setConfig (I2CA_BASE,I2C_MASTER_SEND_MODE);
I2C_SendStartCondition (I2CA_BUS);//发送启动配置
I2C_PUData (I2CA_BASE,POINT_CONFIG);//设置要配置的 TMP175指针
I2C_PUData (I2CA_BASE,TMP175_CONFIG);//发送配置字节
DEVICE_DELAY _US (1000);//允许配置传输的时间
I2C_SendStopCondition (I2CA_BUS);//发送停止配置
}
//
// I2C TX 和接收 FIFO ISR
//
_interrupt void i2cFIFO ISR(void)
{
UINT16_t i;
int a,b = 0;
//
//如果设置了接收 FIFO 中断标志,请读取数据
//
IF ((I2C_getInterruptStatus (I2CA_BASE)& I2C_INT_RXFF)!= 0)
{
对于(i = 0;i < 2;I++)
{
RDATA[i]= I2C_getData (I2CA_BASE);
}
//result =((RDATA[0]<8)|(RDATA[1]>4));
A =(int)(RDATA[0])<8);
B =(int)(RDATA[1]| A);
结果=b>>4;
//result =(RDATA[0])<8| RDATA[1]>4;
温度=((浮点)结果)* 0.0625;
//
//清除中断标志
//
I2C_ClearInterruptStatus (I2CA_BASE,I2C_INT_RXFF);
Fiforx++;
GPIO 写入引脚(device_GPIO _PIN_LED1,1);//关闭 LED1
}
//
//发出 ACK
//
interrup_clearACKGroup (interrup_ACK_group8);
}
//
//文件结束
//
监视表达式:
将指针设置为 config 和 config word:
将指针设置为临时:
读取温度:
该设置是使用开发工具包中的 controlCARD 和 TMP1075进行的 Heath Robinson 事件:
因此,我并不期待完美的信号,但据我所知,设置不会导致任何随机行为,降低 I2C 比特率对代码行为没有任何影响。
此时我只需要 I2C 与一个温度传感器进行通信,因此它应该是直接的,理想情况下我会 使用异步代码进行读取,中断将在芯片就绪时处理响应, 但是,让它像这样运行似乎会给我 带来一些挑战,让我了解正确的顺序来实现它。 正如我所说,上述代码可靠地工作,但只是经过一种时尚。 它有以下问题:
1)在 I2C 启动/停止和主发送/接收模式发生变化时,它依靠处理器延迟来管理 I2C 定时,而我尝试与驱动程序库功能混淆以检查 I2C 忙碌或停止的状态,以尝试和“控制”, 迄今为止,我没有取得成功,因此欢迎就如何有效利用这些资源或如果我走上正确的道路提出任何建议。 或者,使用外部计时器对消息进行排序和主模式更改等是否是唯一的方法?
2)您可以看到,程序中的 while 循环似乎每中断循环的次数是我预期的两倍 ,并且不知道为什么会这样。 有什么想法吗? 由于某种原因,范围上的数据明显具有以 bur 为单位发送的两个字节,FIFO 不会每次收集两个字节。 同样,欢迎提出任何建议。
此致
史蒂夫