Skip to content

Instantly share code, notes, and snippets.

@avr-programmierung
Created May 16, 2019 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avr-programmierung/0ccbb867c2eec1c310c4d3a26831aab5 to your computer and use it in GitHub Desktop.
Save avr-programmierung/0ccbb867c2eec1c310c4d3a26831aab5 to your computer and use it in GitHub Desktop.
ATmega88 @ 8MHz SPI-Kommunikation mit Flash-Speicher SST25VF016B
/* spi_flash_02.c
* SPI-Kommunikation mit Flash-Speicher SST25VF016B
* 1.) Statusregister lesen
* 2.) Ein Byte auf Adresse 000101 schreiben
* 3.) Ein Byte von Adresse 000101 lesen
* 4.) Kompletten Flashspeicher löschen
* Controller: ATmega88 @ 8MHz
*/
#include <avr/io.h>
#define WP (1<<PC5) // Write Protect disable @PC5
#define HOLD (1<<PC4) // Stop serial communication disable @PC4
#define CE (1<<PB2) // Chip Enable @PB2
#define MOSI (1<<PB3) // Master Out Slave In @PB3
#define MISO (1<<PB4) // Master In Slave Out @PB4
#define SCK (1<<PB5) // Clock @PB5
uint8_t data, status_register=0;
void SPI_MasterInit(void) /* Initiate the SPI-Master */
{
DDRB = MOSI|SCK|CE; // Set MOSI, SCK, CE output
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1); // Enable SPI, Master, set clock rate fck/64
}
void SPI_MasterTransmit(uint8_t data) /* Transmit data on MOSI */
{
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
}
uint8_t SPI_SlaveReceive(void) /* Receive data from MISO */
{
while(!(SPSR & (1<<SPIF))); // Wait for reception complete
return SPDR; // Return SPI-Dataregister
}
uint8_t Read_Status_Register(void) /* Read STATUS REGISTER */
{
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x05); // Send command 0x05 (Read the status register)
SPI_MasterTransmit(0x00); // Send one dummy byte
status_register = SPI_SlaveReceive(); // Receive the value of the status register
PORTB |= CE; // CE = high (end of communication)
return status_register; // Return the value of the status register
}
void Enable_Write_Procedure(void) /* Activate write commands in correct sequence */
{
/* Enable write status register EWSR */
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x50); // Send command 0x50 (Enable write status register)
PORTB |= CE; // CE = high (end of communication)
/* Write status register WRSR */
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x01); // Send command 0x01 (Write status register)
SPI_MasterTransmit(0x02); // Send data 00000010 to clear BPx in status register and set WEL=1
PORTB |= CE; // CE = high (end of communication)
/* Write enable WREN */
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x06); // Send command 0x06 (Set write enable WREN)
PORTB |= CE; // CE = high (end of communication)
}
/* Program one data byte */
void Byte_Program(uint8_t addressbyte1, uint8_t addressbyte2, uint8_t addressbyte3, uint8_t databyte)
{
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x02); // Send command 0x02 (program one data byte)
SPI_MasterTransmit(addressbyte1); // Send 1. Addressbyte (MSB first)
SPI_MasterTransmit(addressbyte2); // Send 2. Addressbyte
SPI_MasterTransmit(addressbyte3); // Send 3. Addressbyte
SPI_MasterTransmit(databyte); // Send databyte
PORTB |= CE; // CE = high (end of communication)
}
/* Write disable WRDI */
void Write_Disable(void)
{
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x04); // WRDI (write disable) Send command 0x04
PORTB |= CE; // CE = high (end of communication)
}
/* Read memory */
uint8_t Read_Memory(uint8_t addressbyte1, uint8_t addressbyte2, uint8_t addressbyte3, uint8_t dummybyte)
{
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x03); // Send command 0x03 Read
SPI_MasterTransmit(addressbyte1); // Send 1. Addressbyte (MSB first)
SPI_MasterTransmit(addressbyte2); // Send 2. Addressbyte
SPI_MasterTransmit(addressbyte3); // Send 3. Addressbyte
SPI_MasterTransmit(dummybyte); // Send Dummybyte
data = SPI_SlaveReceive(); // Receive the value of data
PORTB |= CE; // CE = high (end of communication)
return data; // Return the value of data
}
void Chip_Erase(void) /* Chip erase - Erase full memory array */
{
PORTB &= ~CE; // CE = low (start communication)
SPI_MasterTransmit(0x60); // Chip erase (Send command 0x60)
PORTB |= CE; // CE = high (end of communication)
}
int main(void)
{
DDRC |= WP | HOLD; // Set WP, HOLD output
PORTC |= WP|HOLD; // Set WP, HOLD high
SPI_MasterInit(); // Init SPI Master
status_register = Read_Status_Register(); // Read STATUS REGISTER
status_register=0; // set the variable to 0
Enable_Write_Procedure(); // Enable a write process
Byte_Program(0x00, 0x01, 0x01, 0xA7); // Programm 1 databyte (A7) @ address 000101
Write_Disable(); // Write disable WRDI
data = Read_Memory(0x00, 0x01, 0x01, 0x00); // Read 1 databyte @ address 000101
data = 0;
Enable_Write_Procedure(); // Enable a write process
Chip_Erase(); // Chip erase - Erase full memory array
Write_Disable(); // Write disable WRDI
while(1)
{
asm("NOP");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment