cs1242.c
#include <stdint.h>
#include "system/includes.h"
#include "media/includes.h"
#include "asm/spi.h"
#include "generic/log.h"
#include "cs1242.h"
#include "asm/mcpwm.h"
#include "generic/typedef.h"
#include "generic/gpio.h"
#if 1 // TCFG_CS1242_ENABLE
hi_t hi_para;
/*
CS1242_TSSOP16的SPI模式
时钟极性(CPOL):0(SCLK空闲时为低电平)
时钟相位(CPHA):1(数据在SCLK的下降沿采样)
*/
static u8 slave_dir = 1;
static u32 spi2_recv_buf;
static spi_dev spi2_hdl = 2;
void Delay1_us(u32 d) // AT(.common) //大概是2.7us
{
while (d--)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
void spi2_drdy_init(void)
{
gpio_set_pull_up(IO_PORTA_09, 1);
gpio_set_pull_down(IO_PORTA_09, 0);
gpio_set_direction(IO_PORTA_09, 1);
gpio_set_die(IO_PORTA_09, 1);
}
void GPIO_Init_Output(u32 GPIOx, int value)
{
gpio_set_pull_up(GPIOx, 0);
gpio_set_pull_down(GPIOx, 0);
gpio_set_direction(GPIOx, 0);
gpio_set_output_value(GPIOx, value);
}
void GPIO_Init_Input(u32 GPIOx)
{
gpio_set_pull_up(GPIOx, 1);
gpio_set_pull_down(GPIOx, 0);
gpio_set_direction(GPIOx, 1);
gpio_set_die(GPIOx, 1);
}
void SPI_Init()
{
GPIO_Init_Output(MOSI_PIN, LOW); // 配置MOSI为输出模式
GPIO_Init_Input(MISO_PIN); // 配置MISO为输入模式
GPIO_Init_Output(SCLK_PIN, LOW); // 配置SCLK为输出模式
GPIO_Init_Output(CS_PIN, HIGH); // 配置CS为输出模式
spi2_drdy_init(); // 配置DRDY为输入模式
}
void GPIO_WriteHigh(u32 GPIOx)
{
gpio_set_output_value(GPIOx, HIGH);
}
void GPIO_WriteLow(u32 GPIOx)
{
gpio_set_output_value(GPIOx, LOW);
}
void GPIO_Toggle(u32 GPIOx)
{
Delay1_us(1);
gpio_set_output_value(GPIOx, 1);
Delay1_us(1);
gpio_set_output_value(GPIOx, 0);
}
void SPI_Send(uint8_t data)
{
uint8_t i;
Delay1_us(1); // 1us
for (i = 0; i < 8; i++)
{
if (data & 0x80)
{
GPIO_WriteHigh(MOSI_PIN);
}
else
{
GPIO_WriteLow(MOSI_PIN);
}
GPIO_Toggle(SCLK_PIN); // 切换SCLK
data <<= 1;
}
}
uint8_t SPI_Receive()
{
uint8_t data = 0;
uint8_t i;
for (i = 0; i < 8; i++)
{
data <<= 1;
if (gpio_read(MISO_PIN))
{
data |= 0x01;
}
GPIO_Toggle(SCLK_PIN); // 切换SCLK
}
return data;
}
void spi2_cs(u8 value)
{
if (value)
{
gpio_direction_output(CS_PIN, 1);
}
else
{
gpio_direction_output(CS_PIN, 0);
}
}
// SPI发送单字节函数(需根据硬件实现)
void my_spi_send_byte(uint8_t data)
{
SPI_Send(data);
}
// SPI接收单字节函数(需根据硬件实现)
uint8_t my_spi_receive_byte(void)
{
return SPI_Receive();
}
// 发送WREG指令写入寄存器
void write_register(uint8_t reg_addr, uint8_t data)
{
// WREG指令格式:0101 rrrr (r为寄存器地址低4位)
uint8_t command = 0x50 | (reg_addr & 0x0F);
my_spi_send_byte(command); // 发送指令
delay_2ms(1);
my_spi_send_byte(0x00); // 写入1个寄存器(n=0)
delay_2ms(1);
my_spi_send_byte(data); // 发送数据
delay_2ms(1);
}
// 初始化CS1242
void cs1242_init(u8 channel)
{
uint8_t data[15];
GPIO_WriteLow(CS_PIN); // 拉低CS
my_spi_send_byte(0xFE); // RESET指令码0xFE
delay_2ms(1); // 等待复位完成
// 写入寄存器 0x00 发送三个指令
my_spi_send_byte(WRITE_COMMAND);
my_spi_send_byte(0x02);
// 0x00 pga =1
my_spi_send_byte(PGA_1);
// 0通道:正:ADIN0 负:ADIN1
// 1通道:正:ADIN2 负:ADIN3
my_spi_send_byte(channel);
// 单极性
my_spi_send_byte(UNIPOLARITY);
GPIO_WriteHigh(CS_PIN); // 拉高CS
}
// 读取ADC数据(24位)
int32_t cs1242_read_data(void)
{
uint8_t data[3] = {0};
int32_t result = 0;
// 读取3字节数据(MSB在前)
data[0] = my_spi_receive_byte();
data[1] = my_spi_receive_byte();
data[2] = my_spi_receive_byte();
// 组合为24位有符号整数
result = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8) | data[2];
return result;
}
// 读取24位ADC数据(单次模式)
void cs1242_read_single_data(void)
{
u32 ad_data = 0, voltage_value = 0;
double voltage_value_double = 0;
float voltage_temp = 0;
static u8 channel = 0;
channel = !channel;
if (channel == 0)
{
GPIO_WriteLow(CS_PIN);
// 2. 发送RDATA指令
my_spi_send_byte(READ_SINGLE);
while (SPI_READ_DRDY());
// 3. 接收3字节数据(MSB在前)
ad_data = cs1242_read_data();
// 4. 拉高CS引脚
GPIO_WriteHigh(CS_PIN);
// 4. 处理接收到的数据
voltage_value_double = ad_data * 1100.0 / 0xffffff; // 0xffffff=2^24-1=16777215
hi_para.voltage1 = (u16)(voltage_value_double*(11+0.2));
printf("通道1电压值:%d mV\n", hi_para.voltage1);
if(hi_para.voltage1<50) // 电压小于50mV 电流小于500A
{
voltage_temp = hi_para.voltage1; //赋值给浮点数方便计算
hi_para.current = voltage_temp / 50.0 * 500.0; //计算出电流
printf("通道1电流值:%d A\n", hi_para.current);
}
else
{
hi_para.current = 1;
}
cs1242_init(CHANNEL_2);
}
else
{
GPIO_WriteLow(CS_PIN);
// 2. 发送RDATA指令
my_spi_send_byte(READ_SINGLE);
while (SPI_READ_DRDY())
;
// 3. 接收3字节数据(MSB在前)
ad_data = cs1242_read_data();
// 4. 处理接收到的数据
voltage_value_double = ad_data * 3300.0 / 0xffffff; // 0xffffff=2^24-1=16777215
hi_para.voltage2 = (u16)(voltage_value_double * (101 + 0.95));
printf("通道2电压值:%d mV\n", hi_para.voltage2);
// 4. 拉高CS引脚
GPIO_WriteHigh(CS_PIN);
cs1242_init(CHANNEL_1);
}
}
u16 get_current_data(void)
{
return hi_para.current;
}
u16 get_voltage_data(void)
{
return hi_para.voltage2;
}
void cs1242_main()
{
puts(">>> spi main start\n");
// 初始化SPI引脚
SPI_Init();
// io_ext_interrupt_test();
cs1242_init(CHANNEL_2);
printf("cs1242 init ok\n");
sys_timer_add(NULL, cs1242_read_single_data, 500);
}
#endif
cs1242.h
#ifndef _CS_1242_H_
#define _CS_1242_H_
#define READ_CONTINUE 0x03
#define READ_SINGLE 0x01
#define HIGH 1
#define LOW 0
#define MOSI_PIN IO_PORTB_08
#define MISO_PIN IO_PORTB_10
#define SCLK_PIN IO_PORTB_09
#define CS_PIN IO_PORTB_05
#define DRDY_PIN IO_PORTA_09
#define WRITE_COMMAND 0x50
#define THREE_COMMAND 0x02
#define PGA_1 0x00 //pga =1
#define CHANNEL_1 0x01 //正:ADIN0 负:ADIN1
#define CHANNEL_2 0x23 //正:ADIN2 负:ADIN3
#define UNIPOLARITY 0x40 //单极性
typedef struct
{
u16 voltage1; // 电压值1
u16 voltage2; // 电压值2
u16 direction; // 方向
u16 current; // 电流
u16 power; // 功率
u32 electric_num_timer; //充放电计时器
} hi_t;
extern hi_t hi_para;
#define SPI_READ_DRDY() (JL_PORTA->IN & BIT(9))
#define SPI2_READ_MISO() (JL_PORTB->IN & BIT(10))
void cs1242_main();
u16 get_current_data(void);
u16 get_voltage_data(void);
#endif