Hi , i have tried to write some code for M25P80 SPI communication using c programing. i have defined GPIO pins and chip select pin SPI functions also. But i want to make sure what are the functions should i add? Can anybody help me to complete the code for M25P80? or if anybody has written already some code then please email me at pra20008dip@homtail.com thank you.
Complete the code?
You haven't shown any "incomplete code".
And I don't think your teacher wants us to hand over all the code you are expected to write yourself.
Per Westermark ....Here is my incomplete code...i have make transmit data and hold for 5 second then again transmit ...and for up to 3 KHz...
#include <stm32f4xx.h> #include <stm32f4xx_conf.h> uint8_t received_val; uint8_t i; //static int i; void delay(uint32_t a) { while (a--); } void init_GPIO(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //Select pin PA0 (User Button) to configure GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //Set pin to input GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //Set GPIO clock speed GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //Set pin type to push/pull GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; //Enable pulldown resistor to detect high level GPIO_Init(GPIOA, &GPIO_InitStruct); //Initialise GPIOA } void INTTIM_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* TIM2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 3000; // Up to 3 KHz (3 ms) TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); } // this function initializes the SPI1 peripheral void init_SPI1(void){ GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; //DMA_InitTypeDef DMA_InitStructure; // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI2 * PA5 = SCK * PA6 = MISO * PA7 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // connect SPI1 pins to SPI alternate function GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); /* Configure the chip select pin in this case we will use PE7 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOE, &GPIO_InitStruct); GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI2, &SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); // enable SPI2 } /*void mySPI_SendData(uint8_t adress, uint8_t data){ GPIO_ResetBits(GPIOE, GPIO_Pin_7); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, adress); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_I2S_ReceiveData(SPI1); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, data); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_I2S_ReceiveData(SPI1); GPIO_SetBits(GPIOE, GPIO_Pin_7); }*/ /*void my_SPI_Cmd(uint8_t *A, uint8_t length, uint8_t *B) { uint8_t local_count = 0; GPIO_SetBits(GPIOE, GPIO_Pin_7); // disable SPI device GPIO_ResetBits(GPIOE, GPIO_Pin_7); // enable SPI device while (local_count < length) { SPI_I2S_SendData(SPI1, *(A + local_count)); while (SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); // wait until TX done while (SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); // wait until RX done *(B + local_count) = SPI_I2S_ReceiveData(SPI1); local_count++; } while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // wait until BSY = 0 GPIO_SetBits(GPIOE, GPIO_Pin_7); // disable SPI device }*/ uint8_t SPI1_send(uint8_t data) { GPIO_ResetBits(GPIOE, GPIO_Pin_7); SPI1->DR = data; while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); while( SPI1->SR & SPI_I2S_FLAG_BSY ); GPIO_SetBits(GPIOE, GPIO_Pin_7); return SPI1->DR; } int main(void) { init_SPI1(); INTTIM_Config(); GPIOD->BSRRL = 0xF000; //Set PD12 through PD15 (BSRRL = Bit Set/Reset Register Low) delay(0xf42400); //Wait GPIOD->BSRRH = 0xF000; //Reset PD12 through PD15 (BSRRH = Bit Set/Reset Register High) //uint16_t received_val=0; while(1) { GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) low SPI1_send(i); // transmit data received_val = SPI1_send(0x00); // transmit dummy byte and receive data GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) high i++; delay(0x3D0900); //Add delay to debounce the switch } }
Hey, I have posted my code...could you please help me what else should i need to implement more..?
You enable a timer interrupt, but there is no service routine.
Your delay function may be optimized away. Figure out what purpose it has, ideally use a timer or systick based counter to mark actual time, rather than loop iterations.
Your main() loop sends non-sense to the Serial NOR Flash device.
Have you reviewed the manual/data-sheet for the M25P80?
If you send an READ ID Command, does it return the data you expect, along with the unique id?
You'd want to implement a command function. Use that to send READ STATUS REGISTER, READ DATA BYTES, SECTOR ERASE, WRITE ENABLE, WRITE DISABLE, PROGRAM PAGE, etc.
Thanks for your suggestion ... I did completed the program...it works nice....