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_ENABLEhi_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); // 1usfor (i = 0; i < 8; i++){if (data & 0x80){GPIO_WriteHigh(MOSI_PIN);}else{GPIO_WriteLow(MOSI_PIN);}GPIO_Toggle(SCLK_PIN); // 切换SCLKdata <<= 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); // 拉低CSmy_spi_send_byte(0xFE); // RESET指令码0xFEdelay_2ms(1); // 等待复位完成// 写入寄存器 0x00 发送三个指令my_spi_send_byte(WRITE_COMMAND);my_spi_send_byte(0x02);// 0x00 pga =1my_spi_send_byte(PGA_1);// 0通道:正:ADIN0 负:ADIN1// 1通道:正:ADIN2 负:ADIN3my_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=16777215hi_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=16777215hi_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; // 电压值1u16 voltage2; // 电压值2u16 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