打印

SPI 怎么会一直输出16BIT

[复制链接]
5490|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zxp12345|  楼主 | 2013-11-5 17:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
型号STM32F051 怎么会输出16 BIT 的CLOCK,本意是想输出8BIT。
用IO模拟也就半小时的事。
想用他的硬件SPI,结果折腾半天了。一直不对。:L
沙发
zhaoxinzxzx| | 2013-11-5 17:45 | 只看该作者
楼主要贴程序+图形啊!无图无真相!

使用特权

评论回复
板凳
zxp12345|  楼主 | 2013-11-5 18:55 | 只看该作者
摘部分相关代码:
int mian()
{

        RCC->AHBENR|=RCC_AHBENR_GPIOAEN|RCC_AHBENR_GPIOBEN;
        RCC->APB1ENR|=RCC_APB1ENR_SPI2EN|RCC_APB1ENR_TIM2EN|RCC_APB1ENR_DACEN;//enabe SPI2 and TIME2 clock and DAC 0x01;//|(1<<18));

        GPIOB->MODER|=0xaa000000;                //Pb12 13,14,15 SPI2 comm
        GPIOB->MODER|=0x00000a80;                //PB3,Pb4,Pb5 Af
        while(1)
        {
                  Spi2Send(0xa5);
        DelayMs(10);
        }
}

void Spi2Init(void)
{

        SPI2->CR2&=0x70ff;//SPI_DataSize_8b;
        SPI2->CR2|=SPI_DataSize_8b;

        SPI2->CR2|=1<<2;
        SPI2->CR1&=0xffc7;
        SPI2->CR1|=SPI_BaudRatePrescaler_256|SPI_FirstBit_MSB|SPI_NSS_Hard;//7<<3;        //Spi Clock =fosc/256       
        SPI2->CR1|=(SPI_CPOL_High|SPI_CR1_MSTR|SPI_CPHA_2Edge);        //Spi Clock =fosc/256       
        SPI2->CR2|=1<<3;
        SPI2->CR1|=1<<9;

        SPI2->CR2&=~(1<<12);
        SPI2->CR1|=1<<13;
        SPI2->CRCPR=0x07;

        SPI2->CR1|=SPI_CR1_SPE;
       
}

void Spi2Send(unsigned char TxData)
{unsigned char retry=0;
       
        while(SPI2->SR&(1<<1)==0)       
        {
        retry++;
         if (retry>=200)       
                {
                retry=0;       
                return;       
                }
        }
        SPI2->DR=TxData;
       
}

波形就是16 CLOCK,数据对应高字节。这样一来看起来就变成了0Xa500

使用特权

评论回复
地板
feilusia| | 2013-11-5 20:36 | 只看该作者
没配置好吧?
我用的STM32F103ZET6:
SPI2->CR1 |= 0<<11 ;//数据格式:8bit       

使用特权

评论回复
5
puchuang| | 2013-11-5 20:57 | 只看该作者
原理图传上来   大家一起看看   应该很快就能解决问题了  楼主

使用特权

评论回复
6
zxp12345|  楼主 | 2013-11-5 21:57 | 只看该作者
这部分电路很简单,PB12,13,14,15接W25X SPI,硬件就不用怀疑有什么问题了,配置后CLK DO都有数据波形。同理也试过SPI1 (PB3,4,5),对应输出波形一样。

使用特权

评论回复
7
linfeng24| | 2013-11-6 00:21 | 只看该作者
应该不是硬件问题,我一直用的是8bit 的啊,楼主试试单步调试试试

使用特权

评论回复
8
香水城| | 2013-11-6 11:30 | 只看该作者
检查寄存器SPI->CR2的DS[3:0]位,配置成几位传输啦?

使用特权

评论回复
9
ilovezeno| | 2013-11-6 12:06 | 只看该作者
lz 你先用软件库把程序走通了,再改成寄存器操作不好么。。。。那就不会那么折腾了

使用特权

评论回复
10
香水城| | 2013-11-6 12:25 | 只看该作者
ilovezeno 发表于 2013-11-6 12:06
lz 你先用软件库把程序走通了,再改成寄存器操作不好么。。。。那就不会那么折腾了[em:20: ...

对的,一般都这个思路:先在库的demo中找一个和自己应用最接近的,跑通了,再修改功能,或使用寄存器操作。

使用特权

评论回复
11
zxp12345|  楼主 | 2013-11-6 14:42 | 只看该作者
        SPI2->DR=(uint8_t)TxData;
  *(__IO uint8_t *) spixbase = TxData;
这两句有什么区别?用前一句是出16BIT,用后一句是8BIT。库里用的是后者。
其他配置没有问题。
库里TX数据,什么时候发完,好象不做任何处理。按规格书写的不应该要看SPI-》SR BIT1么?

使用特权

评论回复
12
香水城| | 2013-11-6 17:19 | 只看该作者
SPI结构体定义DR这个成员是16位,因此【SPI2->DR=(uint8_t)TxData;】是把一个8位数据写到16位指针所指的地址;后者【 *(__IO uint8_t *) spixbase = TxData;】即库里的SPI_SendData8()是把一个8位数据写到8位指针所指向的地址。

前者是否实际还是一个16位写入,看看汇编即知道。

使用特权

评论回复
13
香水城| | 2013-11-6 17:38 | 只看该作者
另外F0的SPI引入的独立的读FIFO和写FIFO。当数据帧长度不超过1字节时(比如配置成8位),可通过对SPI_DR的单次16位读写操作同时访问或处理2个数据帧。

因此当使用前者的写法,如果编译器作为一个16位写入的操作,则实际写入了两个8位长度的数据帧,因此会看到时钟出来了16个脉冲,对应2个8位数据帧。

使用特权

评论回复
14
香水城主| | 2013-11-6 22:06 | 只看该作者
还有这么一个陷阱呢?  坑爹呀!

使用特权

评论回复
15
zxp12345|  楼主 | 2013-11-8 23:03 | 只看该作者
呵呵,关键的时候,ASM还是起作用。
结贴散分

使用特权

评论回复
16
Zacking| | 2015-1-12 17:03 | 只看该作者
香水城 发表于 2013-11-6 17:38
另外F0的SPI引入的独立的读FIFO和写FIFO。当数据帧长度不超过1字节时(比如配置成8位),可通过对SPI_DR的 ...

请问香版主,stm32硬件SPI只能传输8位和16位吗?如果我要读写32位数据,是不是只能软件模拟的SPI呢?

使用特权

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

本版积分规则

26

主题

156

帖子

0

粉丝