GCCAVR-based SPI simulation program

Publisher:MysticalGardenLatest update time:2017-01-05 Source: eefocusKeywords:GCCAVR Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

AVR has only one SPI interface. If you want to drive more peripherals with SPI interface, you must simulate them through IO. In fact, IO simulation is also very convenient for low-speed peripherals. There are many programs for simulating SPI on the Internet. My program is written based on GCCAVR. Other compilers are similar. When writing, I try to be standardized and convenient for modification and adjustment in later use.

 

The following points should be noted when using:

1. According to the timing requirements of the peripherals, distinguish whether to update data on the rising edge or the falling edge.

2. When sending data, should the high bit come first or the low bit come first?

3. Whether the peripheral has speed requirements for SPI communication. Sometimes, too fast a communication rate may not be able to read and write data.

4. Normal level of CLK, data and other pins

The above points can be understood at a glance by comparing them with the timing diagram of the peripherals. The program is clearly written and you can just make the corresponding changes.

The procedure is as follows:

/******************************(C) COPYRIGHT emouse 2011********************** **********

Name: main.c

Function: Simulate SPI program test

Author:emouse

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

#include "avr/io.h"

#include "avr/interrupt.h"

#include "util/delay.h"

  

#define SetBit(Port,N) (Port|=(1<

#define ClrBit(Port,N) (Port&=~(1<

#define ReverBit(Port,N) (Port^=(1<

#define GetBit(Pin,N) ((Pin>>N)&0x01) //Read a certain bit of IO

/***************Related macro definitions for simulating SPI************************/

#define SPI1_Port PORTC //Set the port used

#define SPI1_DDR DDRC

#define SPI1_PIN PINC

#define SPI1_CS 0 //Set the pin corresponding to each signal

#define SPI1_MISO 1

#define SPI1_MOSI 2

#define SPI1_CLK 3

#define SPI1_CS_H (SPI1_Port|=(1<

#define SPI1_CS_L (SPI1_Port&=~(1<

#define SPI1_GetMISO ((SPI1_PIN>>SPI1_MISO)&0x01)

#define SPI1_MOSI_H (SPI1_Port|=(1<

#define SPI1_MOSI_L (SPI1_Port&=~(1<

#define SPI1_CLK_H (SPI1_Port|=(1<

#define SPI1_CLK_L (SPI1_Port&=~(1<

unsigned char spi_delay; //Set the duration of the signal, which is equivalent to setting the speed of SPI

/****************************************************** ****************************

Name: void SPI1_Init()

Function: Simulate SPI timing port initialization

Parameters: None

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

void SPI1_Init()

{

    SPI1_Port|=((1<

    SPI1_DDR|=(((1<

    SPI1_CS_H;

    SPI1_CLK_L;

    spi_delay=5;

}

/****************************************************** ****************************

Name: SPI1_Send(unsigned char data)

Function: Send SPI data

Parameter: unsigned char data

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

void SPI1_Send(unsigned char data)

{

    unsigned char i;

    SPI1_CS_L; //Pull the chip select signal low

    SPI1_CLK_L; //The clock is low when idle

    SPI1_MOSI_L;

    _delay_us(spi_delay);

    for(i=0;i<8;i++)

    {

        if(data&(0x80>>i))//high bit first, low bit first change to (0x01<

            SPI1_MOSI_H;

        else

            SPI1_MOSI_L;

        _delay_us(spi_delay);

        SPI1_CLK_H; //Update data on the rising edge

        _delay_us(spi_delay);

        SPI1_CLK_L;

    }

    _delay_us(spi_delay);

    SPI1_CS_H; //Pull up the chip select to complete a data transmission

}

/****************************************************** ****************************

Name: unsigned char SPI1_Get()

Function: Receive SPI data

Parameter: return data

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

unsigned char SPI1_Get()

{

    unsigned char i;

    unsigned char data=0x00;

    SPI1_CS_L; //Pull the chip select signal low

    SPI1_CLK_L; //The clock is low when idle

    SPI1_MOSI_L;

    _delay_us(spi_delay);

    for(i=0;i<8;i++)

    {

        if(SPI1_GetMISO)

            data|=(0x80>>i);

        _delay_us(spi_delay);

        SPI1_CLK_H; //Update data on the rising edge

        _delay_us(spi_delay);

        SPI1_CLK_L;

    }

    _delay_us(spi_delay);

    SPI1_CS_H; //Pull up the chip select to complete a data transmission

    return data;

}

/****************************************************** ****************************

Name: void USART0_Init(void)

Function: Initialize serial port 0

Parameters: None

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

void USART0_Init(void)

{

UCSR0A=0x20; //Baud rate is not doubled, single machine communication mode

UCSR0B=0x18; //Interrupt disabled, sending and receiving allowed

UCSR0C = 0x06; //Asynchronous mode, no check, 8-bit data, 1 stop bit

UBRR0H=0x00;

UBRR0L=51; //9600 baud rate, crystal oscillator 8M

}

/****************************************************** ****************************

Name: void USART0_Putc(unsigned char c)

Function: Send a character

Parameter: unsigned char c

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

void USART0_Putc(unsigned char c)

{

    while(!(UCSR0A&(1<

    UDR0=c; //Send data

}

/****************************************************** ****************************

Name: void USART0_Puts(unsigned char * str)

Function: Send string

Parameter: unsigned char * str string to be sent

Date: 2011.1.11

Version: 1.0

Note: None

*************************************************** *******************************/

void USART0_Puts(unsigned char * str)

{

    while(*str)

    {

        USART0_Putc(*str++);

    }

}

int main(void)

{   

    unsigned char i=0;

    USART0_Init(); //Initialize USART0 interface  

    DDRA=0XFF;

    PORTA=0XFF;

    SPI1_Init();

    USART0_Puts("SPI test");

    while(1)

    {     

        SPI1_Send(0x04);

        USART0_Putc(SPI1_Get());

        ReverBit(PORTA,0);

        _delay_ms(500);        

    }

}


Keywords:GCCAVR Reference address:GCCAVR-based SPI simulation program

Previous article:CPLD and AVR communication PWM control program
Next article:AVR Assembly Program Part 1: The Internal Structure of the AVR MCU's CPU

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号