嘿 趁在回去吃饭前 总结一下基于AVR的SPI 功能实现 就先简单说一下SPI是什么吧 它是一个串行外部接口 允许AVR 与外部接口进行高速的同步数据传输 现在为了配合实现SPI功能 让它接上移位寄存器747HC595  这样通过595直接驱动4位7段共阴数码管显示 
        具体的接口安排如下 MOSI接595的串口数据输入端D 即14脚  SCK接595的时钟信号端CLK 即11脚  PB4接595的数据控制端 即12脚  
         代码实现如下:
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint  unsigned int
 
uchar  diap[ ] = { 0xC0, 0xF9, 0xA4,0xb0,0x99,0x82,0xF8,0x80,0x90} ;
 
//延时子函数
void DelayMs ( uchar  i)
{
    uchar j ;
    while ( i--) ;
     {
          j=167;      //1MHZ 1ms延时
          while ( j--)  ;
      }
}
//SPI初始化为主机
/*SPI控制寄存器
 SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
  SPIE  中断使能  SPE SPI使能 DORD 数据次序 1为LSB首先发送,0为MSB首先发送
  MSTR  主从选择 1为主,0为从MSTR置位时选择主机模式,否则为从机.如果MSTR为"1",
   SS配置为输入,但被拉低,则MSTR 被清零,寄存器SPSR 的SPIF 置位.用户必须重新设置   
 MSTR 进入主机模式。
 CPOL: 时钟极性见ATMEGA16L(中文)P130
 CPHA: 时钟相位
  SPR1, SPR0: SPI 时钟速率选择1 与0  SPR1 和SPR0 对从机没有影响。
   使能SPI 主机模式,设置时钟速率为fck/128 */
void SPIMasterInit ( void )
{
     DDRB |= (1<<PB5) | (1<<PB7);
     SPCR  = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);  
}
 
//SPI数据发送
void  SPIMasterTransmit ( uchar TranData)
{
   SPDR = TranData ;                                 //启动数据传输
   while ( !( SPSR & ( 1<< SPIF ) ) ) ;       //   等待数据传输结束
}
 
//595的输出显示
void SPI595out ( uchar i )
{
     PORTB  &= ~ ( 1<<4 ) ;                      //准备锁存数据
     SPIMasterTranmit ( i ) ;
     PORTB   |= ( 1<< 4 )  ;                        /*锁存数据*/ 即是把595中移位寄存器中的数放到数据寄存器中*/
}
 
//主函数
void main ( void )
{
     uchar i  ;
     DDRB = 0xFF;      /*方向输出*/
     PORTB = 0xF0;      /*电平设置*/
     SPImasterInit ( )  ;
     while  ( 1 )
     {
          i++ ;
          if ( i > 9)  i =0    ;
          DelayMs ( 250 ) ;
          DelayMs ( 250 )  ;
          SPI595out ( diap[ i ])  ;
      } 
 
}