#include #include "spi.h" #include "cs1180.h" #include "clock.h" #define CS1180_RDATA 0X01 #define CS1180_RDATAC 0X03 #define CS1180_STOPC 0x0f #define CS1180_RREG 0x10 #define CS1180_WREG 0x50 #define CS1180_CALSELF 0xf0 #define CS1180_OCALSELF 0xf1 #define CS1180_SLFGCAL 0xf2 #define CS1180_OCALSYS 0xf3 #define CS1180_GCALSYS 0xf4 #define CS1180_WAKEUP 0xfb #define CS1180_SYNC 0xfc #define CS1180_SLEEP 0xfd #define CS1180_RESET 0xfe static float _cs1180_gain = 1.0f; #define CS1180_INIT_GAIN CS1180_GAIN_128X static int cs1180_send_cmd(uint8_t data); static uint8_t cs1180_read_data(uint8_t data); static void cs1180_reset(void); void cs_delay(void) { uint32_t count = 60; while(count--); } static int _cs1180_ready = 0; int cs1180_is_ready(void){ return _cs1180_ready; } static void spi_write_reg(uint8_t reg, uint8_t *data, uint8_t len){ cs1180_send_cmd(CS1180_WREG|reg); cs1180_send_cmd(len - 1); while(len -- > 0){ cs1180_send_cmd(*data); data++; } } static void spi_read_reg(uint8_t reg, uint8_t *data, uint8_t len){ cs1180_send_cmd(CS1180_RREG|reg); cs1180_send_cmd(len - 1); while(len -- > 0){ *data = cs1180_read_data(0xFF); data++; } } static uint8_t cs1180_dumy_read(void){ uint8_t data[16] = {0x5A, 0x5A, 0x5A}; while (IS_CS1180_READY()); cs1180_cs(0); cs_delay(); spi_read_reg(0x0, data, 16); cs_delay(); cs1180_cs(1); return data[0]; } /* 对芯片的偏移误差和增益误差进行纠正 */ static void cs1180_self_calibrate(void) { cs1180_cs(0); cs_delay(); cs1180_send_cmd(CS1180_CALSELF); cs_delay(); cs1180_cs(1); delay_us(50); /* wait calibrate finished */ while (IS_CS1180_READY()); while (!IS_CS1180_READY()); delay_us(50 * 1000); while (IS_CS1180_READY()); //drop first data } /* 对芯片的偏移误差进行纠正 */ __attribute__((unused)) static void cs1180_self_offset_calibrate(void) { cs1180_cs(0); cs1180_send_cmd(CS1180_OCALSELF); cs1180_cs(1); delay_us(50); /* wait calibrate finished */ while (IS_CS1180_READY()); while (!IS_CS1180_READY()); } /* 对芯片的增益误差进行纠正 */ __attribute__((unused)) static void cs1180_self_gain_calibrate(void) { cs1180_cs(0); cs1180_send_cmd(CS1180_SLFGCAL); cs1180_cs(1); delay_us(50); /* wait calibrate finished */ while (IS_CS1180_READY()); while (!IS_CS1180_READY()); } /* 对系统的失调误差(偏移误差)进行纠正, 必须要求输入为差分电压为0, */ void cs1180_sys_offset_calibrate(void) { cs1180_cs(0); cs_delay(); cs1180_send_cmd(CS1180_OCALSYS); delay_us(50); cs1180_cs(1); delay_us(50); /* wait calibrate finished */ while (IS_CS1180_READY()); while (!IS_CS1180_READY()); delay_us(10 * 1000); while (IS_CS1180_READY()); //drop first data } /* 对系统的增益误差进行纠正,必须输入正满幅度的电压, SP700,SP600未提供满辐电压,故这一项不做 */ __attribute__((unused)) static void cs1180_sys_gain_calibrate(void) { cs1180_cs(0); cs1180_send_cmd(CS1180_GCALSYS); cs1180_cs(1); delay_us(50); /* wait calibrate finished */ while (IS_CS1180_READY()); while (!IS_CS1180_READY()); } static void _cs1180_adc_set_gain(int gain){ /* 输出频率 15hz,参考电压1.235V 输出数据高位在前, * 输入缓冲器关闭,采样频率 OSC/128,数据格式双极性 */ uint8_t data[] = {0x00, 0x01, 0x00}; data[0] = 0xF & gain; cs1180_cs(0); cs_delay(); spi_write_reg(0x00, data, 3); cs_delay(); cs1180_cs(1); _cs1180_gain = 1 << gain; cs1180_self_calibrate(); cs1180_dumy_read(); } int cs1180_adc_set_gain(int gain){ int count = 0; do { cs1180_reset(); delay_us(10); _cs1180_adc_set_gain(gain); delay_us(10); if (cs1180_dumy_read() == gain){ break; } count ++; }while(count <= 20); if (count >= 20) { if (cs1180_dumy_read() != gain){ return -1; } } delay_us(10*1000); cs1180_sys_offset_calibrate(); cs1180_dumy_read(); return 0; } static void cs1180_reset(void){ cs1180_cs(0); cs_delay(); cs1180_send_cmd(CS1180_RESET); cs_delay(); cs1180_cs(1); } void cs1180_adc_init(void){ _cs1180_ready = 0; CS1180_PWR_ENABLE(0); delay_us(100 * 1000); CS1180_PWR_ENABLE(1); delay_us(200 * 1000); spi1_init(); delay_us(10); _cs1180_ready = cs1180_adc_set_gain(CS1180_INIT_GAIN) == 0; } void cs1180_adc_shutdown(void){ CS1180_PWR_ENABLE(0); spi1_deinit(); _cs1180_ready = 0; } float cs1180_adc_sample(void) { uint8_t data[3] = {0,0,0}; int a = 0; while (IS_CS1180_READY()); //当drdy 为高时,不读取数据 cs1180_cs(0); //spi_read_reg(0xD, data, 3); cs1180_send_cmd(CS1180_RDATA); data[0] = cs1180_read_data(0xFF); data[1] = cs1180_read_data(0xFF); data[2] = cs1180_read_data(0xFF); cs1180_cs(1); a = (data[0] << 16) | (data[1] << 8) | data[2]; a >>= 4; if (a & 0x80000) { a = ~a; a = - (a&0x7FFFF); }else { a = a&0x7FFFF; } return ((float)a) / _cs1180_gain * 0.9f;/* 0.9是一个多个板子测试后的值,具体什么原因需要再分析*/ } static int cs1180_send_cmd(uint8_t cmd){ return spi1_send_byte(cmd, NULL); } static uint8_t cs1180_read_data(uint8_t data){ uint8_t r_data = 0xFF; spi1_send_byte(data, &r_data); return r_data; }