STM32F407xx内嵌四个通用同步/异步接收器(USART1,USART2,USART3和USART6)和两个通用异步收发器(UART4和UART5)。这6个接口提供异步通信的IrDASIR ENDEC支持,多机通信模式,单线半双工通信模式LIN主/从功能。 USART1和USART6接口能够速度高达10.5 Mbit / s的通信其他可用的接口通信高达5.25bit/s。USART1,USART2,USART3和USART6还提供硬件管理的CTS,RTS信号,智能卡的模式(ISO7816兼容)和类似的SPI通信能力。所有接口都可以通过DMA控制器。 USART name | Standard features | Modem (RTS/CTS) | LIN | SPI master | irDA | Smartcard (ISO 7816) | Max. baud rate in Mbit/s (oversampling by 16) | Max. baud rate in Mbit/s (oversampling by 8) | APB mapping | USART1 | X | X | X | X | X | X | 5.25 | 10.5 | APB2 (max. 84 MHz) | USART2 | X | X | X | X | X | X | 2.62 | 5.25 | APB1 (max. 42 MHz) | USART3 | X | X | X | X | X | X | 2.62 | 5.25 | APB1 (max. 42 MHz) | UART4 | X | - | X | - | X | - | 2.62 | 5.25 | APB1 (max. 42 MHz) | UART5 | X | - | X | - | X | - | 2.62 | 5.25 | APB1 (max. 42 MHz) | USART6 | X | X | X | X | X | X | 5.25 | 10.5 | APB2 (max. 84 MHz) |
这里只介绍两根线的最简单串口设置。 波特率的计算: USART用的波特率是由APB时钟线和波特率寄存器USART_BRR确定的,USART_BRR为32位寄存器,其中高16位保留,低十六位确定波特率,低16位又分为[15:4]和[3:0]或[15:4]和[2:0],具体分法由OVER8决定,[15:4]存放USARTDIV的整数部分,小数部分由[3:0]或[2:0]存放。
小数部分USARTDIV的小数部分乘以16或8,结果保留整数存于USART_BRR[3:0]或[2:0]中 比如:要求波特率为115200
设置OVER8=0 解得:USARTDIV=22.768 USART_BRR[15:4]=22=0x16 USART_BRR[3:0]=0.768*16=13=0xC USART_BRR=0x0000016C 设置步骤: 1. 设置中断优先级分组(如果之前没有设置),这个最好一个程序里只在开头设置一次。 2. 使能相关时钟。 3. 设置波特率。 4. 设置控制寄存器CR。 5. 选择相关GPIO引脚的复用功能。 6. 设置相关GPIO引脚为复用模式。 7. 设置相关GPIO引脚的速度,方式。 8. 如果要用到中断,设置USART中断优先级。 9. 如果要用到中断,使能USART中断。 10. 如果要用中断,编写中断服务函数(函数名是固定的)。 11. 中断服务函数里检查是哪个中断。 12. 编写相应服务程序。 电路参见本博客:小工具之——max232电平转换
程序:
[plain] view plain copy
- /*********************************************
- 标题:操作USART的练习
- 软件平台:IAR for ARM6.21
- 硬件平台:stm32f4-discovery
- 主频:168M
-
- 描述:从其他设备接收数据,再把数据发送出去
-
- author:小船
- data:2012-02-01
- **********************************************/
-
- #include <stm32f4xx.h>
-
- u32 Gb_TimingDelay;
-
- u8 suffer[100];
- u8 ok_to_send;
- u8 Rx_data_counter;
-
- void Delay(uint32_t nTime);
-
- void main ()
- {
-
- char Tx_data_counter;
-
- SCB->AIRCR = 0x05FA0000 | 0x400; //中断优先级分组 抢占:响应=3:1
- SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断
-
- RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟
- RCC->APB1ENR |= (1<<18); //使能usart3时钟
-
- USART3->BRR = 0x0000016C; //波特率115200
-
- /*
- 使能usart3
- usart3发送使能
- usart3接收使能
- 接收缓冲区非空中断使能
- 8bit
- 一位停止位
- 无校验
- */
- USART3->CR1 |= (( 1<<13 ) | ( 1<<3 ) | ( 1<<2 ) | ( 1<<5 ));
-
- GPIOD->AFR[1] |= 0x00000077;//选择PD8,9复用功能
-
- GPIOD->MODER &= 0xFFF0FFFF; //设置PD8,9,复用模式
- GPIOD->MODER |= 0x000A0000;
-
- // GPIOD->OTYPER &= 0xFFFFDFFF; //设置PD9推挽输出
-
- GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m
- GPIOD->OSPEEDR |= 0x00020000;
-
- GPIOD->PUPDR &= 0xFFFCFFFF; //PD8
- GPIOD->PUPDR |= 0x00010000;
-
- NVIC->IP[39] = 0xf0; //最低抢占优先级,最低响应优先级1111
- NVIC->ISER[1] |= (1<<(39-32)); //使能中断线39,也就是usart3中断
-
- while(1)
- {
- if(ok_to_send) //接收到数据,可以将数据发送
- {
- if((USART3->SR & (1<<7))) //发送数据寄存器空
- {
- USART3->DR = suffer[Tx_data_counter];
- Tx_data_counter++;
- if( suffer[Tx_data_counter] == '\r' )
- {
- Tx_data_counter = 0;
- USART3->CR1 |= 1<<5; //使能接收中断
- ok_to_send = 0;
- }
- }
- }
- }
- }
-
-
- void Delay(uint32_t nTime)
- {
- Gb_TimingDelay = nTime;
-
- while(Gb_TimingDelay != 0);
- }
-
- void SysTick_Handler(void)
- {
- if (Gb_TimingDelay != 0x00)
- {
- Gb_TimingDelay--;
- }
- }
-
- void USART3_IRQHandler(void)
- {
- if(USART3->SR & (1<<5)) //接收数据寄存器非空
- {
- suffer[Rx_data_counter] = USART3->DR;
- Rx_data_counter++;
- if(suffer[Rx_data_counter - 1] == '\r')
- {
- Rx_data_counter = 0;
- USART3->CR1 &= ~(1<<5); //除能接收中断
- ok_to_send = 1;
- }
- }
- }
运行结果:
|