专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AVR单片机与74HC595的SPI显示程序

作者:佚名   来源:本站原创   点击数:  更新时间:2012年04月08日   【字体:

使用SPI接口控制74HC595 LED显示

SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

  SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,为全双工通信,数据传输速度总体来说比I2C总线要快,速度可达到几Mbps。

  SPI接口是以主从方式工作的,这种模式通常有一个主器件和一个或多个从器件,其接口包括以下四种信号:

    (1)MOSI – 主器件数据输出,从器件数据输入
    (2)MISO – 主器件数据输入,从器件数据输出
    (3)SCLK – 时钟信号,由主器件产生
    (4)/SS – 从器件使能信号,由主器件控制

  在BASCOM中,提供了软件实现的SPI接口的语句,同样BASCOM也有支持硬件SPI的语句。
  下面将使用三个例子来说明如何在BASCOM中使用SPI接口。

  在介绍例子之前,我们先了解一下硬件连接图,连接如图1所示。

   图中共使用三片74HC595芯片,分别控制三个数码管,三片74HC595通过Q7’引脚进行级联。第一片74HC595的DS引脚连接到了ATmega88的MOSI引脚,而SH_CP引脚连接到了ATmega88的SCK引脚,ST_CP引脚连接到了ATmega88的PB1引脚。

           一、使用硬件SPI接口控制74HC595 
            '------------------------------------------------------------------------
            '使用芯片:  ATmega88,
            '晶振:      内部8MHz晶振
            'email:     support@avrbascom.com
            '软件版本:  Bascom-AVR 1.11.8.3 Full version
            '------------------------------------------------------------------------

                $regfile = "m88def.dat"                     '芯片为ATmega88 
                $crystal = 8000000                          '8M晶振频率 

                $hwstack = 32                               '设置堆栈大小 
                $swstack = 10
                $framesize = 40

                Dim I As Byte
                Dim A(3) As Byte

                Latch Alias Portb.1

                Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes ,
                Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
                                        '定义使用单片机自带的硬件SPI,SPI中断未使能,数据发送时,高位先发送。
                                        '设为SPI主设备,时钟4分频 
                Spiinit                 'SPI初始化
                Restore Segtab          '获取要显示数据的内容 
                    For I = 1 To 3
                          Read A(i)
                    Next I

                Spiout A(1) , 3         '输出要显示的内容给74HC595,分别输出A(1),A(2),A(3)

                Latch = 1?              '使能显示 
                Waitus 10
                Latch = 0 

                Do

                Loop

                End
          '*******************************************************************************
          '--------------------------专用字形表------------------------------------------
          Segtab:
               Data &H77 , &H14 , &HE6 , &HB6 , &H95 , &HB3 , &HF3 , &H16 , &HF7 , &HB7
               '0 1 2 3 4 5 6 7 8 9

 

       二、使用软件SPI接口控制74HC595
          '------------------------------------------------------------------------
          '使用芯片: ATmega88,
          '晶振:     内部8MHz晶振 
          'email:    support@avrbascom.com
          '软件版本: Bascom-AVR 1.11.8.3 Full version
          '------------------------------------------------------------------------ 


               $regfile = "m88def.dat"                  '芯片为ATmega88 
               $crystal = 8000000                       '8M晶振频率 

               $hwstack = 32                            '设置堆栈大小 
               $swstack = 10
               $framesize = 40


               Const On = 1
               Const Off = 0

               Dim I As Byte
               Dim A(3) As Byte

               Latch Alias Portb.1

               Config Spi = Soft , Dout = Portb.3 , Ss = None , Clock = Portb.5
                                                       '定义使用软件SPI,pb3作为数据输出口,pb5作为时钟引脚 

               Spiinit                 'SPI初始化
               Restore Segtab          '获取要显示数据的内容 
                   For I = 1 To 3
                         Read A(i)
                   Next I

               Spiout A(1) ,3
                                       '输出要显示的内容给74HC595,分别输出A(1),A(2),A(3)

               Latch = Off            '使能显示 
               Waitus 10
               Latch = On

               Do

               Loop

               End
         '********************************************************************
         '--------------------------专用字形表------------------------------------------
          Segtab:
               Data &H77 , &H14 , &HE6 , &HB6 , &H95 , &HB3 , &HF3 , &H16 , &HF7 , &HB7
               '0 1 2 3 4 5 6 7 8 9

 

       三、使用软件SPI接口控制74HC595
         '------------------------------------------------------------------------
         '使用芯片: ATmega88,
         '晶振:     内部8MHz晶振 
         'email:    support@avrbascom.com
         '软件版本: Bascom-AVR 1.11.8.3 Full version
         '------------------------------------------------------------------------ 

 

               $regfile = "m88def.dat"         '芯片为ATmega88 
               $crystal = 8000000              '8M晶振频率 

               $hwstack = 32                   '设置堆栈大小 
               $swstack = 10
               $framesize = 40

               Const On = 1
               Const Off = 0

               Ledata Alias Portb.3            '数据输出口 
               Ledclk Alias Portb.5            '时钟输出口 
               Latch Alias Portb.1

               Dim I As Byte
               Dim A(3) As Byte

 

 

               Restore Segtab                   '获取要显示数据的内容 
               For I = 1 To 3
                    Read A(i)
               Next I

 

               For I = 3 To 1 Step -1
                     Shiftout Ledata , Ledclk , A(i) , 1
                 '输出要显示的内容给74HC595
               Next I

               Latch = Off                      '使能显示 
               Waitus 10
               Latch = On

               Do

               Loop

               End
         '********************************************************************
         '--------------------------专用字形表------------------------------------------
         Segtab:
              Data &H77 , &H14 , &HE6 , &HB6 , &H95 , &HB3 , &HF3 , &H16 , &HF7 , &HB7
             '0 1 2 3 4 5 6 7 8 9

 

 

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

//            74HC595/165驱动程序

//            (165,595均为两片)

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

unsigned int LED;

unsigned int KEY_DATA;

void Driver_595(unsigned char Bit,unsigned char State)

{

    if(State)

       LED|=(0x00001<<Bit);

    else

       LED&=~(0x00001<<Bit);

    SPI_W_R((int)(LED>>8));

    set_bit(1,0);

    clr_bit(1,0);

    SPI_W_R((int)LED);

    set_bit(1,0);

    clr_bit(1,0);

}

void Port_Init(void)

{

    DDRB=0xff;

PORTB=0x00;

}

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

void Driver_165(void)            //Bite所取位0~15,State为改位的状态0,1

{ 

    unsigned char a1;

    unsigned char a2;

    clr_bit(1,3);  

set_bit(1,3); 

    a1=SPI_W_R(0x00);                //74HC165输入使能       

a2=SPI_W_R(0x00);           //读出键值

KEY_DATA=a1;

KEY_DATA<<=8;

KEY_DATA+=a2;

return;

}

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

void set_bit(unsigned char port,unsigned char n)//port为端口号分别用0~3表示A~D,n该端口的引脚号0~7

{

switch(port)

{

 case 0x00:

 PORTA|=(0x01<<n);

 break;

         case 0x01:

 PORTB|=(0x01<<n);

 break;

 case 0x02:

 PORTC|=(0x01<<n);

 break;

 case 0x03:

 PORTD|=(0x01<<n);

 break;

}

}

//****************OK**********************

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

void clr_bit(unsigned char port,unsigned char n)//port为端口号分别用0~3表示A~D,n该端口的引脚号0~7

{

switch(port)

{

 case 0x00:

 PORTA&=~(0x01<<n);

 break;

     case 0x01:

 PORTB&=~(0x01<<n);

 break;

 case 0x02:

 PORTC&=~(0x01<<n);

 break;

 case 0x03:

 PORTD&=~(0x01<<n);

 break;

}

}

//***************OK***********************************************

unsigned char SPI_W_R(unsigned char data)

{

SPCR=0x50;                  //SPI为查询方式,系统时钟四分频

SPDR=data;                  //写入数据

while((SPSR>>7)==0x00);     //等待数据发送完毕

return SPDR;                //返回收到的数据

}

//*********************OK*****************************************


    总结:以上是AVR单片机使用SPI接口控制74HC595的例子,这些例子经过简单的修改就可以应用到其它具有SPI即可的芯片上,如SPI接口的Flash存储芯片AT45DB系列、SPI接口的时钟芯片DS1302、SPI接口的AD或DA芯片等等。

    对于AVR mega系列单片机一般都具有硬件SPI接口,建议客户使用硬件SPI接口,这样可以占用更少的硬件和软件资源。但软件实现SPI接口,也有一定的优势,如它使用的IO口不是固定的,可以根据需要来指定,它一次发送的数据可以不是8位,而是可以根据需要来指定。

      Shiftout VS Spiout

这两个语句都是SPI输出语句,与它们对应的分别是shiftin和spiin
    shiftout语句可以使用在硬件spi或软件spi接口,通过config语句来确定:
          Config Spi = Hard/soft
    Shiftout语句使用在软件spi接口。

关闭窗口

相关文章