GD32使用CS1237通过ADC采集温度
一.CS1237的配置文档
读和写的命令
注:需要注意PGA的放大倍数,不要超出了CS1237的输入的范围,要不然会输出最大值。
二.源码
CS1237.h文件
#ifndef __CS1237_H__
#define __CS1237_H__
#include "gd32f30x.h"
#include "delay.h"
#define CLK_TIME 50 // max 50us
//************************************************************************************************************
typedef enum
{
C1237_PIN_0=GPIO_PIN_0,
C1237_PIN_1=GPIO_PIN_1,
C1237_PIN_2=GPIO_PIN_2,
C1237_PIN_3=GPIO_PIN_3,
C1237_PIN_11=GPIO_PIN_11,
C1237_PIN_12=GPIO_PIN_12,
C1237_PIN_14=GPIO_PIN_14,
C1237_PIN_15=GPIO_PIN_15,
}C1237_GPIO;
//************************************************************************************************************
typedef enum
{
C1237_RCUG=RCU_GPIOG,
C1237_RCUE=RCU_GPIOE,
}C1237_GPIO_RCU;
//************************************************************************************************************
typedef enum
{
C1237_PORTG=GPIOG,
C1237_PORTE=GPIOE,
}C1237_GPIO_PORT;
//************************************************************************************************************
typedef enum
{
C1237_10HZ = 0,
C1237_40HZ = 1,
C1237_640HZ = 2,
C1237_1280HZ = 3
}C1237_SPEED;
//************************************************************************************************************
typedef enum
{
C1237_PGA_1 = 0,
C1237_PGA_2 = 1,
C1237_PGA_64 = 2,
C1237_PGA_128 = 3
}C1237_PGA;
//************************************************************************************************************
typedef enum
{
C1237_CHA = 0, //adc channel
C1237_RST = 1, //cheap reserved
C1237_TEM = 2, //temperature test
C1237_INS = 3 //internal short
}C1237_CHN;
/************************************************************************************************************
Function: C1237_OneClk();
Return value: void
Discription: C1237 input a clk pusle for to read or write
Example:
C1237_OneClk();
*************************************************************************************************************/
void C1237_OneClk(C1237_GPIO_PORT CS1237_CLK_PORT,C1237_GPIO CS1237_CLK_PIN);
/************************************************************************************************************
Function: CS1237_ReadReg();
Return value: u8
Discription: read CS1237 register
Example:
CS1237_ReadReg();
*************************************************************************************************************/
int16_t CS1237_ReadReg(C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT);
/************************************************************************************************************
Function: C1237_WriteReg(u8 mData);
Return value: void
Discription: wreite data to C1237 register
Example:
C1237_WriteReg(mData);
*************************************************************************************************************/
void C1237_WriteReg(int16_t mData,C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT);
/************************************************************************************************************
Function: C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn);
Return value: void
Discription: CS1237 init
Example:
C1237_Init(0,C1237_10HZ,C1237_PGA_1,C1237_CHA);//ref voltage out disable,speed 10Hz,Pga 1, work at Adc mode
*************************************************************************************************************/
void C1237_Init(unsigned char refOutable, C1237_SPEED msel, C1237_PGA mselPga, C1237_CHN mselChn,C1237_GPIO_RCU CS1237_Data_RCU,C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT);
/************************************************************************************************************
Function: C1237_ReadResult();
Return value: u32
Discription: read C1237 A/D result
Example:
C1237_ReadResult();
*************************************************************************************************************/
int32_t C1237_ReadResult(C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT);
float resistance_to_temprature(float resistance);
extern int32_t ADC_REG_REG_SET;
#endif
CS1237.c文件
/*
* Copyright (c) 2006-2022, yang Team
*
* SPDX-License-Identifier: NONE
*
*Change Logs:
* Date Author Notes
* 2022-xx-xx linchenuyang first implementation
*/
#include "cs1237.h"
#define CS1237_Data_PIN_STATE() gpio_input_bit_get(CS1237_Data_PORT,CS1237_Data_PIN)
//*************************************************************************************************************
void CS1237_Data_IS_Out_HIGH(C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO CS1237_Data_PIN)
{
gpio_init(CS1237_Data_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CS1237_Data_PIN);
gpio_bit_write(CS1237_Data_PORT,CS1237_Data_PIN,SET);
}
//*************************************************************************************************************
void CS1237_Data_IS_Out_LOW(C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO CS1237_Data_PIN)
{
gpio_init(CS1237_Data_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CS1237_Data_PIN);
gpio_bit_write(CS1237_Data_PORT,CS1237_Data_PIN,RESET);
}
//*************************************************************************************************************
void CS1237_Data_IS_INPUT(C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO CS1237_Data_PIN)
{
gpio_init(CS1237_Data_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CS1237_Data_PIN);
gpio_bit_write(CS1237_Data_PORT,CS1237_Data_PIN,SET);
}
//*************************************************************************************************************
void CS1237_Data_IS_INPUT_LOW(C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO CS1237_Data_PIN)
{
gpio_init(CS1237_Data_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CS1237_Data_PIN);
gpio_bit_write(CS1237_Data_PORT,CS1237_Data_PIN,RESET);
}
//*************************************************************************************************************
void CS1237_SCLK_HIHG(C1237_GPIO_PORT CS1237_CLK_PORT,C1237_GPIO CS1237_CLK_PIN)
{
gpio_init(CS1237_CLK_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CS1237_CLK_PIN);
gpio_bit_write(CS1237_CLK_PORT,CS1237_CLK_PIN,SET);
}
//*************************************************************************************************************
void CS1237_SCLK_LOW(C1237_GPIO_PORT CS1237_CLK_PORT,C1237_GPIO CS1237_CLK_PIN)
{
gpio_init(CS1237_CLK_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CS1237_CLK_PIN);
gpio_bit_write(CS1237_CLK_PORT,CS1237_CLK_PIN,RESET);
}
//*************************************************************************************************************
void C1237_OneClk(C1237_GPIO_PORT CS1237_CLK_PORT,C1237_GPIO CS1237_CLK_PIN)
{
CS1237_SCLK_HIHG(CS1237_CLK_PORT,CS1237_CLK_PIN);
delay(CLK_TIME);
CS1237_SCLK_LOW(CS1237_CLK_PORT,CS1237_CLK_PIN);
delay(CLK_TIME);
}
//*************************************************************************************************************
int16_t CS1237_ReadReg(C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT)
{
int16_t i = 0;
int16_t tem = 0;
CS1237_SCLK_LOW(CS1237_CLK_PORT,CS1237_CLK_PIN);
delay(50);//Wakeup MCU
CS1237_Data_IS_INPUT(CS1237_Data_PORT,CS1237_Data_PIN); //输入模式
while (CS1237_Data_PIN_STATE())//需要实际工程使用需要加入超时
{
i++;
delay_1ms(1);//ms
}
for (i = 0; i < 27; i++) // 1-26th CLK
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN); //Force High cs1237 direction input
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 28th CLK
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 29th CLK
//
tem = 0xAC; // PIN out //读命令(0x56)左移1位
for (i = 0; i < 7; i++) // 30~36th CLK
{
if (tem & 0x80)
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN);
else
CS1237_Data_IS_Out_LOW(CS1237_Data_PORT,CS1237_Data_PIN);
tem <<= 1;
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
}
CS1237_Data_IS_INPUT( CS1237_Data_PORT,CS1237_Data_PIN); // cs1237 change to output direction
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 37th CLK
for (i = 0; i < 8; i++) // 37~45th CLK
{
tem <<= 1;
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
if (CS1237_Data_PIN_STATE())
tem++;
}
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
; // 46th CLK
return tem;
}
// End of CS1237_ReadReg()
//*************************************************************************************************************
void C1237_WriteReg(int16_t mData,C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT)
{
int16_t i = 0;
int16_t tem = 0;
CS1237_SCLK_LOW(CS1237_CLK_PORT,CS1237_CLK_PIN);
delay(50);//Wakeup MCU
CS1237_Data_IS_INPUT( CS1237_Data_PORT,CS1237_Data_PIN);
while (CS1237_Data_PIN_STATE())//需要实际工程使用需要加入超时
{
i++;
delay_1ms(1);//ms
}
for (i = 0; i < 27; i++) // 1~26th CLK
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
//C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);//27th CLK
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN); // force high
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 28th CLK
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 29th CLK
tem = 0xCA;//写命令(0x65)左移1位
for (i = 0; i < 7; i++) // 30~36th CLK
{
if (tem & 0x80)
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN);
else
CS1237_Data_IS_Out_LOW(CS1237_Data_PORT,CS1237_Data_PIN);
tem <<= 1;
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
}
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN); // direction chage to intput direction
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 37th CLK
for (i = 0; i < 8; i++) // 38~45th CLK
{
if (mData & 0x80)
CS1237_Data_IS_Out_HIGH(CS1237_Data_PORT,CS1237_Data_PIN);
else
CS1237_Data_IS_Out_LOW(CS1237_Data_PORT,CS1237_Data_PIN);
mData <<= 1;
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
}
CS1237_Data_IS_INPUT( CS1237_Data_PORT,CS1237_Data_PIN);
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN); // 46th CLK
}
// End of C1237_WriteReg(u8 mData)
//*************************************************************************************************************
int32_t ADC_REG_REG_SET;
void C1237_Init(unsigned char refOutable, C1237_SPEED msel, C1237_PGA mselPga, C1237_CHN mselChn,C1237_GPIO_RCU CS1237_Data_RCU,C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT)
{
volatile int16_t tem = 0;
tem= ((refOutable&0x1)<<6)|((msel&0x03)<<4)|((mselPga&0x03)<<2)|((mselChn&0x03)<<0);
rcu_periph_clock_enable(CS1237_Data_RCU);//PG时钟使能
ADC_REG_REG_SET = tem;
C1237_WriteReg(tem,CS1237_Data_PIN, CS1237_CLK_PIN,CS1237_Data_PORT,CS1237_CLK_PORT);
}
// End of C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn)
//*************************************************************************************************************
int32_t C1237_ReadResult(C1237_GPIO CS1237_Data_PIN,C1237_GPIO CS1237_CLK_PIN,C1237_GPIO_PORT CS1237_Data_PORT,C1237_GPIO_PORT CS1237_CLK_PORT)
{
int16_t i;
int32_t rdata = 0;
CS1237_SCLK_LOW(CS1237_CLK_PORT,CS1237_CLK_PIN);
delay(50);//Wakeup MCU
CS1237_Data_IS_INPUT( CS1237_Data_PORT,CS1237_Data_PIN);
while (CS1237_Data_PIN_STATE())//需要实际工程使用中断替换
{
i++;
delay_1ms(1);//ms
}
for (i = 0; i < 24; i++)
{
rdata <<= 1;
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
if (CS1237_Data_PIN_STATE()) // read data
rdata++;
}
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
C1237_OneClk(CS1237_CLK_PORT, CS1237_CLK_PIN);
return rdata;
}
// End of C1237_ReadResult()
ADC值转温度文件(使用的PT1000)
#define LOW_LIMIT_TEMP (-1) //最低温度8度
#define MAX_LIMIT_TEMP (1) //最高温度150度
// PT1000分度表 8~ 150度
const float PT1000_Table[143]=
{
1031.23, 1035.13, //8 ~ 9
1039.03, 1042.92, 1046.82, 1050.71, 1054.60, 1058.49, 1062.38, 1066.27, 1070.16, 1074.05, //10 ~ 19
1077.94, 1081.82, 1085.70, 1089.59, 1093.47, 1097.35, 1101.23, 1105.10, 1108.98, 1112.86, //20 ~ 29
1116.73, 1120.60, 1124.47, 1128.35, 1132.21, 1136.08, 1139.95, 1143.82, 1147.68, 1151.55, //30 ~ 39
1155.41, 1159.27, 1163.13, 1166.99, 1170.85, 1174.70, 1178.56, 1182.41, 1186.27, 1190.12, //40 ~ 49
1193.97, 1197.82, 1201.67, 1205.52, 1209.36, 1213.21, 1217.05, 1220.90, 1224.74, 1228.58, //50 ~ 59
1232.42, 1236.26, 1240.09, 1243.93, 1247.77, 1251.60, 1255.43, 1259.26, 1263.09, 1266.92, //60 ~ 69
1270.75, 1274.58, 1278.40, 1282.23, 1286.05, 1289.87, 1293.70, 1297.52, 1301.33, 1305.15, //70 ~ 79
1308.97, 1312.78, 1316.60, 1320.41, 1324.22, 1328.03, 1331.84, 1335.65, 1339.46, 1343.26, //80 ~ 89
1347.07, 1350.87, 1354.68, 1358.48, 1362.28, 1366.08, 1369.87, 1373.67, 1377.47, 1381.26, //90 ~ 99
1385.06, 1388.85, 1392.64, 1396.43, 1400.22, 1404.00, 1407.79, 1411.58, 1415.36, 1419.14, //100 ~ 109
1422.93, 1426.71, 1430.49, 1434.26, 1438.04, 1441.82, 1445.59, 1449.37, 1453.14, 1456.91, //110 ~ 119
1460.68, 1464.45, 1468.22, 1471.99, 1475.75, 1479.52, 1483.28, 1487.04, 1490.81, 1494.56, //120 ~ 129
1498.32, 1502.08, 1505.84, 1509.59, 1513.35, 1517.10, 1520.85, 1524.60, 1528.39, 1532.14, //130 ~ 139
1535.85, 1539.59, 1543.34, 1547.08, 1550.82, 1554.57, 1558.31, 1562.05, 1565.78, 1569.52, //140 ~ 149
1573.26 //150
};
/******************************************************************************
函数名 : resistance_to_temprature(float resistance)
功能 : 计算PT1000阻值对应的温度
输入参数 : 阻值
返回值 : 温度值
******************************************************************************
*/
float resistance_to_temprature(float resistance)
{
int i=0;
float temprature;
if (resistance < PT1000_Table[0]) //超出范围
{
return LOW_LIMIT_TEMP;
}
if (resistance > PT1000_Table[142])//超出范围
{
return MAX_LIMIT_TEMP;
}
while(i<143)
{
if (resistance < PT1000_Table[i])
{
break;
}
i++;
}
temprature = 8+i;
return temprature;
}
主函数调用方法
float ADC_REG_REG;
float ADC_TEMPERATURE;
C1237_Init(0,C1237_40HZ,C1237_PGA_1,C1237_CHA,C1237_RCUG,C1237_PIN_2,C1237_PIN_3,C1237_PORTG,C1237_PORTG); // 0Cs1237初始化
delay_1ms(50);
ADC_REG_REG=C1237_ReadResult(C1237_PIN_2,C1237_PIN_3,C1237_PORTG,C1237_PORTG)/4068060.199*1000;
delay_1ms(50);
ADC_TEMPERATURE=resistance_to_temprature(ADC_REG_REG);
三.引用
1.在C1237_Init初始化函数中设置好CS1237的工作模式和设置DO和SCLK接脚;
2.调用C1237_ReadResult函数,设置DO和SCLK接脚;