我尝试在 PIC24F 系列的帮助下对 LMP90100进行编程。 我使用 SPI 作为通信类型。 但是、LMP90100的示例已经在 MSP430上编写、这一点我有问题。 在图中的哪里可以找到 LMP90100 SPI 库。
我可以使用 LMP90100 e SPI 写入数据、但读取 ADC 值并使其合理。
一般而言、拥有信息或资源的任何人都可以与我共享吗?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好、Brayn、
void LMP90100_Write(uint8_t addr, uint8_t value, uint8_t* pURA) { uint8_t new_URA, inst; new_URA = (addr & 0x70) >> 4; SS2OUT_SetLow(); if (*pURA != new_URA) { inst = 0x10; SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; } inst = 0x00 | 0x00 | (addr & 0x0F); SPI2_Exchange8bit(inst); SPI2_Exchange8bit(value); SS2OUT_SetHigh(); } void LMP90100_Read(uint8_t addr, uint8_t* pURA) { uint8_t x, new_URA, inst; new_URA = (addr & 0x70); SS2OUT_SetLow(); if (*pURA != new_URA) { inst = 0x10; SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; } inst = 0x80 | 0x00 | (addr & 0x0F); SPI2_Exchange8bit(inst); x = SPI2_Exchange8bit(0); SS2OUT_SetHigh(); return x; }
我创建的代码如上所示。 但我不确定这些代码。 我尝试使用这些代码尝试示例代码中的第一个示例、但写入到注册地址的值和读取的值不匹配。 当我在示波器的帮助下查看 SPI 通道时、我可以看到信号活动。
如果您能提供帮助、我很高兴。
提前感谢
您好、ASSA、
您是否已将其他 SPI 信号正确设置到 ADC、例如 SCLK、CS 等?
您是否遵循了数据表中 SPI 命令的正确时序?
有关如何设置 SPI 接口和正确时序的详细信息、请参阅数据表。
您能否发送系统原理图、以便我们了解输入和电源是如何连接的?
您还可以沿着示波器快照进行传递、以便我们可以看到您向 ADC 发送的命令以及 ADC 的响应方式。 但如果没有其他所要求的信息、示波器截图就不会有价值。
布莱恩
您好、ASSA、
您能帮助解释一下您在这里提供的信息吗? 示波器照片没有标记、因此不清楚您显示的内容。
此外、示波器快照显示了相当多的电压弹跳。 如果这些是通信线路、则信号线路上似乎存在相当多的噪声。 您可能会考虑改进布局或以其他方式确保这些敏感信号上的噪声不会进入系统。 您还应检查以确保所有数字和模拟信号都具有实心接地层或接地连接。
最后、您提供的原理图信息有限。 我看不到模拟输入、电源或其他任何相关器件是如何连接的。 您能否在下一次回复中包含更多详细信息?
布莱恩
您好、ASSA、
要从 LMP 器件中读回数据、您需要遵循数据表中显示的指南。 有一个快速入门部分可帮助您快速入门并运行(第10.1.1节)。 本快速入门指南中的步骤8指向图60所示的读取/写入协议、该协议从所需通道(在本例中为 CH0)捕获数据。
图60中显示的读/写协议详细说明了必须如何发送两个事务(URA 设置和数据访问)。 如果要读取数据、则 INST1 = 0x10、UA = 0x1、LRA = 0xA、大小= 3字节。 然后、生成的3x 字节数据将在 SDO 引脚上输出。 确保在此事务期间将 CSB 置为有效、然后在事务完成后将 CSB 置为无效。 有关使用 LMP 读取数据的示例、请参阅第9.5.14.2节。
布莱恩
根据您所说的内容、我的新代码示例已附加、但我 只能获取0作为 ADC 值。
您好、ASSA、
指令字节(INST1)应该一直为0x10、即使对于读取也是如此。 如图73所示。 INST2中的读取/写入位仍然取决于读取或写入、但 INST1始终为0x10。
我还将假定您正在将 SPI2_Exchange8bit()函数中的位进行适当组合,因为每个单独的事务似乎都是对该函数的单独调用。 例如、UAB 寄存器中的5个高位(全为零)作为该函数的一部分被调用、而市建局的低3位被单独调用。 我在下面的代码中突出显示了这一点
我也不确定为什么在写函数的后面调用"SPI2_Exchange8bit (0x01);"。 INST2字节的高四位应全部为零、我可以告诉您、因为每次写入一个字节(位4始终为0)。
最后、如果您想在一次调用中写入所有寄存器、而不必每次写入一个寄存器、则可以利用流功能。 第9.5.5节对此进行了说明。 和9.5.15.1。 但是、这两种方法都可以正常工作。
我建议首先尝试写入寄存器、然后重新读取它们、以确保 SPI 协议正常工作。 然后、我将继续尝试读取数据。
CS1_SetLow();
SPI2_Exchange8位(0x01);
SPI2_Exchange8bit (0x00);->这5个位应与 addr1组合、形成发送到 ADC 的单个字节
SPI2_Exchange8位(addr1);
SPI2_Exchange8位(0x00);
SPI2_Exchange8位(0x00);
SPI2_Exchange8bit (0x01);-->为什么这是0x01而不是0x00?
SPI2_Exchange8位(addr2);
SPI2_Exchange8位(data1);
SPI2_Exchange8位(data2);
CS1_SetHigh();
布莱恩
根据您的建议和示例代码、您的代码将被编辑、下面提供了电路图。 当我运行代码时、我得到0作为 ADC 值。
#include "mcc_generated_files/system.h" #include "mcc_generated_files/mcc.h" #include "mcc_generated_files/fatfs/fatfs_demo.h" #include "mcc_generated_files/TI_LMP90100.h" #include "mcc_generated_files/TI_LMP90100_register_settings.h" #define FCY 8000000UL #include <libpic30.h> static FATFS drive; static FIL file; void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA) { uint8_t new_URA, inst; new_URA = (addr & 0x70)>>4; // extract upper register address SS2OUT_SetLow(); //CS1_SetLow(); if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = 0x10; // Transaction-1 SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; // save new URA } inst = 0x00 | 0x00 |(addr & 0x0F); // lower register address SPI2_Exchange8bit(inst); SPI2_Exchange8bit(value); __delay_ms(1); //CS1_SetHigh(); SS2OUT_SetHigh(); } uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, uint8_t *pURA) { uint8_t x, new_URA, inst; new_URA = (addr & 0x70)>>4; // ı upper register address SS2OUT_SetLow(); //CS1_SetLow(); if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = 0x10; // Transaction-1 SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; // save new URA } inst = 0x80 | 0x00 | (addr & 0x0F); // Transaction-2 SPI2_Exchange8bit(inst); x=SPI2_Exchange8bit(0); //CS1_SetHigh(); SS2OUT_SetHigh(); return x; } void TI_LMP90100_SPINormalStreamReadADC(uint8_t addr, uint8_t *buffer,uint8_t count, uint8_t *pURA) { uint8_t i, new_URA, inst; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address SS2OUT_SetLow(); if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; // save new URA } inst = LMP90100_READ_BIT | LMP90100_SIZE_STREAM | (addr & LMP90100_LRA_MASK); // Transaction-2 SPI2_Exchange8bit(inst); for(i=0; i<count; i++) { *(buffer+i) = SPI2_Exchange8bit(0); } SS2OUT_SetHigh(); } void TI_LMP90100_WriteRegSettings(uint8_t *pURA) { TI_LMP90100_SPIWriteReg(TI_LMP90100_RESETCN_REG, TI_LMP90100_RESETCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_HANDSHAKECN_REG, TI_LMP90100_SPI_HANDSHAKECN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_STREAMCN_REG, TI_LMP90100_SPI_STREAMCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_PWRCN_REG, TI_LMP90100_PWRCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_RESTART_REG, TI_LMP90100_ADC_RESTART_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_GPIO_DIRCN_REG, TI_LMP90100_GPIO_DIRCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_GPIO_DAT_REG, TI_LMP90100_GPIO_DAT_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_BGCALCN_REG, TI_LMP90100_BGCALCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_DRDYBCN_REG, TI_LMP90100_SPI_DRDYBCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_AUXCN_REG, TI_LMP90100_ADC_AUXCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_CRC_CN_REG, TI_LMP90100_SPI_CRC_CN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SENDIAG_THLDH_REG, TI_LMP90100_SENDIAG_THLDH_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SENDIAG_THLDL_REG, TI_LMP90100_SENDIAG_THLDL_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_SCALCN_REG, TI_LMP90100_SCALCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_DONE_REG, TI_LMP90100_ADC_DONE_REG_VALUE, pURA); while (TI_LMP90100_SPIReadReg((TI_LMP90100_CH_STS_REG & TI_LMP90100_CH_SCAN_NRDY), pURA)); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH_SCAN_REG, TI_LMP90100_CH_SCAN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH0_INPUTCN_REG, TI_LMP90100_CH0_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH0_CONFIG_REG, TI_LMP90100_CH0_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH1_INPUTCN_REG, TI_LMP90100_CH1_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH1_CONFIG_REG, TI_LMP90100_CH1_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH2_INPUTCN_REG, TI_LMP90100_CH2_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH2_CONFIG_REG, TI_LMP90100_CH2_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH3_INPUTCN_REG, TI_LMP90100_CH3_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH3_CONFIG_REG, TI_LMP90100_CH3_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH4_INPUTCN_REG, TI_LMP90100_CH4_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH4_CONFIG_REG, TI_LMP90100_CH4_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH5_INPUTCN_REG, TI_LMP90100_CH5_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH5_CONFIG_REG, TI_LMP90100_CH5_CONFIG_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH6_INPUTCN_REG, TI_LMP90100_CH6_INPUTCN_REG_VALUE, pURA); TI_LMP90100_SPIWriteReg(TI_LMP90100_CH6_CONFIG_REG, TI_LMP90100_CH6_CONFIG_REG_VALUE, pURA); } int main(void) { SYSTEM_Initialize(); UINT actualLength; uint8_t prev_URA,count,addr,read_buf[3]; uint32_t adc_data; char data1[3]; char data[]="\r\n ADC:"; addr = TI_LMP90100_ADC_DOUT2_REG; // Start Reading from ADC_DOUT2 Register count = 3; // bytes to read: ADC_DOUT2 - ADCDOUT0 prev_URA = LMP90100_URA_END; // Initialize prev_URA to invalid segment TI_LMP90100_WriteRegSettings(&prev_URA); CS1_SetHigh(); IO_RE5_SetHigh(); __delay_ms(1000); IO_RE5_SetLow(); __delay_ms(1000); while (1) { TI_LMP90100_SPINormalStreamReadADC(addr, read_buf, count, &prev_URA); // read adc output into read_buf adc_data = ((uint32_t) read_buf[0] << 16) | ((uint16_t) read_buf[1] << 8) | read_buf[2]; // form raw adc output data sprintf(data1,"%X",adc_data); if( SD_SPI_IsMediaPresent() == false) { return 0; } if (f_mount(&drive,"0:",1) == FR_OK) { if (f_open(&file, "DEMO.TXT", FA_WRITE | FA_OPEN_APPEND ) == FR_OK) { f_write(&file, data, sizeof(data)-1, &actualLength ); f_write(&file, data1, sizeof(data1)-1, &actualLength ); f_close(&file); } f_mount(0,"0:",0); } IO_RE5_SetHigh(); __delay_ms(1000); IO_RE5_SetLow(); __delay_ms(1000); } }
您好、ASSA、
我曾要求您在尝试读取数据之前读回寄存器。 您是否执行了此操作? 如果是、发生了什么情况?
此外、看起来您在代码中进行了相当多的更改。 您是否逐行运行代码以使每个函数/变量的输出符合预期? 您还应使用示波器或逻辑分析仪进行检查、以确保在写入寄存器时、PIC 的输出是您希望的输出。 如果不是、则表示存在需要解决的代码错误。
遗憾的是、该电路图没有太大帮助、因为它基本上只是显示了原理图符号。 不清楚电源的供电方式、去耦电容值、输入滤波、数字连接等
我使用以下代码来写入和读取寄存器。
我在 SD 卡上读取的值如下所示。
#include "mcc_generated_files/system.h" #include "mcc_generated_files/mcc.h" #include "mcc_generated_files/fatfs/fatfs_demo.h" #define FCY 8000000UL #include <libpic30.h> static FATFS drive; static FIL file; void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA) { uint8_t new_URA, inst; new_URA = (addr & 0x70)>>4; // extract upper register address SS2OUT_SetLow(); if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = 0x10; // Transaction-1 SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; // save new URA } inst = 0x00 | 0x00 |(addr & 0x0F); // lower register address SPI2_Exchange8bit(inst); SPI2_Exchange8bit(value); __delay_ms(1); SS2OUT_SetHigh(); } uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, uint8_t *pURA) { uint8_t x, new_URA, inst; new_URA = (addr & 0x70)>>4; // ı upper register address SS2OUT_SetLow(); if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = 0x10; // Transaction-1 SPI2_Exchange8bit(inst); SPI2_Exchange8bit(new_URA); *pURA = new_URA; // save new URA } inst = 0x80 | 0x00 | (addr & 0x0F); // Transaction-2 SPI2_Exchange8bit(inst); x=SPI2_Exchange8bit(0); SS2OUT_SetHigh(); return x; } void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s)-1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } int main(void) { SYSTEM_Initialize(); UINT actualLength; uint8_t prev_URA; prev_URA = LMP90100_URA_END; // Initialize prev_URA to invalid segment TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_DRDYBCN_REG, 0x83, prev_URA); CS1_SetHigh(); IO_RE5_SetHigh(); __delay_ms(1000); IO_RE5_SetLow(); __delay_ms(1000); while (1) { uint8_t d=TI_LMP90100_SPIReadReg(TI_LMP90100_SPI_DRDYBCN_REG,prev_URA); char h[5]; itoa(d,h); char m[]="\r\nSPI_DRDYBCN:"; if( SD_SPI_IsMediaPresent() == false) { return 0; } if (f_mount(&drive,"0:",1) == FR_OK) { if (f_open(&file, "Demo3.TXT", FA_WRITE | FA_OPEN_APPEND ) == FR_OK) { f_write(&file, m, sizeof(m)-1, &actualLength ); f_write(&file, h, sizeof(h)-1, &actualLength ); f_close(&file); } f_mount(0,"0:",0); } IO_RE5_SetHigh(); __delay_ms(1000); IO_RE5_SetLow(); __delay_ms(1000); } }
SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0 SPI_DRDYBCN:0
您好、ASSA、
您是否单步执行代码以确保其按预期运行? 根据数据表、您是否要生成正确的字节来读取和写入寄存器?
您是否已使用示波器或逻辑分析仪验证时序是否准确?
您是否验证了 ADC 输入引脚上的电压是否有效、是否在规格范围内、并且在 ADC 运行时不会下降?
您是否验证了 PIC 配置是否正确(根据需要选择 GPIO、如果有多个 SPI 外设、则选择正确的 SPI 外设等)?
在您检查所有这些潜在问题之前、我无法为您提供进一步的帮助。 此时、未知因素太多、我需要您帮助验证这些未知因素、然后再继续提供支持。 请仔细阅读 LMP90100数据表、并确保您的系统符合本文档中概述的规格和要求。
请告诉我您在完成/验证所有这些任务后发现的内容。
布莱恩
您好、Brayn、
1 -参考数据表和示例代码创建了正确的代码。
2 -当时钟信号被触发时、数据从 MISO 和 MOSI 进行交换。
3 -目前、我只是尝试将数据读取并写入寄存器值。 这就是我尚未查看 ADC 引脚的原因。 进入 LMP90100的功率值提供了必要的条件。
4- PIC 的所有配置都是正确的,我确信 PIC 工作正常。 由于 SD 卡执行 SPI 通信、LED 闪烁应用和 OLED 显示应用。 此外、我将 PIC 的另一个 SPI 模块用于 SD 卡。