基于STM32和ADS1118的热电偶设计笔记( 二 )


(1)根据DOUT/DRDY引脚是否变为低电平 。
(2)根据设定的数据传输速率做合理延时,例如完成一次转换需要最少1.2ms,因此在头两次寄存器配置写入之后,再延时2ms就可以执行数据读取 。
这两种方式的代码如下(注释为方式1):
ADC1_CS_LOW();delay_us(200);//第一次写入配置,返回值为上一次采集的数据SPI_ReadWrite16Bit(SPI1,data);//第二次写入配置,返回值为寄存器回读值tmp = SPI_ReadWrite16Bit(SPI1,data);delay_ms(2);//ADS1118_SPI_MISO_PIN引脚低电平指示新数据可用//GPIO_ResetBits(ADS1118_SPI_GPIO_PORT, ADS1118_SPI_MISO_PIN);//GPIO_InitStructure.GPIO_Pin = ADS1118_SPI_MISO_PIN;//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Init(ADS1118_SPI_GPIO_PORT, &GPIO_InitStructure);//while(GPIO_ReadInputDataBit(ADS1118_SPI_GPIO_PORT, ADS1118_SPI_MISO_PIN) != 0) ;//GPIO_InitStructure.GPIO_Pin = ADS1118_SPI_MISO_PIN;//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Init(ADS1118_SPI_GPIO_PORT, &GPIO_InitStructure);//GPIO_SetBits(ADS1118_SPI_GPIO_PORT, ADS1118_SPI_MISO_PIN);//读取转换数据value = http://www.kingceram.com/post/SPI_ReadWrite16Bit(SPI1,0x00FF);tmp = SPI_ReadWrite16Bit(SPI1,0x00FF);delay_us(200);ADC1_CS_HIGH();
2.3.2 获取温度传感器数据
内置14位的高精度温度传感器,可直接读取热电偶冷端温度,便于进行冷端温度补偿 。对于温度的数据格式,数据手册有如下说明:

基于STM32和ADS1118的热电偶设计笔记

文章插图
温度数据以 14 位结果呈现,与 16 位转换结果左对齐 。数据从最高有效字节 (MSB) 开始输出 。当读取这两个数据字节,前 14 位用来指定温度测量结果 。一个 14 位 LSB 等于 0.03125°C 。负数以二进制补码形式表示.
要将数字代码转换为温度,首先需要检查 MSB 是0还是1 。如果 MSB 为0,将十进制代码乘以 0.03125°C即可获得结果 。如果 MSB = 1,则将结果减“1”后对各位取补码 。之后将结果乘以 –0.03125°C 。
刚开始由于没有仔细看采用的是左对齐格式,对数据的处理就出了问题 。最后实在TI的论坛上看到的才又仔细看了一下数据手册 。
也就是说,在采集回温度数据之后:
(1)MSB为0,把数据右移两位,乘以 0.03125°C 。
(2)MSB为1,数据减1后取反,再右移两位,乘以 -0.03125°C 。
2.4 小结
至此,对于驱动编写的注意事项就说完了,总的来说都不是什么大问题,但是需要详细阅读数据手册,所以在编写驱动前一定要熟读数据手册,特别是对时序和数据格式的说明,一定要弄明白 。
3 热电偶数据处理
这里的数据处理就比较简单了,按照《简单的热电偶测量解决方案》 给出的软件方案来写就可以了 。
首先,读取热端的电压值,然后在读取冷端的温度,这里测得的片载温度转换为相应的所使用的热电偶类型的电压 。我们使用的是K型热电偶,因此就按照厂家提供的K型热电偶分度表进行转换 。才用了32点插值,通过手册给出的公式进行温度电压之间的转换 。
【基于STM32和ADS1118的热电偶设计笔记】/*温度(度)*/const u16 TempList[2][33] = /*电压(uV)*/{//K型热电偶分度表{0,5,10, 15, 20, 25,30,35,40,55,70,85,100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 220, 240, 260,280,300,400,500,600,700,800},{0,198,397,597,789,1000,1203,1407,1611,2229,2850,3473,4095,4508,4919,5327,5733,6137,6539,6939,7338,7737,8137,8938,9745,10560,11381,12207,16395,20640,24902,29128,33277}};
热电偶温度计算的代码如下:
//获取热端电压uVtemp->HotVoltage = ADS1118_WriteReadData(0,START_ADC1_DP_CH0) * 7.8125;//热电偶最大量程1375度,54875uVif(temp->HotVoltage >= TCMax) return 0xFFFF;//ADC温度传感器采集值转换为度tmp = (ADS1118_WriteReadData(0,START_ADC1_TS)) >> 2;//ADC温度1LSB为0.03125度temp->ColdTemp = tmp * 0.03125;//获取冷端电压(芯片温度转为分度表中的电压)temp->TInList = FindList(TinList,temp->ColdTemp);temp->ColdVoltage = (TempList[1][temp->VInList-1]+(TempList[1][temp->VInList]-TempList[1][temp->VInList-1])*((temp->ColdTemp-TempList[0][temp->VInList-1])/(TempList[0][temp->VInList]-TempList[0][temp->VInList-1])));//热电偶冷端温度补偿voltage = temp->HotVoltage + temp->ColdVoltage;//转换为热端实际温度temp->VInList = FindList(VinList,voltage);temp->Temperature =(TempList[0][temp->VInList-1]+(TempList[0][temp->VInList]-TempList[0][temp->VInList-1])*((voltage-TempList[1][temp->VInList-1])/(TempList[1][temp->VInList]-TempList[1][temp->VInList-1])));