qqliufeng 发表于 2012-1-5 16:00:06

AVR单片机SPI多机通信ATmega16+ATmega8 ICC编译

最近研究了一下AVR的SPI通信。因为自己是新手,在我找资料学习的时候碰到了不少障碍,网上找的好多例程通过仿真都或多或少都有些毛病,再此希望给那些和我一样正在学习SPI通信的朋友们一些帮助。实验很简单就是通过读取本机I/O状态通过SPI发送到对方用LED显示。Proteus仿真在附件里。是段全双工SPI通信。
注释不是很多希望大家参考芯片手册了学习。

主机:
#include<iom16v.h>
#include<macros.h>
#include<AVRdef.h>
#define uint unsigned int
#define uchar unsigned char

void spi_init(void);
uchar spi_transmit(uchar sData);


/**********************************************/
void spi_init(void) //spi初始化
{   
   PORTB=0XF0; //SCK MISO MOSI SS 使能上拉      
   DDRB=BIT(5)|BIT(7)|BIT(4);
   SPCR=BIT(SPE)|BIT(MSTR)|BIT(SPR0);
}

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

/****************************************************/
uchar spi_transmit(uchar sData)//功能:使用SPI发送一个字节
{
   uchar tep;
   PORTB&=~BIT(4)//这个很重要,当初就是没仔细领悟芯片手册关于ss的解释导致我浪费了好多时间。
   SPDR = sData;
   while(!(SPSR & BIT(SPIF)));
   PORTB|=BIT(4);
   tep=SPDR;//读从机发回来的数据
   return tep;
   
}

/*************************************************/
void main(void)
{       
       uchar led;
       DDRC=0X00;
       PORTC=0X00;
       DDRA=0XFF;
       PORTA=0X00;
       
       
       spi_init();
       while(1)
       {
       led = spi_transmit(PINC);
       
       PORTA=led;
        }       

}

从机:
#include<iom16v.h>
#include<macros.h>
#include<AVRdef.h>
#define uint unsigned int
#define uchar unsigned char
#pragma interrupt_handler SIG_SPI:11//从机的中断,用于发送结束。
uchar temp=0x01;

void spi_init(void);

/**************************
函数名称:delay_ms
作用:毫秒延时函数
***************************/
void delay_ms(xms)
{       
       uchar i,j;
       for(i=xms;i>0;i--)
             for(j=1141;j>0;j--);
}

/***********************************************/
void spi_init(void) //spi初始化
{
   DDRB=BIT(6);
   PORTB=0XF0;
   SPCR = BIT(SPE)|BIT(SPIE);
   SEI();
}
/*************************************************/
void SIG_SPI(void) //一个字节发送或接收完成中断
{
   temp=SPDR;
}

/***************************************************/
void main(void)
{       
       DDRC=0X00;
       PORTC=0X00;
       DDRA=0XFF;
       PORTA=0X00;

       spi_init();
       
   
       while(1)
       {               
               SPDR=PINC;
               PORTA=        temp;
       }
}

ATmega8的例程我打包放附件里了。和16差不多就是SPI的接口不同,当时就是没仔细看芯片手册闹了不少笑话。仿真终究不是真的,现实中遇到的有些问题是仿真不出来的!




仿真 程序在里面ourdev_710554L4OCLA.zip(文件大小:153K) (原文件名:AVR单片机SPI通信带proteus仿真ICC编译.zip)

guoxiong1987 发表于 2012-2-9 10:39:01

你好,刚开始接触spi这一块,有点疑惑想问一下,JTAG ICE MKII仿真器是否能仿真主机与从机的通信

wuchonghjp 发表于 2013-7-8 20:27:25

呵呵,好贴没人顶啊、、、、、、、、、、、
页: [1]
查看完整版本: AVR单片机SPI多机通信ATmega16+ATmega8 ICC编译