Recently, I want to control the ADS1299 with STM32, but the spi communication is not correct. I followed the diagram"Figure 56. Initial Flow at Power-Up" in the ADS1299 datasheet, but I don't know what's the problem with my code?
#include "stm32f10x.h" #include "stm32f10x_usart.h" #include "misc.h" #include "stdarg.h" #include "spi_ads1299.h" #include "main.h" #include "exti.h" extern void SPI_ADS1299_Init(void); /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void USART_Config(USART_TypeDef* USARTx); void EXTI_PA0_Config(void); u8 SPI_ReadByte(void); u8 SPI_SendByte(u8 byte); char *itoa(int value, char *string, int radix); void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...); void delay(uint32_t i); /* global variable declaration */ uint16_t adc_temp; uint8_t spi_buffer[27]; uint8_t i; uint8_t signal = 0; //EXTI0中断标志 int main(void) { RCC_Configuration(); //设置系统时钟 GPIO_Configuration(); //IO口设置 USART_Config(USART1); //串口1初始化 EXTI_PA0_Config(); //exti 中断设置 SPI_ADS1299_Init(); //SPI1 初始化 //Set RESET = 1, Wait for 1s for Power-On Reset CS_HIGH; RESET_HIGH; delay(30); USART_OUT(USART1,"* STEP 1 :\r\n"); //Issue Reset Pulse RESET_LOW; delay(0xf); RESET_HIGH; delay(0x30); //Send SDATAC Command: stop read data continuously mode spi_buffer[0] = 0x11; CS_LOW; SPI_SendByte(spi_buffer[0]); delay(0x02); CS_HIGH; // //STOP // spi_buffer[0] = 0x0A; // CS_LOW; // SPI_SendByte(spi_buffer[0]); // delay(0x02); // CS_HIGH; // //If Using Internal Reference, Send Command-WREG CONFIG3 E0h spi_buffer[0] = 0x43; //write 1 register starting at address 03H(CONFIG3) spi_buffer[1] = 0x00; spi_buffer[2] = 0xE0; CS_LOW; for(i=0;i<3;i++) { SPI_SendByte(spi_buffer[i]); delay(0x02); } CS_HIGH; //Set Device for DR = fMOD/4096, WREG CONFIG1 96H spi_buffer[0] = 0x41; //write 1 register starting at address 01H(CONFIG1) spi_buffer[1] = 0x00; spi_buffer[2] = 0x96; CS_LOW; for(i=0;i<3;i++) SPI_SendByte(spi_buffer[i]); delay(0x02); CS_HIGH; //Set Device for DR = fMOD/4096, WREG CONFIG2 C0H spi_buffer[0] = 0x42; //write 1 register starting at address 02H(CONFIG2) spi_buffer[1] = 0x00; spi_buffer[2] = 0xC0; CS_LOW; for(i=0;i<3;i++) SPI_SendByte(spi_buffer[i]); delay(0x02); CS_HIGH; //Activate Conversion: Set START = 1; // //config test signal // spi_buffer[0] = 0x22; //read 1 register starting at address 02H(CONFIG2) // spi_buffer[1] = 0x00; // // spi_buffer[2] = 0xC0; // CS_LOW; // CS low // for (i=0;i<2;i++) // ReadWriteByte(spi_buffer[i]); // spi_buffer[0]=ReadWriteByte(0x00); // Delay_ms(1); // CS_HIGH; // CS high // // spi_buffer[2] = 0x14 | spi_buffer[0]; // spi_buffer[1] = 0x00; // spi_buffer[0] = 0x42; // CS_LOW; // CS low // for (i=0;i<3;i++) // ReadWriteByte(spi_buffer[i]); // Delay_ms(5); // CS_HIGH; // CS high // // // CONFIG CH1 for test signal // spi_buffer[0] = 0x25; // spi_buffer[1] = 0x00; // spi_buffer[2] = 0x00; // CS_LOW; // CS low // for (i=0;i<2;i++) // ReadWriteByte(spi_buffer[i]); // spi_buffer[0]=ReadWriteByte(0x00); // Delay_ms(5); // CS_HIGH; // CS high // // spi_buffer[2] = 0x5 | spi_buffer[0]; // spi_buffer[1] = 0x00; // spi_buffer[0] = 0x45; // CS_LOW; // CS low // for (i=0;i<3;i++) // ReadWriteByte(spi_buffer[i]); // Delay_ms(5); // CS_HIGH; // CS high // START / spi_buffer[0] = 0x08; CS_LOW; // CS low SPI_SendByte(spi_buffer[0]); delay(0x0f); CS_HIGH; // CS high // RDATAC /Enable Read Data Continuous mode spi_buffer[0] = 0x10; CS_LOW; // CS low SPI_SendByte(spi_buffer[0]); delay(0x0f); CS_HIGH; // CS high NVIC_EnableIRQ(EXTI0_IRQn); while(1) { if(signal == 1) { for(i=0;i<27;i++) { USART_OUT(USART1,"spi_buffer[%d] = %d",i,spi_buffer[i]); USART_OUT(USART1," "); } USART_OUT(USART1,"\r\n"); } } } /* *简单软件延时函数ms */ void delay(uint32_t i) { uint32_t j; for (j=0; j!=i*1000; j++) ; } /**************************************************************************** * 名 称:void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...) * 功 能:格式化串口输出函数 * 入口参数:USARTx: 指定串口 Data: 发送数组 ...: 不定参数 * 出口参数:无 * 说 明:格式化串口输出函数 "\r" 回车符 USART_OUT(USART1, "abcdefg\r") "\n" 换行符 USART_OUT(USART1, "abcdefg\r\n") "%s" 字符串 USART_OUT(USART1, "字符串是:%s","abcdefg") "%d" 十进制 USART_OUT(USART1, "a=%d",10) * 调用方法:无 ****************************************************************************/ void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){ const char *s; int d; char buf[16]; va_list ap; va_start(ap, Data); while(*Data!=0){ //判断是否到达字符串结束符 if(*Data==0x5c){ //'\' switch (*++Data){ case 'r': //回车符 USART_SendData(USARTx, 0x0d); Data++; break; case 'n': //换行符 USART_SendData(USARTx, 0x0a); Data++; break; default: Data++; break; } } else if(*Data=='%'){ // switch (*++Data){ case 's': //字符串 s = va_arg(ap, const char *); for ( ; *s; s++) { USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } Data++; break; case 'd': //十进制 d = va_arg(ap, int); itoa(d, buf, 10); for (s = buf; *s; s++) { USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } Data++; break; default: Data++; break; } } else USART_SendData(USARTx, *Data++); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } } /****************************************************** 整形数据转字符串函数 char *itoa(int value, char *string, int radix) radix=10 标示是10进制 非十进制,转换结果为0; 例:d=-379; 执行 itoa(d, buf, 10); 后 buf="-379" **********************************************************/ char *itoa(int value, char *string, int radix) { int i, d; int flag = 0; char *ptr = string; /* This implementation only works for decimal numbers. */ if (radix != 10) { *ptr = 0; return string; } if (!value) { *ptr++ = 0x30; *ptr = 0; return string; } /* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-'; /* Make the value positive. */ value *= -1; } for (i = 10000; i > 0; i /= 10) { d = value / i; if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } } /* Null terminate the string. */ *ptr = 0; return string; } /* NCL_Itoa */ /**************************************************************************** * 名 称:USART_Config(USART_TypeDef* USARTx) * 功 能:配置串口 * 入口参数: * 出口参数:无 * 说 明: * 调用方法:例如: USART_Config(USART1) ****************************************************************************/ void USART_Config(USART_TypeDef* USARTx){ USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; //速率115200bps USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位 USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 /* Configure USART1 */ USART_Init(USARTx, &USART_InitStructure); //配置串口参数函数 // /* Enable USART1 Receive and Transmit interrupts */ // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能接收中断 // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //使能发送缓冲空中断 /* Enable the USART1 */ USART_Cmd(USART1, ENABLE); } /**************************************************************************** * 名 称:void RCC_Configuration(void) * 功 能:系统时钟配置为72MHZ, 外设时钟配置 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void RCC_Configuration(void){ SystemInit(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE); } /**************************************************************************** * 名 称:void GPIO_Configuration(void) * 功 能:通用IO口配置 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法: ****************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1 RESET GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式最大速度50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //状态LED1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式最大速度50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); } /******************* **********************************END OF FILE************/
Does anyone has experience to use STM32 to control the ADS1299?