SPI 怎么会一直输出16BIT

[复制链接]
6435|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       
puchuang 发表于 2013-11-5 20:57 | 显示全部楼层
原理图传上来   大家一起看看   应该很快就能解决问题了  楼主
 楼主| zxp12345 发表于 2013-11-5 21:57 | 显示全部楼层
这部分电路很简单,PB12,13,14,15接W25X SPI,硬件就不用怀疑有什么问题了,配置后CLK DO都有数据波形。同理也试过SPI1 (PB3,4,5),对应输出波形一样。
linfeng24 发表于 2013-11-6 00:21 | 显示全部楼层
应该不是硬件问题,我一直用的是8bit 的啊,楼主试试单步调试试试
香水城 发表于 2013-11-6 11:30 | 显示全部楼层
检查寄存器SPI->CR2的DS[3:0]位,配置成几位传输啦?
ilovezeno 发表于 2013-11-6 12:06 | 显示全部楼层
lz 你先用软件库把程序走通了,再改成寄存器操作不好么。。。。那就不会那么折腾了
香水城 发表于 2013-11-6 12:25 | 显示全部楼层
ilovezeno 发表于 2013-11-6 12:06
lz 你先用软件库把程序走通了,再改成寄存器操作不好么。。。。那就不会那么折腾了[em:20: ...

对的,一般都这个思路:先在库的demo中找一个和自己应用最接近的,跑通了,再修改功能,或使用寄存器操作。
 楼主| zxp12345 发表于 2013-11-6 14:42 | 显示全部楼层
        SPI2->DR=(uint8_t)TxData;
  *(__IO uint8_t *) spixbase = TxData;
这两句有什么区别?用前一句是出16BIT,用后一句是8BIT。库里用的是后者。
其他配置没有问题。
库里TX数据,什么时候发完,好象不做任何处理。按规格书写的不应该要看SPI-》SR BIT1么?
香水城 发表于 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位写入,看看汇编即知道。
香水城 发表于 2013-11-6 17:38 | 显示全部楼层
另外F0的SPI引入的独立的读FIFO和写FIFO。当数据帧长度不超过1字节时(比如配置成8位),可通过对SPI_DR的单次16位读写操作同时访问或处理2个数据帧。

因此当使用前者的写法,如果编译器作为一个16位写入的操作,则实际写入了两个8位长度的数据帧,因此会看到时钟出来了16个脉冲,对应2个8位数据帧。
香水城主 发表于 2013-11-6 22:06 | 显示全部楼层
还有这么一个陷阱呢?  坑爹呀!
 楼主| zxp12345 发表于 2013-11-8 23:03 | 显示全部楼层
呵呵,关键的时候,ASM还是起作用。
结贴散分
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

粉丝
快速回复 在线客服 返回列表 返回顶部