进阶之路(基础篇) - 008 SPI数据传输(库函数方法)
主机端:
1 /********************************* 2 代码功能:SPI数据传输(主机端) 3 引脚说明: 4 SS/CS:片选(高电平屏蔽,低电平启用) 5 MOSI :主机送出信号 6 MISO :主机结收信号 7 CLK :时钟脉冲 8 SPI成员: 9 begin(); 10 功能 :初始化SPI,设置CLK,MISO和SS为输出,将SCK和MOSI拉低,将SS拉高。 11 形式 :SPI.begin(); 12 返回值:none 13 setBitOrder(); 14 功能:设 置进入和输出SPI总线比特(bit)的顺序:LSBFIRST(低位开始)或者 MSBFIRST (高位开始)。 15 形式:SPI.setBitOrder(order); 16 参数:order:LSBFIRST或 MSBFIRST 17 返回值:none 18 setClockDivider(); 19 功能:设置SPI串行通信时钟的分频系数 20 形式:setClockDivider(SPI_CLOCK); 21 参数(SPI_CLOCK) 22 SPI_CLOCK_DIV2 //2分频,系统时钟的 1/2 23 SPI_CLOCK_DIV4 //4分频,系统时钟的 1/4 24 SPI_CLOCK_DIV8 //8分频,系统时钟的 1/8 25 SPI_CLOCK_DIV16 //16分频,系统时钟的 1/16 26 SPI_CLOCK_DIV32 //32分频,系统时钟的 1/32 27 SPI_CLOCK_DIV64 //64分频,系统时钟的 1/64 28 SPI_CLOCK_DIV128 //128分频,系统时钟的 1/128 29 setDataMode(); 30 功能:设置数据模式 31 形式:SPI.setDataMode(mode); 32 参数(mede): 33 SPI_MODE0 CPOL = 0 CPHA = 0 34 SPI_MODE1 CPOL = 0 CPHA = 1 35 SPI_MODE2 CPOL = 1 CPHA = 0 36 SPI_MODE3 CPOL = 1 CPHA = 1 37 时钟极性CPOL: 即SPI空闲时,时钟信号SCLK的电平(1:空闲时高电平; 0:空闲时低电平) 38 时钟相位CPHA: 即SPI在SCLK第几个边沿开始采样(0:第一个边沿开始; 1:第二个边沿开始) 39 transfer(); 40 功能:在SPI上传输一个字节(byte),发送和接收都是这个函数 41 形式:SPI.transfer(val); 42 参数(val):要发送的字节 43 返回值:从 bus 上读取字节。(读操作使用的时候) 44 end(); 45 功能:结束传输 46 形式:end(); 47 参数:无 48 返回值:无 49 创作时间:2016*10*10 50 作者邮箱:jikexianfeng@outlook.com 51 ********************************/ 52 #include<SPI.h> //共用MOSI从机输入线 53 void setup() 54 { 55 Serial.begin(115200); //串口通信波特率 56 Serial.println("start ..."); 57 digitalWrite(SS,HIGH); //SS高电平表示从器件未被选中,从器件不工作,MISO输出高阻; 58 SPI.begin(); //初始化SPI串口 59 SPI.setClockDivider(SPI_CLOCK_DIV8); //设置SPI的时钟速率为8分频 60 } 61 void loop() 62 { 63 char c; 64 digitalWrite(SS,LOW); //启动周边选择 65 for(const char *p = "Hello world!\n";c = *p;p++) //送出测试的字符 66 { 67 SPI.transfer(c); //SPI输出数据 68 Serial.print(c); //串口输出数据 69 } 70 digitalWrite(SS,HIGH); //使从器件不工作 71 delay(1000); 72 }
从机端:
1 /********************************* 2 代码功能:SPI数据传输(从机端) 3 创作时间:2016*10*14 4 作者邮箱:jikexianfeng@outlook.com 5 ********************************/ 6 #include<SPI> 7 char buf[100]; //设置缓冲区 8 volatile byte pos; //定义一个共享的字符 9 volatile boolean process_it; //定义一个共享的整型 10 11 void setup(void) 12 { 13 //通信串口设置 14 Serial.begin(115200); //设置串口和波特率 15 Serial.println("start slave"); 16 //SPI总线设置 17 pinMode(MISO,OUTPUT); //拉高屏蔽主机输出线 18 SPCR |= _BV(SPE); //打开ISP在从机 19 SPI.setBitOrder(MSBFIRST); //传输方式高位开始 20 SPI.setDataMode(SPI_MODE0); //设置SPI数据模式 21 SPI.setClockDivider(SPI_CLOCK_DIV8); //设置SPI的时钟速率为8分频 22 //中断使用数据 23 pos = 0; 24 process_it = false; //假 25 SPI.attachInterrupt(); //准备好中断 26 } 27 //ISR终端服务程序 28 ISR(SPI_STC_vect) 29 { 30 byte c = SPDR; //从SPI寄存器读取数据 31 if(pos < sizeof(buf)) //判断空间是否使用完 32 { 33 buf[pos++] =c; 34 if(c =='\n') 35 process_it = true; 36 } 37 } 38 void loop(void) 39 { 40 if(process_it) //判读数据是否写入结束 41 { 42 String stringOne = String(buf); 43 Serial.print(stringOne); 44 buf[pos] = 0; 45 pos = 0; 46 process_it = false; 47 } 48 }