CS1180是高精度、低功耗模数转换芯片。其分辨率为 20bit,有效分辨率可达 19 位。可以广泛使用在工艺控制、量重、液体/气体化学分析、血液分析、智能发送器、便携测量仪器领域。
本次主要以智能变送器为主 采集电压电流值稳控
首先我们看一下管脚说明
主要以spi通信方式为主,我这里是用到两个adc芯片 SDI、SDO、SCLK、三线共用,以片选不同采集不同路的数据
接下来看规格书要求的通信时序
按照要求编写即可
接下来就是我们要操作的寄存器 以下是主要寄存器
SETUP和MUX在初始化中配置,增益倍数选择,默认是0,测试中4倍也是可以读到的
这里要注意ACR寄存器使用单极性输出,时钟选择/256,这个要根据你的时钟选择判断,转换范围选择也要选择VERF/2的,是有哪位我的外部电路输入电压不同导致选择的不同 其他位用默认值0即可
ODAC寄存器配置为0x30,这里我也没有特别理解,网上搜到的驱动是这样写的,可能与你本身的硬件电路有关,我买的是cs1180集成板,里面电路已经确定的,如果各位知道原因的话,也教一下我,谢谢
主要的内容就是以上,接下来直接看代码,如有疑问和问题,敬请指出
#define SETUP 0X00
#define MUX 0X01
#define ACR 0X02
#define ODAC 0X03
#define DIO 0X04
#define DIR 0X05
#define IOCON 0X06
#define OCC0 0X07
#define OCC1 0X08
#define OCC2 0X09
#define GCC0 0X0A
#define GCC1 0X0B
#define GCC2 0X0C
#define DOR2 0X0D
#define DOR1 0X0E
#define DOR0 0X0F
#define RDATA 0X01
#define RDATAC 0X03
#define STOPC 0X0F
#define RREG 0X10
#define WREG 0X50
#define CALSELF 0XF0
#define OCALSELF 0XF1
#define GCALSELF 0XF2
#define OCALSYS 0XF3
#define GCALSYS 0XF4
#define WAKEUP 0XFB
#define SYNC 0XFC
#define SLEEP 0XFD
#define RESET 0XFE
#define P_ADD 0XA3
#define SPI_SDI(n) (n?gpio_bit_set(GPIOA, GPIO_PIN_6):gpio_bit_reset(GPIOA, GPIO_PIN_6))
#define SPI_SCK(n) (n?gpio_bit_set(GPIOA, GPIO_PIN_0):gpio_bit_reset(GPIOA, GPIO_PIN_0))
#define SPI_SDO_READ() gpio_input_bit_get(GPIOA,GPIO_PIN_5)
#define VOL_EXTI_LINE EXTI_4
#define CURR_EXTI_LINE EXTI_5
unsigned long curr_adc,vol_adc;
void ADC_GPIO_init()
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0);
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_4);
gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_5);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN4);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN5);
exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_4);
exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_5);
}
void Write_One_Byte(unsigned char Byte)
{
char i=0;
SPI_SCK(1);
for(;i<8;i++)
{
if(Byte&(0x80>>i))
{
SPI_SDI(1);
}
else
{
SPI_SDI(0);
}
Delay1us();
SPI_SCK(0);
Delay1us();
SPI_SCK(1);
Delay1us();
}
}
unsigned char Read_One_Byte(void)
{
char i=0;
unsigned char Data = 0;
SPI_SCK(1);
for(;i<8;i++)
{
SPI_SCK(0);
Delay1us();
Data = (Data << 1) | SPI_SDO_READ();
Delay1us();
SPI_SCK(1);
Delay1us();
}
return Data;
}
unsigned long Read_Adc_Data(void)
{
unsigned long datah;
unsigned long datam,datal;
unsigned long c=0;
datal=datam=datah=0;
Write_One_Byte(0x01);
Delay1us();
datah=Read_One_Byte();
datam=Read_One_Byte();
datal=Read_One_Byte();
c=datah<<8|datam;
return(c);
}
#if 0
unsigned char Write_Reg_Data(char start_reg_addr,char reg_data)
{
char err_num = 0;
Write_One_Byte(0x50|start_reg_addr);
Write_One_Byte(0x00);
Write_One_Byte(reg_data);
return 0;
}
#endif
void CS1180_ADC_Init(void)
{
ADC_GPIO_init();
gpio_bit_reset(GPIOA, GPIO_PIN_7);
gpio_bit_set(GPIOC, GPIO_PIN_7);
Write_One_Byte(RESET);
Delay1us();
Write_Reg_Data(SETUP,0x00);
Write_Reg_Data(ACR,0x62);
Write_Reg_Data(ODAC,0x30);
delay_ms(5);
while(DRDY1 == 1);
Read_One_Byte();
delay_ms(5);
gpio_bit_set(GPIOA, GPIO_PIN_7);
gpio_bit_set(GPIOC, GPIO_PIN_7);
gpio_bit_reset(GPIOA, GPIO_PIN_7);
Write_One_Byte(RESET);
Delay1us();
Write_Reg_Data(SETUP,0x00);
Write_Reg_Data(ACR,0x62);
Write_Reg_Data(ODAC,0x30);
delay_ms(5);
while(DRDY2 == 1);
Read_One_Byte();
delay_ms(5);
delay_ms(5);
gpio_bit_set(GPIOC, GPIO_PIN_7);
nvic_irq_enable(EXTI4_IRQn, 2U, 0U);
nvic_irq_enable(EXTI5_9_IRQn, 1U, 0U);
}
void EXTI5_9_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(VOL_EXTI_LINE)) {
nvic_irq_disable(EXTI5_9_IRQn);
exti_interrupt_flag_clear(VOL_EXTI_LINE);
gpio_bit_reset(GPIOC, GPIO_PIN_7);
vol_adc = Read_Adc_Data() & 0xFFFFFF;
gpio_bit_set(GPIOC, GPIO_PIN_7);
}
nvic_irq_enable(EXTI5_9_IRQn, 1U, 0U);
}
void EXTI4_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(CURR_EXTI_LINE)) {
nvic_irq_disable(EXTI4_IRQn);
exti_interrupt_flag_clear(CURR_EXTI_LINE);
gpio_bit_reset(GPIOA, GPIO_PIN_7);
curr_adc = Read_Adc_Data() & 0xFFFFFF;
gpio_bit_set(GPIOA, GPIO_PIN_7);
}
nvic_irq_enable(EXTI4_IRQn, 1U, 0U);
}
原作者:兆易创新GD32 MCU Phoenix_dz9WiU