STM32F4-DISCO 学习之把USART当低速SPI使用

/ 2评 / 0

USART模块有同步模式,并且可以输出时钟,也就是可以用作SPI,但是USART速度都不快.比如2.625MHz(USART2),或者5.25MHz(USART1),当然我们板子上的USART2不能用.这么慢速的设备,适合用于像触摸芯片等慢速设备.而且他是基于串口的分频器,所以分频出来可以更精确某个频率(当然,SPI一般并不那么要求.) 我做了个表格,关于各种频率:

PCLK(Hz) 42,000,000            
               
16倍采样波特率计算 BRR=PCLK/Baud          
波特率设定 分频比>=1 计算结果 实际分频比 寄存器值(HEX) 实际波特率 波特率误差 误差百分比
9,600 273.4375 4375 273.4375 1117 9600.00 0.00 0.000
19,200 136.71875 2187 136.6875 88B 19204.39 4.39 0.023
38,400 68.359375 1093 68.3125 445 38426.35 26.35 0.069
115,200 22.78645833 364 22.75 16C 115384.62 184.62 0.160
230,400 11.39322917 182 11.375 B6 230769.23 369.23 0.160
1,000,000 2.625 42 2.625 2A 1000000.00 0.00 0.000
2,000,000 1.3125 21 1.3125 15 2000000.00 0.00 0.000
               
16倍采样波特率计算 BRR=(PCLK+Baud/2)/Baud        
波特率设定 分频比>=1 计算结果 实际分频比 寄存器值 实际波特率 误差 误差百分比
9,600 273.4375 4375 273.4375 1117 9600.00 0.00 0.000
19,200 136.71875 2188 136.75 88C 19195.61 -4.39 -0.023
38,400 68.359375 1094 68.375 446 38391.22 -8.78 -0.023
115,200 22.78645833 365 22.8125 16D 115068.49 -131.51 -0.114
230,400 11.39322917 182 11.375 B6 230769.23 369.23 0.160
1,000,000 2.625 42 2.625 2A 1000000.00 0.00 0.000
2,000,000 1.3125 21 1.3125 15 2000000.00 0.00 0.000
               
8倍采样波特率计算 BRR=PCLK/Baud          
波特率设定 分频比>=1 计算结果 实际分频比 寄存器值(HEX) 实际波特率 波特率误差 误差百分比
9,600 546.875 4375 546.875 2227 9600.00 0.00 0.000
19,200 273.4375 2187 273.375 1113 19204.39 4.39 0.023
38,400 136.71875 1093 136.625 885 38426.35 26.35 0.069
115,200 45.57291667 364 45.5 2D4 115384.62 184.62 0.160
230,400 22.78645833 182 22.75 166 230769.23 369.23 0.160
1,000,000 5.25 42 5.25 52 1000000.00 0.00 0.000
2,000,000 2.625 21 2.625 25 2000000.00 0.00 0.000
               
8倍采样波特率计算 (PCLK+Baud/2)/Baud        
波特率设定 分频比>=1 计算结果 实际分频比 寄存器值(HEX) 实际波特率 波特率误差 误差百分比
9,600 546.875 4375 546.875 2227 9600.00 0.00 0.000
19,200 273.4375 2188 273.5 1114 19195.61 -4.39 -0.023
38,400 136.71875 1094 136.75 886 38391.22 -8.78 -0.023
115,200 45.57291667 365 45.625 2D5 115068.49 -131.51 -0.114
230,400 22.78645833 182 22.75 166 230769.23 369.23 0.160
1,000,000 5.25 42 5.25 52 1000000.00 0.00 0.000
2,000,000 2.625 21 2.625 25 2000000.00 0.00 0.000

比如我们要发生2MHz的SPI时钟,那么波特率应该是2000000bps.要使能CLKEN引脚,CLKEN才能输出.比如我的配置.

QQ截图20151027125001

一般来说,SPI还是MSB的,但是串口是LSB的,但是串口这里不能MSB先发,所以也有一些其他限制.特别注意的是,CLKEN必须有,才能输出SCLK,然后TX就是MOSI,RX就是MISO.为什么要M位,这个在串口模式下,他是表示9位数据,但是SPI模式是发8Bit,因为时钟只发了8Bit,最后一个被忽略了.波特率稍微高一些,SPI设备肯定比串口设备更能接受数据啊,所以BRR我们设置0x15,也就是2MHz.因为之前学习了BitBand,所以这里有一些涉及BitBand的寄存器配置.但是有一些注释,也是很方便的.

void DUSART_Init(void)
{
    GPIOA_B->MODER.MODER2 = 0x02; //PA2
    GPIOA_B->OSPEEDR.OSPEEDR2 = 0x02;
    GPIOA_B->PUPDR.PUPDR2 = 0x01;
    GPIOA_B->MODER.MODER4 = 0x02; //PA4
    GPIOA_B->OSPEEDR.OSPEEDR4 = 0x02;
    GPIOA_B->PUPDR.PUPDR4 = 0x01;
    GPIOA_B->AFR[0].AFR2 = 0x07; //Pin Mux
    GPIOA_B->AFR[0].AFR4 = 0x07;
    USART2->BRR = 0x00000015; //2MHz
    USART2->CR1 = 0x00003008; //EN + TX + 9B(8B For SPI)
    USART2->CR2 = 0x00000800; //CLKOUT
}

 然后可以做一个测试示例.

void test_spi_usart(void)
{
    uint8_t i = 0;
    for(i = 0x00; i < 0xff; i++)
    {
        while(!(USART2_B->SR.TC));
        GPIOD_B->ODR.ODR15 = 0x01;
        Delay(1);
        GPIOD_B->ODR.ODR15 = 0x00;
        USART2->DR = i;
    }
}

就可以发SPI了,不过是LSB,不支持MSB的.

  1. Joy说道:

    太好,完美解决了我SPI不够用的问题。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注