问一个关于STM32 SPI的问题

wangjianqun 2014-09-07 04:57:35
打算用STM32读写93C46,因为是SPI总线所以,用STM32的SPI2读写,可怎么都不行,后来又GPIO模拟也不行,请教一下高手,是什么问题呢?
模拟SPI程序如下:
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler);
#if(bb)
void c46init()
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

}



void Ewen(void)
{
u8 temp,InData;
CS=0;
delay_us(1);
CLK=0;
CS=1;
InData=0x98; // 10011XXXX
for(temp=9;temp!=0;temp--)
{ // 9位的指令(当93c46选择为16结构时,93c46有7条9位的指令
DI=InData&0x80; // 将InData按位输入
CLK=1;delay_us(1); CLK=0;
InData<<=1; //InData=InData<<1;
}
CS=0;
}

void Ewds(void)
{
u8 temp,InData;
CS=0;
delay_us(1);
CLK=0;
CS=1;
InData=0x80; // 10000XXXX
for(temp=9;temp!=0;temp--)
{ // 9位的指令(当93c46选择为16结构时,93c46有7条9位的指令
DI=InData&0x80; // 将InData按位输入
CLK=1; delay_us(1);CLK=0;
InData<<=1; //InData=InData<<1;
}
CS=0;
}

//写入93c46RAM
void write(unsigned char address,unsigned int InData)
{
u8 temp;
Ewen();
CLK=0; DI=1; // 101 A5-A0
CS=0;delay_us(1); CS=1;
CLK=1;delay_us(1); CLK=0; // 先输入一个1
address=address&0x3f|0x40; // address变成10xxxxxx
for(temp=8;temp!=0;temp--) // 接下来连续输入8位(在93C46中的地址 指令形式 101 A5-A0)
{ // 8
DI=address&0x80;
CLK=1;delay_us(1); CLK=0;
address<<=1;
}
for(temp=16;temp!=0;temp--) // 写入16位的数据(一字节)
{
DI=InData&0x8000;
CLK=1;delay_us(1); CLK=0; //上升沿
InData<<=1; //InData=InData<<1;
}
CS=0; DO=1;
delay_us(1);
CS=1; CLK=1; //CS不片选芯片(为0)的时间要大于Tcsmin
while(DO==0)
{
CLK=0;delay_us(1); CLK=1; //如果繁忙状态,则CLK=0,CS=1
}
CLK=0; CS=0; // 结束
Ewds();
}

//读出93c46RAM
unsigned int read(unsigned char address)
{
u8 i;
u16 result;
Ewen();
CLK=0; DI=1; // 110 A5-A0
CS=0;delay_us(1); CS=1;
CLK=1;delay_us(1); CLK=0; // 先输入一个1
address=address&0x3f|0x80; // address变成10xxxxxx
for(i=8;i!=0;i--) // 接下来连续输入8位(在93C46中的地址 指令形式 110 A5-A0)
{ // 8
DI=address&0x80;
CLK=1;delay_us(1); CLK=0;
address<<=1;
}
DO=1;
for(i=16;i!=0;i--) //读取16位的数据(一字节)
{ // 16
CLK=1; //在下降沿输出数据到DO
result=(result<<1)|DO; //将数据按位存入result中
delay_us(1);
CLK=0;
}
CS=0;
Ewds();
return(result);
}
...全文
949 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lion_Peng 2014-09-26
  • 打赏
  • 举报
回复
引用 7 楼 wangjianqun 的回复:
似乎找到问题了 93C46的控制命令是9位的,应该是输入的命令不对,我选的8位模式,如何输入9位命令呢?
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;是不是这个?
piaoyayezi 2014-09-24
  • 打赏
  • 举报
回复
解决了吗?使用使用AF不用重映射引脚吗?
wangjianqun 2014-09-10
  • 打赏
  • 举报
回复
这是硬件SPI的程序,但还是读写不了。之前用51的时候是没问题的
wangjianqun 2014-09-10
  • 打赏
  • 举报
回复
void SPI2_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI2, ENABLE); //使能SPI外设 // SPI2_SetSpeed(SPI_BaudRatePrescaler_8); } //SPI 速度设置函数 //SpeedSet: //SPI_BaudRatePrescaler_2 2分频 //SPI_BaudRatePrescaler_8 8分频 //SPI_BaudRatePrescaler_16 16分频 //SPI_BaudRatePrescaler_256 256分频 void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler) { assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); SPI2->CR1&=0XFFC7; SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度 SPI_Cmd(SPI2,ENABLE); } //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 SPI2_ReadWriteByte(u8 TxData) { u8 retry=0; while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位 { retry++; if(retry>200)return 0; } SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据 retry=0; while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位 { retry++; if(retry>200)return 0; } return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据 } void Ewen(void) { CS=1; SPI2_ReadWriteByte(0x98); CS = 0; } void Ewds(void) { CS=1; SPI2_ReadWriteByte(0x80); CS = 0; } u16 read(u8 addr) { u16 rec; Ewen(); CLK=0; DI=1; // 110 A5-A0 CS=0; CS=1; CLK=1; CLK=0; // 先输入一个1 addr=addr&0x3f|0x80; rec = SPI2_ReadWriteByte(addr); CS=0; Ewds(); return rec; } void write(u8 add,u16 data) { //u8 dh,dl; Ewen(); CLK=0; DI=1; // 101 A5-A0 CS=0;CS=1; CLK=1;CLK=0; // 先输入一个1 add=add&0x3f|0x40; SPI2_ReadWriteByte(add); //dh = data>>8; //dl = data&0x00ff; //SPI2_ReadWriteByte(dh); //SPI2_ReadWriteByte(dl); SPI2_ReadWriteByte(data); CS = 0; Ewds(); }
wangjianqun 2014-09-10
  • 打赏
  • 举报
回复
似乎找到问题了 93C46的控制命令是9位的,应该是输入的命令不对,我选的8位模式,如何输入9位命令呢?
zhxianbin 2014-09-09
  • 打赏
  • 举报
回复
网上 stm32 spi 的代码多入牛毛,找个改改啊,这种配置基本不用改 为什么要用GPIO模拟呢,怀疑 芯片spi 有问题吗?我觉得这种解决问题的方法是浪费时间
zhxianbin 2014-09-09
  • 打赏
  • 举报
回复
    //SPI1 configuration
    SPI_Cmd(SPI1, DISABLE);
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE); // Enable SPI1
这段代码没有吧
Lenka丨 2014-09-09
  • 打赏
  • 举报
回复
速度问题 可能
wangjianqun 2014-09-09
  • 打赏
  • 举报
回复
没人知道吗 ?

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧