├── .gitignore ├── CS1237.c ├── CS1237.h ├── CS1237_bsp.c ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /CS1237.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CS1237.c 3 | * 4 | * Created on: 2023年3月12日 5 | * Author: Simgor001 6 | */ 7 | 8 | #include 9 | 10 | //基准电压 11 | static float ref = 2.5; 12 | //增益 13 | static int32_t Gain = 1; 14 | 15 | //建立时间 16 | static uint32_t buile_ti = 0; 17 | 18 | //数据采集使能(0不采集,1正常采集) 19 | static char towork = 0; 20 | 21 | //采集到的原始数据 22 | static int32_t raw_data = 0; 23 | 24 | 25 | /** 26 | *@brief 延迟 27 | *@param ms 毫秒 28 | **/ 29 | extern void _CS1237_ms(uint32_t ms); 30 | 31 | /** 32 | * @brief 延迟一个脉冲 33 | */ 34 | extern void _CS1237_Delay(); 35 | 36 | /** 37 | *@brief 初始化GPIO(需要移植) 38 | **/ 39 | extern void _CS1237_GPIO_Init(); 40 | 41 | /** 42 | *@brief 设置数据引脚方向为输入(需要移植) 43 | **/ 44 | extern void _CS1237_Input(); 45 | 46 | /** 47 | *@brief 设置数据引脚方向为输出(需要移植) 48 | **/ 49 | extern void _CS1237_Output(); 50 | 51 | /** 52 | *@brief 时钟输出低电平(需要移植) 53 | **/ 54 | extern void _CS1237_CLK_ResetBits(); 55 | 56 | /** 57 | *@brief 时钟输出高电平(需要移植) 58 | **/ 59 | extern void _CS1237_CLK_SetBits(); 60 | 61 | /** 62 | *@brief 数据输出低电平(需要移植) 63 | **/ 64 | extern void _CS1237_SDA_ResetBits(); 65 | 66 | /** 67 | *@brief 数据输出高电平(需要移植) 68 | **/ 69 | extern void _CS1237_SDA_SetBits(); 70 | 71 | /** 72 | *@brief 读取数据线的值(需要移植) 73 | **/ 74 | extern uint8_t _CS1237_SDA_ReadBits(); 75 | 76 | /*================================================================== 77 | * API层 78 | * ===============================================================*/ 79 | 80 | static inline void _CS1237_PowerUp() 81 | { 82 | //从掉电模式中唤醒 83 | _CS1237_CLK_ResetBits(); 84 | _CS1237_ms(2); 85 | } 86 | 87 | static inline void _CS1237_PowerDown() 88 | { 89 | //进入掉电模式 90 | _CS1237_CLK_SetBits(); 91 | } 92 | 93 | /** 94 | * @brief 唤醒芯片,开始采集数据 95 | */ 96 | void CS1237_Start() 97 | { 98 | _CS1237_PowerUp(); 99 | 100 | //设置引脚为输入模式 101 | _CS1237_Input(); 102 | 103 | //使能刷新 104 | towork = 1; 105 | } 106 | 107 | /** 108 | * @brief 结束采集数据,休眠芯片 109 | */ 110 | void CS1237_Finish() 111 | { 112 | //关闭刷新 113 | towork = 0; 114 | 115 | _CS1237_PowerDown(); 116 | } 117 | 118 | 119 | /** 120 | * @brief 发送一个脉冲 121 | */ 122 | static inline void _CS1237_Clock() 123 | { 124 | _CS1237_CLK_SetBits(); 125 | _CS1237_Delay(); 126 | _CS1237_CLK_ResetBits(); 127 | _CS1237_Delay(); 128 | } 129 | 130 | /** 131 | * @brief 读操作 132 | * 133 | * @param len 需要读的bit数量 134 | */ 135 | static uint32_t _CS1237_Read(char len) 136 | { 137 | uint32_t data = 0; 138 | char i; 139 | for (i = 0; i < len; ++i) 140 | { 141 | _CS1237_CLK_SetBits(); //上升沿 142 | _CS1237_Delay(); //等待至少500ns,因为SCLK上升沿到新数据位有效(传输延迟)至少455ns 143 | data <<= 1; 144 | if(_CS1237_SDA_ReadBits()) //读取数据 145 | ++data; 146 | 147 | _CS1237_CLK_ResetBits(); //下降沿 148 | _CS1237_Delay(); 149 | } 150 | return data; 151 | } 152 | 153 | 154 | /** 155 | * @brief 写操作 156 | * 157 | * @param data 需要写入的数据 158 | */ 159 | static void CS1237_Send(uint8_t data) 160 | { 161 | char i; 162 | for(i = 0; i < 8; ++i) 163 | { 164 | _CS1237_CLK_SetBits(); //上升沿 165 | _CS1237_Delay(); //等待至少500ns,因为SCLK上升沿到新数据位有效(传输延迟)至少455ns 166 | 167 | if(data & (1 << (7 - i))) 168 | _CS1237_SDA_SetBits(); 169 | else 170 | _CS1237_SDA_ResetBits(); 171 | 172 | _CS1237_CLK_ResetBits(); //下降沿 173 | _CS1237_Delay(); 174 | } 175 | } 176 | 177 | 178 | /** 179 | * @brief 刷新(1ms调用一次) 180 | * 181 | * -用于匹配建立时间,采集数据保存到缓冲区 182 | */ 183 | void CS1237_Ref() 184 | { 185 | //基准时间 186 | static uint32_t ti = 0; 187 | 188 | //是否需要采集数据,不需要就跳过 189 | if(towork == 0) 190 | return; 191 | 192 | ++ti; 193 | 194 | //等待所需的建立时间 195 | if(ti < buile_ti) 196 | return; 197 | ti = 0; 198 | 199 | //只有为低电平时,才表示数据准备就绪 200 | if(_CS1237_SDA_ReadBits()) 201 | return; 202 | 203 | //读取24位数据 204 | raw_data = _CS1237_Read(24); 205 | _CS1237_Clock(); //第25位 206 | _CS1237_Clock(); //第26位 207 | _CS1237_Clock(); //第27位 208 | } 209 | 210 | 211 | /** 212 | * @brief 初始化 213 | * 214 | * @param CS1237_InitStruct 配置参数指针 215 | * 216 | * @return -超时返回0,成功返回1 217 | */ 218 | char CS1237_Init(CS1237_InitTypedef* CS1237_InitStruct) 219 | { 220 | _CS1237_GPIO_Init(); 221 | 222 | char timeout = 0; 223 | while(_CS1237_SDA_ReadBits()) 224 | { 225 | _CS1237_ms(2); 226 | ++timeout; 227 | if(timeout > 20) 228 | return 0; 229 | } 230 | 231 | _CS1237_PowerUp(); 232 | 233 | _CS1237_Read(26); //前面26个时钟抛弃 234 | 235 | _CS1237_Output(); 236 | _CS1237_SDA_SetBits(); //强制拉高 237 | _CS1237_Clock(); //27 238 | _CS1237_Clock(); //28 239 | _CS1237_Clock(); //29 240 | 241 | 242 | CS1237_Send((CS1237_Config_Write << 1) + 1); //30~37(第37位用于切换方向) 243 | 244 | CS1237_Send(CS1237_InitStruct->CS1237_REFO| 245 | CS1237_InitStruct->CS1237_Speed| 246 | CS1237_InitStruct->CS1237_PGA| 247 | CS1237_InitStruct->CS1237_Channel);//38~45 248 | 249 | _CS1237_Input(); 250 | _CS1237_Clock(); 251 | 252 | //设置放大倍数 253 | if(CS1237_InitStruct->CS1237_PGA == CS1237_PGA_1) 254 | Gain = 1; 255 | else if(CS1237_InitStruct->CS1237_PGA == CS1237_PGA_2) 256 | Gain = 2; 257 | else if(CS1237_InitStruct->CS1237_PGA == CS1237_PGA_64) 258 | Gain = 64; 259 | else if(CS1237_InitStruct->CS1237_PGA == CS1237_PGA_128) 260 | Gain = 128; 261 | 262 | //按照速度设置建立时间 263 | if(CS1237_InitStruct->CS1237_Speed == CS1237_Speed_10Hz) 264 | buile_ti = 300; 265 | else if(CS1237_InitStruct->CS1237_Speed == CS1237_Speed_40Hz) 266 | buile_ti = 75; 267 | else if(CS1237_InitStruct->CS1237_Speed == CS1237_Speed_640Hz) 268 | buile_ti = 6; 269 | else if(CS1237_InitStruct->CS1237_Speed == CS1237_Speed_1280Hz) 270 | buile_ti = 3; 271 | 272 | return 1; 273 | } 274 | 275 | 276 | /** 277 | * @brief 异步获取电压 278 | */ 279 | double CS1237_GetData() 280 | { 281 | if(towork == 0) 282 | return 0; 283 | 284 | //转换之后的数据 285 | int32_t data = 0; 286 | 287 | //计算后的电压 288 | double u = 0; 289 | 290 | //设置符号位 291 | if(raw_data & (1 << 23)) 292 | { 293 | //负数 294 | data = ~raw_data; 295 | data = -((data + 1) & 0x00FFFFFF); 296 | } 297 | else 298 | { 299 | data = raw_data; 300 | } 301 | 302 | u = data * (0.5 * ref / Gain) / 8388607.0; 303 | return u; 304 | } 305 | -------------------------------------------------------------------------------- /CS1237.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Simgor001/CS1237/15e3f345ac34d0f1fe5092ef36f58722e0e8dcac/CS1237.h -------------------------------------------------------------------------------- /CS1237_bsp.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Simgor001/CS1237/15e3f345ac34d0f1fe5092ef36f58722e0e8dcac/CS1237_bsp.c -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Simgor001 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CS1237 2 | 一个通用的CS1237驱动库 3 | 4 | [使用例见此项目](https://github.com/Simgor001/FWMA_Filter) 5 | 6 | # 介绍 7 | - 这是一个异步获取数据的库,需要每1ms调用一次CS1237_Ref(),以获取新的数据 8 | - 暂时只支持单路CS1237,后续可能会更新多路支持 9 | - 理论上支持所有控制芯片,只需要移植CS1237_bsp.c文件的内容 10 | - 注意_CS1237_ms(uint32_t ms)和_CS1237_Delay()函数的移植 11 | 12 | # 使用流程: 13 | - 移植CS1237_bsp.c文件的内容,让其适配您使用的处理器 14 | - 调用CS1237_Init函数,将CS1237芯片初始化 15 | - 调用CS1237_Start函数,让芯片上电,并且开始采集数据 16 | - 调用CS1237_GetData函数,返回当前采集到的电压值 17 | - (可选)调用CS1237_Finish函数,让CS1237芯片进入掉电模式 18 | 19 | ## CH32V203C8T6代码参考 20 | 21 | C文件如下: 22 | ``` c 23 | // main.c 24 | #include 25 | #include "debug.h" 26 | /* Global typedef */ 27 | 28 | /* Global define */ 29 | 30 | /* Global Variable */ 31 | 32 | void tim2_init() 33 | { 34 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 35 | 36 | TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; 37 | TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; 38 | TIM_TimeBaseInitStruct.TIM_Prescaler = SystemCoreClock / 1000000 - 1; 39 | TIM_TimeBaseInitStruct.TIM_Period = 1000; 40 | TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); 41 | TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 42 | 43 | NVIC_InitTypeDef NVIC_InitStruct; 44 | NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; 45 | NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; 46 | NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; 47 | NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; 48 | NVIC_Init(&NVIC_InitStruct); 49 | 50 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 51 | GPIO_InitTypeDef GPIO_InitStruct; 52 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; 53 | GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 54 | GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; 55 | GPIO_Init(GPIOA, &GPIO_InitStruct); 56 | 57 | TIM_Cmd(TIM2, ENABLE); 58 | } 59 | 60 | 61 | /********************************************************************* 62 | * @fn main 63 | * 64 | * @brief Main program. 65 | * 66 | * @return none 67 | */ 68 | 69 | int main(void) 70 | { 71 | double data = 0; 72 | 73 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 74 | tim2_init(); 75 | Delay_Init(); 76 | USART_Printf_Init(115200); 77 | printf("SystemClk:%d\r\n", SystemCoreClock); 78 | 79 | CS1237_InitTypedef CS1237_InitStruct; 80 | CS1237_InitStruct.CS1237_Channel = CS1237_Channel_A; 81 | CS1237_InitStruct.CS1237_PGA = CS1237_PGA_1; 82 | CS1237_InitStruct.CS1237_REFO = CS1237_REFO_DISABLE; 83 | CS1237_InitStruct.CS1237_Speed = CS1237_Speed_10Hz; 84 | 85 | if(CS1237_Init(&CS1237_InitStruct) == 0) 86 | { 87 | printf("初始化超时!\r\n"); 88 | while(1); 89 | } 90 | Delay_Ms(2); 91 | 92 | CS1237_Start(); 93 | while(1) 94 | { 95 | data = CS1237_GetData(); 96 | printf("当前电压:%.5lf\r\n",data); 97 | 98 | Delay_Ms(100); 99 | } 100 | } 101 | ``` 102 | 103 | 定时中断内容: 104 | ``` c 105 | void TIM2_IRQHandler(void) 106 | { 107 | if (TIM_GetITStatus(TIM2, TIM_IT_Update)) 108 | { 109 | CS1237_Ref(); 110 | TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 111 | } 112 | } 113 | ``` 114 | 115 | # 未实现功能 116 | - 温度计算功能 117 | - 多路CS1237功能 118 | - 滤波算法 119 | --------------------------------------------------------------------------------