打印
[N32G03x]

N32G030 SPI2不能使用

[复制链接]
741|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liguhu138|  楼主 | 2023-1-8 09:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        GPIO_InitType  GPIO_InitStructure;
        SPI_InitType  SPI_InitStructure;
                               
        RCC_EnableAPB1PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
        RCC_EnableAPB1PeriphClk(RCC_APB2_PERIPH_SPI2, ENABLE);

        GPIO_InitStructure.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11; //CS SCK SO   
        GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
                                GPIO_InitStructure.GPIO_Alternate =  GPIO_AF0_SPI2;
        GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
                               
                                GPIO_InitStructure.Pin = GPIO_PIN_8;//SI   
        GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
                                //GPIO_InitStructure.GPIO_Alternate =  GPIO_AF0_SPI2;
        GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
                                     
        RCC_EnableAPB1PeriphReset(RCC_APB2_PERIPH_SPI2,ENABLE);//¸´Î»SPI1
                                //Delay_Ms(20);
        RCC_EnableAPB1PeriphReset(RCC_APB2_PERIPH_SPI2,DISABLE);//Í£Ö¹¸´Î»SPI1
                               
        SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;          //ÉèÖÃSPIµ¥Ïò»òÕßË«ÏòµÄÊý¾Ýģʽ:SPIÉèÖÃΪ˫ÏßË«ÏòÈ«Ë«¹¤
        SPI_InitStructure.SpiMode = SPI_MODE_MASTER;                                                //ÉèÖÃSPI¹¤×÷ģʽ:ÉèÖÃΪÖ÷SPI
        SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;                                            //ÉèÖÃSPIµÄÊý¾Ý´óС:SPI·¢ËͽÓÊÕ8λ֡½á¹¹
        SPI_InitStructure.CLKPOL = SPI_CLKPOL_HIGH;                                                        //´®ÐÐͬ²½Ê±ÖӵĿÕÏÐ״̬Ϊ¸ßµçƽ
        SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;                                                //´®ÐÐͬ²½Ê±Öӵĵڶþ¸öÌø±äÑØ£¨ÉÏÉý»òϽµ£©Êý¾Ý±»²ÉÑù
        SPI_InitStructure.NSS = SPI_NSS_SOFT;                                                                                //NSSÐźÅÓÉÓ²¼þ£¨NSS¹Ü½Å£©»¹ÊÇÈí¼þ£¨Ê¹ÓÃSSI룩¹ÜÀí:ÄÚ²¿NSSÐźÅÓÐSSIλ¿ØÖÆ
        SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_4;                      //¶¨Ò岨ÌØÂÊÔ¤·ÖƵµÄÖµ:²¨ÌØÂÊÔ¤·ÖƵֵΪ256
        SPI_InitStructure.FirstBit = SPI_FB_MSB;                                                                                               //Ö¸¶¨Êý¾Ý´«Êä´ÓMSBλ»¹ÊÇLSBλ¿ªÊ¼:Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼
        SPI_InitStructure.CRCPoly = 7;                                                                                                                                       //CRCÖµ¼ÆËãµÄ¶àÏîʽ
        SPI_Init(SPI2, &SPI_InitStructure);                                                                                                                                 //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPIx¼Ä´æÆ÷
                               
                                /* Enable SPI_MASTER TE interrupt */
                                //SPI_I2S_EnableInt(SPI2, SPI_I2S_INT_TE, ENABLE);
               
        SPI_Enable(SPI2, ENABLE); //ʹÄÜSPIÍâÉè      

不能使用SPI2对EEPROM操作,AT25640B    请问大神有没有错误设置?

使用特权

评论回复
沙发
Afanx| | 2023-1-8 13:33 | 只看该作者
做主机用软件控制CS引脚,不要用硬件NSS功能,NSS好像给从机用的。CS直接配置普通推挽输出,需要传输时手动拉低CS。

使用特权

评论回复
板凳
liguhu138|  楼主 | 2023-1-8 15:47 | 只看该作者
CS 我是手动操作的,把数据送到DAT中,不会产生CK信号,一直为高电平。

使用特权

评论回复
地板
liguhu138|  楼主 | 2023-1-9 08:21 | 只看该作者
我也是手动操作的,把数据送到DAT中,是不会产生CK信号,如果不产生,怎样的芯片通讯,我看了规格书中说要CK操作时,才能通讯。

使用特权

评论回复
5
liguhu138|  楼主 | 2023-1-9 08:28 | 只看该作者
#ifndef __AT25640_c__
#define __AT25640_c__

//#include"Config.h"
#include"AT25640.h"
#include"Delay.h"

#define WREN 0x06//设置写入启用锁存器
#define WRDI 0x04//复位锁存器--禁止写入
#define RDSR 0x05//读状态寄存器
#define WRSR 0x01//写状态寄存器
#define READ 0x03//读数据至存储列表
#define WRITE 0x02//写数据至存储列表
/*
WREN 0000 X110 Set Write Enable Latch
WRDI 0000 X100 Reset Write Enable Latch
RDSR 0000 X101 Read Status Register
WRSR 0000 X001 Write Status Register
READ 0000 X011 Read Data from Memory Array
WRITE 0000 X010 Write Data to Memory Array
*/

void eeprom_init()
{
        GPIO_InitType  GPIO_InitStructure;
        SPI_InitType  SPI_InitStructure;
                               
       
        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_SPI2, ENABLE);

        GPIO_InitStructure.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11; //SI SCK SO   
        GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
                                GPIO_InitStructure.GPIO_Alternate =  GPIO_AF0_SPI2;
        GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
                               
                                GPIO_InitStructure.Pin = GPIO_PIN_8;//CS   
        GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
                                //GPIO_InitStructure.GPIO_Alternate =  GPIO_AF0_SPI2;
        GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
       
                                //GPIO_SetBits(GPIOA,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11);
                                     
        //RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI2,ENABLE);//复位SPI1
                                //Delay_Ms(20);
        //RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_SPI2,DISABLE);//停止复位SPI1
                               
        SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;          //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SpiMode = SPI_MODE_MASTER;                                                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;                                            //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.CLKPOL = SPI_CLKPOL_HIGH;                                                        //串行同步时钟的空闲状态为高电平
        SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;                                                //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.NSS = SPI_NSS_SOFT;                                                                                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_4;                      //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.FirstBit = SPI_FB_MSB;                                                                                               //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.CRCPoly = 7;                                                                                                                                       //CRC值计算的多项式
        SPI_Init(SPI2, &SPI_InitStructure);                                                                                                                                 //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
                               
                                /* Enable SPI_MASTER TE interrupt */
                                //SPI_I2S_EnableInt(SPI2, SPI_I2S_INT_TE, ENABLE);
               
        SPI_Enable(SPI2, ENABLE); //使能SPI外设     

              eeprom_read_write_byte(0xff);//启动传输       
}

//SPI 速度设置函数
/*
#define SPI_BR_PRESCALER_2   ((uint16_t)0x0000)
#define SPI_BR_PRESCALER_4   ((uint16_t)0x0008)
#define SPI_BR_PRESCALER_8   ((uint16_t)0x0010)
#define SPI_BR_PRESCALER_16  ((uint16_t)0x0018)
#define SPI_BR_PRESCALER_32  ((uint16_t)0x0020)
#define SPI_BR_PRESCALER_64  ((uint16_t)0x0028)
#define SPI_BR_PRESCALER_128 ((uint16_t)0x0030)
#define SPI_BR_PRESCALER_256 ((uint16_t)0x0038)
*/
//void eeprom_set_speed(u8 SPI_BaudRatePrescaler)
//{
//                                assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
//                                SPI2->CTRL1&=0XFFC7;//位3--5清零,用来设置波特率
//                                SPI2->CTRL1|=SPI_BaudRatePrescaler;        //设置SPI的速度
//                                //SPI_Enable(SPI2,ENABLE); //使能SPI1
//}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 eeprom_read_write_byte(u8 TxData)//0:发送 1:接收
{            
                                        u8 retry;
                                        while (SPI_I2S_GetStatus(SPI2, SPI_I2S_TE_FLAG) == RESET){
                                                        retry++;
                                                        if(retry>200) return 0;
                                        }                                                //等待发送区空    0:非空 1:空
                                        SPI_I2S_TransmitData(SPI2, TxData);                                                                                                                                         //通过外设SPIx发送一个byte 数据
                               
                                        while (SPI_I2S_GetStatus(SPI2, SPI_I2S_RNE_FLAG) == RESET){
                                                                retry++;
                                                                if(retry>200) return 0;
                                        }                                         //等待接收完一个byte  0:空  1:非空
                                        return SPI_I2S_ReceiveData(SPI2);                                                                                                                                                 //返回通过SPIx最近接收的数据  
}

//==============================================================================
// 描述: 在AT25读状态寄存器
// 输入: 无
// 返回: unsigned char dat 状态寄存器数据
//==============================================================================
u8 eeprom_read_sr(void)
{
        u8 dat;
        Eeprom_Cs_Off;
        eeprom_read_write_byte(RDSR);        //  写入指令0x05
        dat = eeprom_read_write_byte(0xff);       //读回数据
        Eeprom_Cs_On;
        return  dat;
}

//==============================================================================
// 描述: 向AT25写入一个数据
// 输入: unsigned char Dat 字符数据
//       unsigned int addr 写入的地址
// 返回: 无
//==============================================================================
void eeprom_write_byte(u16 addr,u8 Dat)
{
        unsigned char Add;
        while(eeprom_read_sr()&RDSR);        //读状态寄存器           
      
        Eeprom_Cs_Off;
        eeprom_read_write_byte(WREN);            //写使能锁存器               
        Eeprom_Cs_On;
        Eeprom_Cs_Off;                                  // 芯片使能
                               
//        if(addr>0x00ff)
//          eeprom_read_write_byte((WRITE|0x08));  //地址大于255         
//        else
//          eeprom_read_write_byte(WRITE);        //地址小于255         

        Add = (unsigned char)(addr & 0xff);             // 将地址换成8位
        eeprom_read_write_byte(Add);

        eeprom_read_write_byte(Dat);
        Eeprom_Cs_On;                              
}

//==============================================================================
// 描述: 在AT25读一个字节操作
// 输入: 无
// 返回: unsigned char dat 读出一个字符数据
//==============================================================================
u8 eeprom_read_byte(u16 addr)
{
        u8 dat,add;
        while(eeprom_read_sr()&RDSR);                   //读状态寄存器
        Eeprom_Cs_Off;

//        if(addr>0x00ff)
//          eeprom_read_write_byte((READ | 0x08));   //地址大于255     
//        else
//                                        eeprom_read_write_byte(READ);                  //地址小于255

        add = (unsigned char)(addr & 0xff);             // 将地址换成8位
        eeprom_read_write_byte(add);

        dat=eeprom_read_write_byte(0xff);
        Eeprom_Cs_On;
        return dat;
}

//==============================================================================
//描述:向AT25连续写入数据
//输入:unsigned char *PC写入数据指针
//unsigned int count 写入数量计数
//unsigned int SatAddr写入起始地址
//返回:无
//==============================================================================
void eeprom_write_buf(u16 startAddr,u8 *buf,u16 count)
{
        u16 i;
        while(eeprom_read_sr()&RDSR);                   // 读状态指令

        Eeprom_Cs_Off;
        eeprom_read_write_byte(WREN);                           //写使能锁存
        Eeprom_Cs_On;
        Eeprom_Cs_Off;
      
        eeprom_read_write_byte(WRITE);                        //写入写操作指令
        eeprom_read_write_byte(startAddr>>8);                 //写入地址
        eeprom_read_write_byte(startAddr);

        for(i=0;i<count;i++)
        {
                eeprom_read_write_byte(*buf++);
        }
        Eeprom_Cs_On;                                   
}
//==============================================================================
//描述:向AT25连续写入n字节的数据
//输入:unsigned char *PC写入数据指针
//unsigned int count写入数据计数
//unsigned int StaAddr写入起始地址
//返回:无
//==============================================================================
void eeprom_write_nbyte(u16 startAddr,u8 *buf,u16 count)
{
        u16 pageTotal=count/64;
        u16 pageResidue=count%64;
        u16 i;
        u16 pageCnt=0;
      
        for(i=0;i<pageTotal;i++)
        {
                eeprom_write_buf(startAddr+pageCnt,&buf[pageCnt],64);
                pageCnt+=64;
        }
        eeprom_write_buf(startAddr+pageCnt,&buf[pageCnt],pageResidue);
}


//==============================================================================
//描述:在AT25连续读数据
//输入:unsigned char *PC读出数据指针
//unsigned int count 读出数量指针
//unsigned int StaAddr读出起始指针
//==============================================================================
void eeprom_read_buf(u16 startAddr,u8 *buf,u16 count)
{
        unsigned int i;
        while(eeprom_read_sr()&RDSR);                   //读状态寄存器
        Eeprom_Cs_Off;
      
        eeprom_read_write_byte(READ);       //写入读操作指令     
        eeprom_read_write_byte(startAddr>>8);
        eeprom_read_write_byte(startAddr);

        for(i=0;i<count;i++)
        {
                *buf++ = eeprom_read_write_byte(0xff);
        }
        Eeprom_Cs_On;
}


#endif


这个是SPI通讯


#include"Include.h"
                               
void RCC_Configuration(void)
{
    /* TIM1, GPIOA, GPIOB, GPIOE and AFIO clocks enable */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB |
                                                                                                                RCC_APB2_PERIPH_TIM1  | RCC_APB2_PERIPH_AFIO , ENABLE);
       
          RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3,ENABLE);
                /* Enable SPI_MASTER Periph clock */
    //RCC_EnableAPB2PeriphClk(SPI_MASTER_GPIO_CLK | SPI_MASTER_CLK , ENABLE);
    //When debug ,TIM1 and TIM3 stop
    DBG_ConfigPeriph(DBG_TIM1_STOP | DBG_TIM3_STOP , ENABLE);
}

void NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;
    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority           = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void GPIO_Configuration()
{
    GPIO_InitType GPIO_InitStructure;

                RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB,ENABLE);
                                       
                GPIO_InitStruct(&GPIO_InitStructure);//初始化GPIO--复位所有IO为默认设置
               
    GPIO_InitStructure.Pin        = GPIO_PIN_3 ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;//复用功能
    GPIO_InitStructure.GPIO_Current = GPIO_DC_LOW;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF3_TIM1;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
               
                GPIO_InitStructure.Pin        = GPIO_PIN_5 ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;//复用功能
    GPIO_InitStructure.GPIO_Current = GPIO_DC_HIGH;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF4_TIM1;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
               
                GPIO_InitStructure.Pin        = GPIO_PIN_0 ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
}

void Send_Dat(Uchar Data_Out)
{
                USART_SendData(USART1,Data_Out);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXDE)==RESET);
}

int main(void)
{
        Uchar Dat;
        RCC_Configuration();
        GPIO_Configuration();
        Usart1_Init(115200);
        TIM_Initial(TIM1);
        TIM3_Int_Init(9,47);
        eeprom_init();
        Delay_Init();
       
        while(1)
        {
                if(Time.T_500ms) {
                        Time.T_500ms=0;
                       
                        eeprom_write_byte(0x00,0x02);
                        Delay_Ms(10);
                        Dat=eeprom_read_byte(0x00);
                       
                        Send_Dat(Dat);
                       
                        Flag.Led=!Flag.Led;
                        if(Flag.Led) {
                                RunLed_On;
                                RedLed_On;
//                                USART_SendData(USART1,0xAA);
//                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXDE)==RESET);
                        }
                        else {
                                RunLed_Off;
                                RedLed_Off;
//                                USART_SendData(USART1,0xBB);
//                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXDE)==RESET);
                        }
                                       
                        Send_Dat(0xAB);
                }
               
                if(Flag.Led_On) {
                        Flag.Led_On=0;
                        //RunLed_On;
                        Send_Tu_Ta(1,1);
                }
                else if(Flag.Led_Off) {
                        Flag.Led_Off=0;
                        //RunLed_Off;
                        Send_Tu_Ta(1,10);
                }
               
                if(Time.T_1ms) {
                        Time.T_1ms=0;
                        Usart1_Reset();
                }
        }
}








这个是MAIN函数,不知道调用错了没有?

使用特权

评论回复
6
liguhu138|  楼主 | 2023-1-9 08:29 | 只看该作者
不知道怎样发文件。只有这个粘贴。

使用特权

评论回复
7
码道功澄| | 2023-1-9 11:09 | 只看该作者
配置成SPI_NSS_SOFT,调用一下SPI_Set_Nss_Level(SPI2, SPI_NSS_HIGH);试试

使用特权

评论回复
8
liguhu138|  楼主 | 2023-1-9 13:36 | 只看该作者
还是一样,SI,CK有输出,但SO一直为低电平。我想问下:有没有SPI2的例程?我想下载试下。

使用特权

评论回复
评论
码道功澄 2023-1-9 16:08 回复TA
有可能是通讯评率太高设置分频系数为32或者更大试试。 
9
chenjun89| | 2023-1-9 19:12 | 只看该作者
使用硬片选,一定要配置正确。

使用特权

评论回复
10
liguhu138|  楼主 | 2023-1-10 08:45 | 只看该作者
感觉没能启动SPI2,N32G030规格书里面有SPI2,不知道是不是真的?

使用特权

评论回复
11
ayb_ice| | 2023-1-10 08:57 | 只看该作者
我从不不用硬件SPI,IIC接口,模拟的移植特方便

使用特权

评论回复
12
liguhu138|  楼主 | 2023-1-10 09:54 | 只看该作者
有没有例程?发过来给我参考下。万分感激!

使用特权

评论回复
13
sy12138| | 2023-1-10 14:53 | 只看该作者
liguhu138 发表于 2023-1-9 13:36
还是一样,SI,CK有输出,但SO一直为低电平。我想问下:有没有SPI2的例程?我想下载试下。 ...

可以抓一下MOSI和SCLK的数据和软件配置的是否一样,以及发送的地址是否有问题

使用特权

评论回复
14
liguhu138|  楼主 | 2023-1-10 16:14 | 只看该作者
我现在改为软件模拟,时序都对,但SO输出只有1MS的高电平,这个应该是时序不对

使用特权

评论回复
15
liguhu138|  楼主 | 2023-1-11 10:24 | 只看该作者
模拟的已经调好了,现在想知道硬件的是什么问题?有没有什么好的例程?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

44

帖子

1

粉丝