上面的这段的程序配合注释可以很容易理解,USART_InitTypeDef定义了一个包括USART主要参数的结构体,因此首先对USART的相关参数进行配置,使用标准外设库进行配置的优势就体现出来了,通过程序可以很容易读出这个串口的配置:
l 波特率9600Kbps
l 数据长度8
l 停止位1
l 奇偶校验:无
l 硬件流控制:无
l 工作模式:收、发
然后利用USART_Init函数进行初始化,这段程序中设置了两个串口,使用同样的配置,然后配置相应的中断。最后通过USART_Cmd函数使能相应的串口,前面有过介绍,这些例程里的程序是针对官方的开发套件的,因此程序中并没有指名具体的端口,而是使用了宏定义USARTy、USARTz。通过这段程序就可以很方便的更改相关的参数得到我们需要的配置程序。
这儿只是完成了USART的配置,下面来看一下对应的I/O设置,仍然在这个文件中可以找到GPIO_Configuration(void)这个函数,程序如下:
- void GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- #ifdef USE_STM3210C_EVAL
- /* Enable the USART3 Pins Software Remapping */
- GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
- /* Enable the USART2 Pins Software Remapping */
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
- #elif defined USE_STM3210B_EVAL || defined USE_STM32100B_EVAL
- /* Enable the USART2 Pins Software Remapping */
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
- #endif
- /* Configure USARTy Rx as input floating */
- GPIO_InitStructure.GPIO_Pin = USARTy_RxPin;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
- /* Configure USARTz Rx as input floating */
- GPIO_InitStructure.GPIO_Pin = USARTz_RxPin;
- GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);
- /* Configure USARTy Tx as alternate function push-pull */
- GPIO_InitStructure.GPIO_Pin = USARTy_TxPin;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
- /* Configure USARTz Tx as alternate function push-pull */
- GPIO_InitStructure.GPIO_Pin = USARTz_TxPin;
- GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);
- }
复制代码
这段函数完成了相关的I/O配置,首先通过宏定义判断是官方的哪一款开发套件,然后进行相应的端口映射(端口映射请参加官方的数据手册),然后进行相应的端口配置,同串口配置一样,这段程序中德端口用的也是宏定义USARTy_RxPin替代的,改为我们使用的实际I/O,端口时钟设置为50MHz,串口所使用到的端口设置为复用(GPIO_Mode_AF_PP)完成端口初始化。
另外仍然通过观察这个例程可以很容易发现,在使用一个外设时还需要首先打开对应的外设时钟,这部分程序如下:
- void RCC_Configuration(void)
- {
- /* Enable GPIO clock */
- RCC_APB2PeriphClockCmd(USARTy_GPIO_CLK | USARTz_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
- #ifndef USE_STM3210C_EVAL
- /* Enable USARTy Clock */
- RCC_APB2PeriphClockCmd(USARTy_CLK, ENABLE);
- #else
- /* Enable USARTy Clock */
- RCC_APB1PeriphClockCmd(USARTy_CLK, ENABLE);
- #endif
- /* Enable USARTz Clock */
- RCC_APB1PeriphClockCmd(USARTz_CLK, ENABLE);
- }
复制代码
这段程序中需要注意两点,首先,GPIO、USART等都是连在APB1、APB2两条总线上的,各外设具体的总线连接情况参见图 5‑2,因此首先应该确定外设对应的总线,例如USART1是APB2总线,而USART2是APB1总线。其次使能相应的时钟时不光要使能对应的I/O端口,还要使能总线的复用端口,这点也容易忽略。
最后根据库中的例程,借鉴库中例程的编写风格,就可以得出我们需要的程序,程序在工程的mian.c中编写,函数如下:
- #include "stm32f10x.h"
- void USART_Configuration(void);
- void GPIO_Configuration(void);
- void Delay(__IO uint32_t nCount);
- void USART1_Puts(char * str);
- int main(void)
- {
- USART_Configuration();
- GPIO_Configuration();
- USART1_Puts("Hello Wrold!\n");
- while (1)
- {
- GPIOF->BSRR = 0x000000C0;
- Delay(0xAFFFF);
- GPIOF->BRR = 0x000000C0;
- Delay(0xAFFFF);
- USART1_Puts("Hello Wrold!\n");
- }
- }
- void USART_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- //使能串口、串口所用的I/O口以及端口复用时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO, ENABLE);
- /* A9 USART1_Tx */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出-TX
- GPIO_Init(GPIOA,&GPIO_InitStructure);
- /* A10 USART1_Rx */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入-RX
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART1, &USART_InitStructure);
- /* Enable the USARTx */
- USART_Cmd(USART1, ENABLE);
- }
- void GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
- /* 设置LED对应的引脚 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOF, &GPIO_InitStructure);
- }
- void Delay(__IO uint32_t nCount)
- {
- for(; nCount != 0; nCount--);
- }
- void USART1_Puts(char * str)
- {
- while(*str)
- {
- USART_SendData(USART1, *str++);
- /* Loop until the end of transmission */
- while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- }
- }
复制代码
至此完成了主函数的编写。接下来还需要到stm32f10x_conf.h文件中选择相应的头文件,这儿去掉需要使用的头文件之前的注释,去掉注释的头文件如下:
l #include "stm32f10x_gpio.h"
l #include "stm32f10x_gpio.h"
l #include "stm32f10x_usart.h"
这样,我们的程序编写就完成了,下面可以进行我们的编译与调试了。
|