基于C8051F340单片机的增强型串行外设接口——SPI0从器件模式应用C程序

一、前言

C8051F340单片机的增强型串行外设接口(SPI0)提供访问一个全双工同步串行总线的能力。SPI0 可以作为主器件或从器件工作,可以使用 3 线或 4 线方式,并可在同一总线上支持多个主器件和从器件。
本文展示配置为从器件模式。主入从出(MISO)信号是从器件的输出和主器件的输入,用于从从器件到主器件的串行数据传输。当 SPI0 作为主器件时,该信号是输入;当 SPI0 作为从器件时,该信号是输出。数据传输时最高位在先。当 SPI 被禁止或工作在 4 线从方式而未被选中时, MISO 引脚被置于高阻态。当作为从器件工作在 3 线方式时,MISO 由移位寄存器的 MSB 驱动。

二、程序展示

1、头文件部分

#include <C8051F340.h>
#define SYSCLK 12000000 
#define MAX_BUFFER_SIZE 8
#define  SLAVE_LED_ON  0x01
#define  SLAVE_LED_OFF 0x02 
#define  SPI_WRITE  0x04
#define  SPI_READ   0x08
#define  SPI_WRITE_BUFFER  0x10
#define  SPI_READ_BUFFER   0x20 
#define  ERROR_OCCURRED    0x40
sbit LED = P2^2;
unsigned char SPI_Data = 0xA5;
unsigned char SPI_Data_Array[MAX_BUFFER_SIZE] = {0};
void PCA0_Init (void);
void Oscillator_Init (void);
void Port_Init (void);
void SPI0_Init (void);
void Init_Device (void);

2、主程序

void main (void)
{
   Init_Device (); 
   EA = 1;             
   LED = 0;
   while (1);   
}

3、PCA0初始化程序

void PCA0_Init (void)
{
   PCA0MD &= ~0x40;   //关闭看门狗
   PCA0MD = 0x00;
}

4、振荡器初始化程序

void Oscillator_Init (void)
{
   OSCICN = 0x83;  // 使用内部12M晶振
}

5、端口初始化程序

void PORT_Init (void)
{
   P0MDOUT = 0x02;   // 设置MISO推挽输出
   P2MDOUT = 0x04;   // 设置P2.2推挽输出
   P2SKIP = 0x04;    //跳过P2.2
   XBR0 = 0x02;     //允许配置SPI
   XBR1 = 0x40;     
}

6、SPI0初始化程序

void SPI0_Init()
{
   SPI0CFG = 0x00;  // 配置为从器件模式                                      
   SPI0CN = 0x05;    //允许SPI为4线从模式
   ESPI0 = 1;      //允许SPI中断
}

7、设备初始化程序

void Init_Device (void)
{
   PCA0_Init ();   
   Oscillator_Init ();
   Port_Init ();
   SPI0_Init ();
}

8、SPI中断程序

void SPI_ISR (void) interrupt 6
{
   static unsigned char command;
   static unsigned char array_index = 0;
   static unsigned char state = 0;
   unsigned char dummy_byte;
   if (WCOL == 1)
   {
      // Write collision occurred

      SPI0DAT = ERROR_OCCURRED;   
      WCOL = 0;   
   }
   else if (RXOVRN == 1)
   {
      SPI0DAT = ERROR_OCCURRED;        
      RXOVRN = 0;  
   }
   else
   {
      if (state == 0)
      {
         command = SPI0DAT;   // 读命令

         array_index = 0; 

         switch (command)
         {
            case SLAVE_LED_ON:
               LED = 1;
               state = 0;    // 传输结束
               break;
            case SLAVE_LED_OFF:
               LED = 0;
               state = 0;   //传输结束
               break;
            case SPI_WRITE:
               state = 1;
               break;
            case SPI_READ:
               SPI0DAT = SPI_Data;    
               state = 0;  // 结束传输
               break;
            case SPI_WRITE_BUFFER:
               state = 1;             
               break;
            case SPI_READ_BUFFER:
               SPI0DAT = SPI_Data_Array[array_index]; 
               array_index++;
               state = 1;             
               break;
            default:
               state = 0;
         }

      }
      else if (state == 1)
      {
         switch (command)
         {
            case SPI_WRITE:
               SPI_Data = SPI0DAT;
               state = 0;   // 传输结束
               break;
            case SPI_WRITE_BUFFER:
               SPI_Data_Array[array_index] = SPI0DAT; // 接收下一字节
               array_index++;
               if (array_index == MAX_BUFFER_SIZE) //是否最后一字节
               {
                  state = 0;           
               }
               else
               {
                  state = 1; 
               }
               break;
            case SPI_READ_BUFFER:
               SPI0DAT = SPI_Data_Array[array_index]; 
               dummy_byte = SPI0DAT;   
               array_index++;
               if (array_index == MAX_BUFFER_SIZE) 
               {
                  state = 0;          
               }
               else
               {
                  state = 1;           
               }

               break;
            default:
               state = 0;
         }
      }

      SPIF = 0;                   
   }
}
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xll_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值