wuzhengmin 发表于 2025-10-15 15:56:33

下面是重点研究的时序图:


1.SPI的IO口初始化2.SPI读取一个字节(MSB模式)3.SPI写入一个字节这3个函数都是看着时序图来编写:


wuzhengmin 发表于 2025-10-15 16:00:13

跟着冲哥,慢慢来:


void SPI_Init(void)                                //初始化
        {
                CS           = 1;                                        //不选中该器件
                MISO= 1;                                        //       
                WP          = 1;                       
                MOSI= 1;       
                SCLK= 0;                                        //spi模式0,sclk初始化为低电平       
        }


        void SPI_WriteByte(u8 dat)                //写入一个字节
        {
                u8 i;
                for( i=0;i<8;i++ )
                {
                        if( dat & 0x80 )
                                MOSI = 1;
                        else
                                MOSI = 0;
                        SCLK = 1;                                //下降沿
                        SCLK = 0;
                        dat <<=1;
                }
        }


        u8 SPI_ReadByte(void)                        //读取一个字节
        {
                u8 i;
                u8 dat=0;
               
                for( i=0;i<8;i++ )
                {
                        dat<<=1;
                       
                        SCLK = 1;                               
                        if( MISO )                                //从机往主机发送数据的引脚
                                dat |= 1;
        //                else
        //                        dat |= 0;
                        SCLK = 0;
                }
               
                return dat;
        }这是软件模拟的情况,能读出存储芯片的ID:

wuzhengmin 发表于 2025-10-15 16:02:31

接着就换硬件的SPI:


先看寄存器:


首先是引脚选择,我们还是配成01 :P22 P23 P24 P25

wuzhengmin 发表于 2025-10-15 16:04:49

串口1控制寄存器(SCON)我们要选择模式0,注意第四位REN必须配置为1才能接受数据。


wuzhengmin 发表于 2025-10-15 16:06:21

硬件SPI 对应的3个函数:


void SPI_Init(void)                                //初始化
        {
                P_SW1 &= 0XF3;                //1111 0011                P_SW1功能寄存器,引脚切换选择 B3B2位决定4种引脚配置
                P_SW1 |= 0X04;                //0000 0100   我们要选P22P23P24P25,先要把B3B2清零,才能改写为01
                                                        //清零用P_SW1 &= 1111 0011 B3B2改写为01:P_SW1 |= 0000 0100
               
                SPCTL = 0X90;                //SPI控制寄存器SPCTL,SPCTL是最核心的模式配置,第一位取1:忽略引脚功能,
                                    //使用MSTR确定器件是主机还是从机,第二位是使能位,第三位DORD:SPI数据位发
                                                        //送/接收的顺序,0:先发送/接收数据的高位(MSB)1:先发送/接收数据的低
                                                        //位(LSB).第四位MSTR:器件主/从模式选择位:设置主机模式
                                                        //若 SSIG=0,则 SS 管脚必须为高电平且设置 MSTR 为1若 SSIG=1,则只需要设置
                                                        //MSTR 为 1(忽略 SS 管脚的电平)设置从机模式:
                                                        //若 SSIG=0,则 SS 管脚必须为低电平(与 MSTR 位无关)若 SSIG=1,则只需要设
                                                        //置 MSTR 为 0(忽略 SS 管脚的电平)第3位CPOL设置时钟极性和时钟相位控制
                                                        //CPOL:SPI 时钟极性控制,0:SCLK 空闲时为低电平,SCLK 的前时钟沿为上升沿,
                                                        //后时钟沿为下降沿1:SCLK 空闲时为高电平,SCLK 的前时钟沿为下降沿,后时钟沿
                                                        //为上升沿第2位CPHA:SPI 时钟相位控制,0:数据 SS 管脚为低电平驱动第一位数
                                                        //据并在 SCLK 的后时钟沿改变数据,前时钟沿采样数据(必须SSIG=0),1:数据在
                                                        //SCLK 的前时钟沿驱动,后时钟沿采样.最后1和0位是时钟频率选择
               
               
                SPCTL |= 0X40;   //只有1个存储芯片,配主从模式,第一位和第四位取1,先不使能,MSB方式读取:得
                                                   //0x90,配置完成,最后再使能SPI:SPCTL |= 0X40(第二位置1)
               
                SCLK = 0;                        //时钟引脚初始化spi模式0,sclk初始化为低电平       
               
                SPIF = 1;                        //SPSTAT是状态寄存器,SPIF清空标志位要置1。当发送/接收完成 1 字节的数据后,
                                                        //硬件自动将此位置 1,并向 CPU 提出中断请求。当 SSIG 位被设置为0 时,由于
                                                        //SS管脚电平的变化而使得设备的主/从模式发生改变时,此标志位也会被硬件自动
                                                        //置1,以标志设备模式发生变化。注意:此标志位必须用户通过软件方式向此位写
                                                        //1 进行清零。SPIF不等于0,发送/接受就结束了,SPIF读到0表示正在读写,读到
                                                        //1表示完成
                WCOL = 1;         //WCOL:SPI写冲突标志位。当SPI在进行数据传输的过程中写SPDAT寄存器时,硬件
                                                        //将此位置1.注意:此标志位必须用户通过软件方式向此位写 1 进行清零。
                                                        //读取和写入完成之后都要清空SPIF和WCOL(置1)
        }


        void SPI_WriteByte(u8 dat)                //写入一个字节
        {
                SPDAT = dat;       //SPI 数据寄存器(SPDAT),SPI 发送/接收数据缓冲器。
                while(SPIF == 0);
                SPIF = 1;          //每次读取写入完成后都要清空状态寄存器标志位
                WCOL = 1;                   //每次读取写入完成后都要清空状态寄存器标志位
        }


        u8 SPI_ReadByte(void)                        //读取一个字节
        {
                SPDAT = 0XFF;       //SPI 数据寄存器(SPDAT),SPI 发送/接收数据缓冲器。
                                                        //这里发送一个字节,主要是为了产生8位时钟脉冲,没有脉冲无法读数据
                while(SPIF == 0);
                SPIF = 1;         //每次读取写入完成后都要清空状态寄存器标志位
                WCOL = 1;                  //每次读取写入完成后都要清空状态寄存器标志位
                return SPDAT;
        }我已经注释的很详细了,方便以后查看..............

wuzhengmin 发表于 2025-10-15 16:09:55

最后是USART_SPI


串口1同步模式控制寄存器1(USARTCR1)

这种串口配置,寄存器比较多,一开始容易晕菜:


wuzhengmin 发表于 2025-10-15 16:13:29

不过,其实还好,有些我们不要管它..........


串口1同步SPI的函数如下:

void SPI_Init(void)                                //初始化USART_SPI寄存器
        {
                P_SW3 &= 0XF3;                //1111 0011                引脚选择P_SW3 第3位第2位选01模式(对应引脚P22--P25)
                P_SW3 |= 0X04;                //0000 0100
               
                SCON = 0x10;       //串口1控制寄存器(SCON)模式0同步移位串行方式 REN位取1
               
                USARTCR1=0x10;    //串口1同步模式控制寄存器1(USARTCR1)DORD:SPI 模式数据位发送/接收的顺序
                                                  //0:先发送/接收数据的高位(MSB)
                                                  //1:先发送/接收数据的低位(LSB)
                USARTCR4=0x00;    //串口1同步模式控制寄存器4(USARTCR4),SPI 模式时钟选择,选最慢
                USARTCR1|=0x08;//1:使能 SPI 功能

        }


        void SPI_WriteByte(u8 dat)                //写入一个字节
        {
                TI = 0;          //清标志位
                SBUF = dat;
                while(!TI);
        }


        u8 SPI_ReadByte(void)                        //读取一个字节
        {
                TI = 0;      //清标志位
                SBUF = 0X00;   //产生8个时钟脉冲信号用来传递数据
                while(!TI);
                return SBUF;
        }        也是尽可能详细的注释,方便以后查询.....................

运行结果也很顺利 ,感觉真的是好像七窍通了六窍,不是真的懂了,只是做了一遍,嘻嘻!好了,今天就这样啦!

wuzhengmin 发表于 2025-10-17 09:53:53

今天我们继续学习   第二十九集:SPI读写FLASH芯片


先看看大致任务:


1.W25X40CL简介
2.数据读写
3.代码实现
4.实战小练(温室大棚历史温度记录装置)


看手册,还是要英文好,所以我们当初开日语的,很吃亏!

wuzhengmin 发表于 2025-10-17 09:56:42

命名规则如下:


我在咱们的试验箱上没有找到这颗芯片,不过我们有替代品:


GD AY2122 25Q40CTIGUFT369


wuzhengmin 发表于 2025-10-17 09:58:30

试验箱说明书的图纸:



对应型号是:Ul1PM25LV040   都是一样的使用方法



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