wuzhengmin 发表于 2025-10-13 19:45:38

SPI数据模式:



CPOL:SPI 时钟极性控制
0:SCLK 空闲时为低电平,SCLK 的前时钟沿为上升沿,后时钟沿为下降沿1:SCLK 空闲时为高电平,SCLK 的前时钟沿为下降沿,后时钟沿为上升沿CPHA:SPI 时钟相位控制
0:数据 SS 管脚为低电平驱动第一位数据并在 SCLK 的后时钟沿改变数据,前时钟沿采样数据(必须 SSIG=0)
1:数据在 SCLK 的前时钟沿驱动,后时钟沿采样



wuzhengmin 发表于 2025-10-13 19:48:22

2.硬件连接
1.硬件链接

不过,我仔细在试验箱上找了,没有发现有 W25X40CL 芯片,可能是用其他芯片替换了吧?



wuzhengmin 发表于 2025-10-13 19:49:50

CS:低电平有效DI/DO:数据输入输出端WP:低电平写保护HOLD:低电平时暂停CLK:时钟信号
这里芯片是用3.3V的:


wuzhengmin 发表于 2025-10-13 19:52:04

接下来学习程序的编写:


先看好时序图:

我觉得没有单总线的18B20 那么清晰,有点乱:

wuzhengmin 发表于 2025-10-13 19:54:12

1.SPI的IO口初始化2.SPI读取一个字节(MSB模式)3.SPI写入一个字节
我们写个模式0(CPOL=0和 CPHA=0)的程序:


wuzhengmin 发表于 2025-10-13 19:55:26

先明确引脚:



//------------------------------引脚定义------------------------------
#define CS    P22
#define MISOP24
#define WP    P53
#define MOSIP23
#define SCLKP25



wuzhengmin 发表于 2025-10-13 19:56:21



最关键是3个函数:


void SPI_Init()   //SPI初始化
{
                CS   =1;//不选中该器件
                MISO =1;//不要一开始就拉低引脚电平,避免从机发数据过来接收不到
                WP   =1;//不需要锁定
                MOSI =1;//不需要锁定
                SCLK =0;//SPI选模式0,初始化 CPOL=0
       
}       

void SPI_WriteByte(u8 dat)   //写一个字节
{
        u8 i;
        for(i=0;i<8;i++)//如果是MSB就先写高位
        {
                if( dat & 0x80)//判断最高位是1么?
                MOSI = 1;
                else
                MOSI = 0;   //和单总线不同,不用输出1码,直接就是高电平
                SCLK =1;    //产生一个下降沿
                SCLK =0;    //数据就传出去
               
                dat<<=1;   //再返回去循环第二位
               
        }

}


u8SPI_RearByte()   //读取一个字节
{
        u8 i;
        u8 dat;
        for(i=0;i<8;i++)//如果是MSB就先写高位
        {
                dat<<=1;    //最先接到的数据放在最高位
               
                SCLK =0;    //产生一个上升沿
                SCLK =1;    //数据就传出去
               
                if( MISO)//判断MOSI是高位1么?这是从机往主机发送数据
                dat |= 1;//一定是|=1
                else
                dat |= 0;   //和单总线不同,不用输出1码,直接就是低电平
               
                                   //再返回去循环第二位
        }
       
        return dat;



}


wuzhengmin 发表于 2025-10-13 19:57:25

看看主函数:


void main()                                        //程序开始运行的入口
{
        int dat = 0;                        //初始数值
        sys_init();                                //USB功能+IO口初始化
        usb_init();                                //usb库初始化
        EUSB = 1;
        Timer0_Init();                        //定时器0初始化

        EA = 1;                                        //CPU开放中断,打开总中断。

        while( DeviceState != DEVSTATE_CONFIGURED );

        SPI_Init();   //SPI初始化
       
        while(1)                //死循环
        {
                u8ID;
               
                delay_ms(2);

                if( bUsbOutReady )                //单片机每接受到一次数据,就打印一次存储芯片的ID号回来串口                                                       
                {
//                        USB_SendData(UsbOutBuffer,OutNumber);
                        usb_OUT_done();
                       
                        CS = 0;
                       
                        SPI_WriteByte(0xAB);   //写入一个字节,0xAB命令,读取芯片ID
                       
                        SPI_WriteByte(0x00);   //写入一个字节,空命令,读取芯片ID
                        SPI_WriteByte(0x00);   //写入一个字节,空命令,读取芯片ID
                        SPI_WriteByte(0x00);   //写入一个字节,空命令,读取芯片ID
                       
                        ID = SPI_RearByte();   //读取一个字节
                       
                        CS = 1 ;
                       
                        printf("本芯片的ID: %u\r\n", (u16)ID);//ID是无符号的8位变量 %u 对应u16,这是10进制打印
                        printf("本芯片的ID: %x\r\n", (u16)ID);//ID是无符号的8位变量 %u 对应u16,这是16进制打印

                       
                }

                if( TIM_10MS_Flag==1 )                                                                        //如果10ms到了
                {
                        TIM_10MS_Flag = 0;                                                                        //清空标志位       
                }
               
//研究SPI时序图可知,SPI初始化结束后,往从机里发0xAB指令,接着发3个任意空指令,
//接着马上在D0上读取一个字节,这个字节就是芯片的ID
               


                       
        }
}


wuzhengmin 发表于 2025-10-13 20:00:24

当然,看着冲哥写,跟着冲哥写,就容易


离开视频,真正自己对照时序图,能写出来并且调通,上机实验,能得到正确结果

那才是真的学会了!

好了,spi 就简单先到这里,其实还没完...................

wuzhengmin 发表于 2025-10-14 08:27:33

前几天不知道什么原因,我的PC机(win10) 突然出来个毛病


鼠标右键要选择文件夹,就开始转圈,然后闪退,之后用了很多方法,都没有解决

只能重装系统,在网上找了个纯净的win10 ,装完系统后随便装了2个软件,故障又出现

后来没辙了,退会win7 ,好像问题就解决了,今天开始用一下win7 继续搞STC32G12K128的实验

接着看软件模拟SPI读取芯片ID的运行结果:

一个是16进制,一个是10进制

页: 10 11 12 13 14 15 16 17 18 19 [20] 21 22 23 24 25 26 27 28 29
查看完整版本: 第一次:环境的创立 | 送实验箱