嵌入式技术论坛
直播中

bigbangboom

8年用户 1313经验值
擅长:电源/新能源
私信 关注
[经验]

GD32F450驱动CS1237 ADC芯片步骤详解

一、说明

手中项目ADC芯片使用的是芯海科技的CS1237芯片,此芯片使用spi驱动,本以为通用spi就行了,结果ennn一看手册我的天,收发口是一个,spi是两线的我的天,一个CLK,另一个DRDY / DOUT发送数据接收数据一个口,然后看看咋控吧,我天啊,根据时钟个数第几个来说是读是写好麻烦啊,这样就不能使用通用spi借口了。

二、基本初始化

我这个项目CS1237因为在与单片机中间有隔离,又发现我去隔离器只能收数据,不能发数据,没办法了跳线吧,跟我们领导一说,领导拍板,接两根线,反正也是模拟的spi口,就这样芯片一个引脚接了两根线。好吧开始写。
首先初始化引脚,两个配置成输出模式,一个配置成输入模式,接的是PE2/PE4/PE5先初始化吧

rcu_periph_clock_enable(RCU_GPIOE);//使能时钟
//cs1237
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_2| GPIO_PIN_5);//PE2 时钟clk PE5 发送
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2| GPIO_PIN_5);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_4);//读取

三、正式编写读取配置芯片

下面正式开始配置读取接收函数,
查看手册时钟不能超过100us所以包装成函数吧,时钟拉高一个拉低一个。

void cs1237_clk_high(void)
{
gpio_bit_set(GPIOE, GPIO_PIN_2);
}
void cs1237_clk_low(void)
{
gpio_bit_reset(GPIOE, GPIO_PIN_2);
}
先看看数据接收发送的功能吧,好多字啊,脑袋大了


总的来说,想要只读取的话24个数据,还有三个输出寄存器状态更新标志的时钟,如果不需要配置,就只读取发送27个时钟就可以了。写一个吧

int32_t CS1237_read_data()
{
uint8_t i;
int32_t read_data;
if(! gpio_input_bit_get(GPIOE,GPIO_PIN_4))//判断数据是不是准备好了
{
//1-24个SCLK,读取ADC的转换结果
for(i=1; i<=24; i++)
{
read_data<<= 1;
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
if(gpio_input_bit_get(GPIOE,GPIO_PIN_4))
read_data++;
delay_us(1);
}
// 第25,26,27个时钟
for(i = 0; i < 3; i ++)
{
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
delay_us(1);
}
return read_data;
}
}
哎程序读取完成但是还需要配置啊,放弃只读取的函数吧重新写一个




int32_t cs1237_oper(int32_t read_data, uint8_t command, uint8_t register)
{

uint8_t i;
int32_t ad_data = 0;
uint8_t byte_temp;
if(! gpio_input_bit_get(GPIOE,GPIO_PIN_4))
{
//1-24个SCLK,读取ADC的转换结果
for(i=1; i<=24; i++)
{
ad_data <<= 1;
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
if(gpio_input_bit_get(GPIOE,GPIO_PIN_4))
ad_data++;
delay_us(1);
}
// 第25,26,27个时钟
for(i = 0; i < 3; i ++)
{
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
delay_us(1);
}
if(read_data)
*read_data = ad_data;
}
else
{
return -1;
}
// 数据读取完成,配置CS1237
if(command)
{
if(register == NULL)
return -2;

// 第28,29个时钟,直接跳过
for(i = 0; i < 2; i ++)
{
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
delay_us(1);
}
// 第30~36个时钟,写寄存器操作命令
byte_temp = command;
for(i = 0; i < 7; i ++)
{
cs1237_clk_high();
if(byte_temp & 0x40)
gpio_bit_set(GPIOE, GPIO_PIN_5);
else
gpio_bit_reset(GPIOE, GPIO_PIN_5);
delay_us(1);
cs1237_clk_low();
delay_us(1);
byte_temp <<= 1;
}
// 第37个时钟,芯片自动切换引脚状态
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
delay_us(1);
// 第38~45个时钟,输出或者读取寄存器的状态
if(command == 0x65)
{
// 写配置寄存器
byte_temp = *register;
for(i = 0; i < 8; i ++)
{
cs1237_clk_high();
if(byte_temp & 0x80)
gpio_bit_set(GPIOE, GPIO_PIN_5);
else
gpio_bit_reset(GPIOE, GPIO_PIN_5);
delay_us(1);
cs1237_clk_low();
delay_us(1);
byte_temp <<= 1;
}
}
else if(command == 0x56)
{
// 读配置寄存器
byte_temp = 0;
for(i = 0; i < 8; i ++)
{
byte_temp <<= 1;
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
if(gpio_input_bit_get(GPIOE,GPIO_PIN_4))
byte_temp ++;
delay_us(1);
}
*register = byte_temp;
}
else
return -3;
// 第46个时钟,CS1237切换为输出
cs1237_clk_high();
delay_us(1);
cs1237_clk_low();
delay_us(1);
}
return 0;
}

原作者:嚜軒公告

更多回帖

发帖
×
20
完善资料,
赚取积分