SPI学习笔记
1、写时序图:
第一字节是访问寄存器地址,第二字节是写数据,从图中可以看出,在写操作的时候,都是上升沿有效,并且必须拉高CE信号,数据时从最低位开始发送,到最高位结束。
2、读时序图:
第一字节也是访问寄存器地址,上升沿有效。第二字节是读数据开始,下降沿有效。同时CE必须拉高。第一字节数据是从LSB开始发送,第二字节数据时从LSB开始接收的。
3、DS1302寄存器和RAM操作
BIT7 固定
BIT6 1—> 访问RAM空间 0—>访问寄存器本身
BIT5. .1 表示寄存器或者RAM空间的地址
BIT0 表示访问寄存器本身:0—>写操作,1—>读操作
写:
先写入第一节地址-{2’b10,5’dAddr,1’b0};
后写入第二节数据-{如8’hff};
读:
先写入第一节地址-{2’b10,5’dAddr,1’b1};
后读出第一节数据-{4’h读出十位,4’h读出个位}
寄存器地址(BIT6-BIT1):
秒:5’d0 BIT7 代表开启或关闭计时
时:5’d2 BIT7 代表12小时和24小时制选择
控制:5’d7 BIT7 0—>关闭写保护 1—>打开写保护
故每次要变更寄存器的内容之前,就要关闭写保护
4、ds1302寄存器地址定义:
6、时钟产生和数据发送
0时将数据存入rData寄存器,1时将rData的第0位数据送到数据线上,2时上升沿到来,将数据锁存。(上面的写法可以保证在上升沿到来之前,数据已经准备好)。
SPI写数据代码:
1 else if( Start_Sig[1] ) 2 case( i ) 3 4 0 : 5 begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end//先将数据暂存如寄存器rData中 6 7 1, 3, 5, 7, 9, 11, 13, 15 : 8 if( Count1 == T0P5US ) i <= i + 1'b1;//0.5us的计数保证数据传送完成 9 else begin rSIO <= rData[ (i >> 1) ]; rSCLK <= 1'b0; end//在上升沿到来之前,先将数据按位送到数据线上,即在上升沿到来之前必须将数据准备好 10 11 2, 4, 6, 8, 10, 12, 14, 16 : 12 if( Count1 == T0P5US ) i <= i + 1'b1;//0.5us的计数保证数据传送完成 13 else begin rSCLK <= 1'b1; end//上升沿到来,锁存数据 14 15 17 : 16 begin rData <= Write_Data; i <= i + 1'b1; end 17 18 18, 20, 22, 24, 26, 28, 30, 32 : 19 if( Count1 == T0P5US ) i <= i + 1'b1; 20 else begin rSIO <= rData[ (i >> 1) - 9 ]; rSCLK <= 1'b0; end 21 22 19, 21, 23, 25, 27, 29, 31, 33 : 23 if( Count1 == T0P5US ) i <= i + 1'b1; 24 else begin rSCLK <= 1'b1; end 25 26 34 : 27 begin rRST <= 1'b0; i <= i + 1'b1; end 28 29 35 : 30 begin isDone <= 1'b1; i <= i + 1'b1; end 31 32 36 : 33 begin isDone <= 1'b0; i <= 6'd0; end 34 35 endcase
SPI读数据代码:
1 else if( Start_Sig[0] ) 2 case( i ) 3 4 0 : 5 begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end 6 7 1, 3, 5, 7, 9, 11, 13, 15 : 8 if( Count1 == T0P5US ) i <= i + 1'b1; 9 else begin rSIO <= rData[ (i >> 1) ]; rSCLK <= 1'b0; end 10 11 2, 4, 6, 8, 10, 12, 14, 16 : 12 if( Count1 == T0P5US ) i <= i + 1'b1; 13 else begin rSCLK <= 1'b1; end 14 15 17 : 16 begin isOut <= 1'b0; i <= i + 1'b1; end 17 18 18, 20, 22, 24, 26, 28, 30, 32 : 19 if( Count1 == T0P5US ) i <= i + 1'b1; 20 else begin rSCLK <= 1'b1; end 21 22 19, 21, 23, 25, 27, 29, 31, 33 : 23 if( Count1 == T0P5US ) begin i <= i + 1'b1; end 24 else begin rSCLK <= 1'b0; rData[ (i >> 1) - 9 ] <= SIO; end 25 26 34 : 27 begin rRST <= 1'b0; isOut <= 1'b1; i <= i + 1'b1; end 28 29 35 : 30 begin isDone <= 1'b1; i <= i + 1'b1; end 31 32 36 : 33 begin isDone <= 1'b0; i <= 6'd0; end 34 35 endcase
SPI数据线:
1 assign SIO = isOut ? rSIO : 1'bz
isOut控制SIO是写入还是读出状态:读入数据时,为高阻态。写数据是,即为低电平或者高电平。