需要添加的固件库文件有 stm32f4xx_gpio.c、stm32f4xx_rcc.c、 misc.c、 stm32f4xx_usart.c 四个。
1) 串口时钟和 GPIO 时钟使能。
串口3是挂载在 APB1 下面的外设,, 对应着芯片引脚 PB10、PB11,所以使能函数为:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
2) 设置引脚复用器映射
引脚复用器映射配置,调用函数为:
GPIO_PinAFConfig(GPIOB,GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource11, GPIO_AF_USART3);
因为串口使用到 PB10,PB11,所以我们要把 PB10 和PB11 都映射到串口3。所以这里调用两次函数。 对于 GPIO_PinAFConfig 函数的第一个和第二个参数很好理解,就是设置对应的 IO 口,如果是 PB10那么第一个参数是GPIOB,第二个参数就是 GPIO_PinSource10。第二个参数,实际不需要去记忆,只需去相应的配置文件找到外设对应的 AF 配置宏定义标识符即可,串口 3为 GPIO_AF_USART3。
3) GPIO 端口模式设置: PB10,PB11 要设置为复用功能。
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 |GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
4) 串口参数初始化并使能:设置波特率,字长,奇偶校验等参数
串口初始化是调用函数 USART_Init 来实现的,具体设置方法如下:
USART_InitStructure.USART_BaudRate=bound;
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity= USART_Parity_No;
USART_InitStructure.USART_StopBits= USART_StopBits_1;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
5) 开启中断并且初始化 NVIC,使能相应中断
这一步如果我们要开启串口中断才需要配置 NVIC 中断优先级分组。通过调用函数NVIC_Init 来设置。
NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
同时,我们还需要使能相应中断,使能串口中断的函数是:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,
FunctionalState NewState)
这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。比如在接收到数据的时候(RXNE 读数据寄存器非空),我们要产生中断,那么开启中断的方法是:
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
在发送数据结束的时候(TC,发送完成)要产生中断,那么方法是:
USART_ITConfig(USART1,USART_IT_TC,ENABLE);
这里还要特别提醒,因为实验开启了串口中断,所以在系统初始化的时候需要先设置系统的中断优先级分组,是在main 函数开头设置的,代码如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
设置分组为 2,也就是 2 位抢占优先级,2 位响应优先级。
6) 中断服务函数
当发生中断的时候,程序就会执行中断服务函数。然后在中断服务函数中编写我们相应的逻辑代码即可。
void USART3_IRQHandler(void)
{
u8 rec_data;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
rec_data =(u8)USART_ReceiveData(USART3);
if(rec_data=='S')
{
uart_byte_count=0x01;
}
else if(rec_data=='E')
{
if(strcmp("Light_led1",(char *)receive_str)==0) LED1=0;
else if(strcmp("Close_led1",(char *)receive_str)==0) LED1=1;
else if(strcmp("Open_beep",(char *)receive_str)==0) BEEP=1;
else if(strcmp("Close_beep",(char *)receive_str)==0) BEEP=0;
for(uart_byte_count=0;uart_byte_count<32;uart_byte_count++)receive_str[uart_byte_count]=0x00;
uart_byte_count=0;
}
else if((uart_byte_count>0)&&(uart_byte_count<=USART3_REC_NUM))
{
receive_str[uart_byte_count-1]=rec_data;
uart_byte_count++;
}
}
}
7) 软件设计
usart.c 代码
#include "common.h"
#include "beep.h"
#include "led.h"
#include "usart3.h"
#include "string.h"
#include "stdlib.h"
u8 receive_str[USART3_REC_NUM];
u8 uart_byte_count=0;
void uart3_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource11, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 |GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
USART_InitStructure.USART_BaudRate=bound;
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity= USART_Parity_No;
USART_InitStructure.USART_StopBits= USART_StopBits_1;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void uart3SendChar(u8 ch)
{
while((USART3->SR&0x40)==0);
USART3->DR = (u8) ch;
}
int fputc(int ch, FILE *f)
{
uart3SendChar(ch);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
return ch;
}
void uart3SendChars(u8 *str, u16 strlen)
{
u16 k= 0 ;
do { uart3SendChar(*(str + k)); k++; }
while (k < strlen);
}
void USART3_IRQHandler(void)
{
u8 rec_data;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
rec_data =(u8)USART_ReceiveData(USART3);
if(rec_data=='S')
{
uart_byte_count=0x01;
}
else if(rec_data=='E')
{
if(strcmp("Light_led1",(char *)receive_str)==0) LED1=0;
else if(strcmp("Close_led1",(char *)receive_str)==0) LED1=1;
else if(strcmp("Open_beep",(char *)receive_str)==0) BEEP=1;
else if(strcmp("Close_beep",(char *)receive_str)==0) BEEP=0;
for(uart_byte_count=0;uart_byte_count<32;uart_byte_count++)receive_str[uart_byte_count]=0x00;
uart_byte_count=0;
}
else if((uart_byte_count>0)&&(uart_byte_count<=USART3_REC_NUM))
{
receive_str[uart_byte_count-1]=rec_data;
uart_byte_count++;
}
}
}
usart.h 代码
#ifndef __USART3_H
#define __USART3_H
#include "stdio.h"
#include "common.h"
#define USART3_REC_NUM 100
extern u8 uart_byte_count;
extern u8 receive_str[USART3_REC_NUM];
void uart3_init(u32 bound);
void uart3SendChars(u8 *str, u16 strlen);
#endif
main.c 代码
#include "usart3.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
uart3_init(9600);
KEY_Init();
LED_Init();
BEEP_Init();
LED0=0;
while(1)
{
key_scan(0);
if(keyup_data==KEY0_DATA)
{
printf("串口打印测试\r\n");
uart3SendChars("UART1 TEST\r\n",13);
LED0=!LED0;
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)