目录
串口,最大支持数据位长度为9bit。(DATA) <= 0x1FF 是断言检测数据位是否不大于9bit 0001 1111 1111
1.1.2、宏定义的参数检查函数( assert_param())
一、printf重定向简介
c语言中printf函数默认输出设备是显示器,如果实现在串口或者LCD上显示,必须重定义标准库函数里面调用的输出设备定义的相关函数。
如:使用printf输出到串口,需要将fputc里面的输出指向串口,这一过程称为重定向。
-
int fputc(int ch,FILE *p) // 函数默认的,在使用printf函数时自动调用
-
-
{
-
-
USART_SendDate(USART1,(u8)ch);
-
-
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
-
-
return ch;
-
-
}
-
// 此函数定义在stdio.h中,调用此函数需先导入stdio.h头文件
1.1、fputc函数解析
使用此函数需要导入stdio.h头文件
/**
* @brief Transmits single data through the USARTx peripheral. 通过USARTx外设传输单个数据
* @param USARTx: Select the USART or the UART peripheral. 选择USART或UART外设
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param Data: the data to transmit. 传输的数据
* @retval None
*/
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)/*
*/
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));/*#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
((PERIPH) == USART2) || \
((PERIPH) == USART3) || \
((PERIPH) == UART4) || \
((PERIPH) == UART5))USART1, USART2, USART3, UART4 or UART5
*/
assert_param(IS_USART_DATA(Data));
/*#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) // 串口,最大支持数据位长度为9bit。(DATA) <= 0x1FF 是断言检测数据位是否不大于9bit 0001 1111 1111
*/
/* Transmit Data */
USARTx->DR = (Data & (uint16_t)0x01FF); Data & 0000 0001 1111 1111
}
1.1.1、0x01FF 解析
十进制: 1*16*16 + 16*15 +15 = 511
0*16*16*16(16的3次方) + 1*16*16(16平方)+15*16(F的十进制位15,16的一次方)+15*16的0次方
二进制 0000 0001 1111 1111
左边的0000 可省略不改变其真值
八进制:
串口,最大支持数据位长度为9bit。(DATA) <= 0x1FF 是断言检测数据位是否不大于9bit 0001 1111 1111
1.1.2、宏定义的参数检查函数( assert_param())
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
assert参数宏用于函数的参数检查。
* @param expr: If expr is false, it calls assert_failed function which reports
* the name of the source file and the source line number of the call
* that failed. If expr is true, it returns no value.
expr:如果expr为false,它将调用assert失败的函数,该函数返回失败调用的源文件的名称和源行号。如果expr为真,则不返回任何值
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) // 调用失败
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line); // 调用此函数 显示调用失败的文件 与代码行
#else
#define assert_param(expr) ((void)0) // 调用成功
#endif /* USE_FULL_ASSERT */
1.1.3、USART数据寄存器(DR)
1.1.4、USART结构框图
1.2、USART_GetFlagStatus()函数
-
/**
-
* @brief Checks whether the specified USART flag is set or not.
-
检测设置的串口标志是否修改
-
* @param USARTx: Select the USART or the UART peripheral.
-
选择串口或串口外设
-
* This parameter can be one of the following values:
-
这个参数有以下值
-
* USART1, USART2, USART3, UART4 or UART5.
-
* @param USART_FLAG: specifies the flag to check.
-
检查设置标志
-
* This parameter can be one of the following values:
-
* @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
-
CTS 改变标志 (不适合于串口2和串口4)
-
* @arg USART_FLAG_LBD: LIN Break detection flag
-
Lin 中断检查标志
-
* @arg USART_FLAG_TXE: Transmit data register empty flag
-
发送寄存器 空的标志
-
* @arg USART_FLAG_TC: Transmission Complete flag
-
发送完成标志
-
* @arg USART_FLAG_RXNE: Receive data register not empty flag
-
接收数据寄存器不为空的标志
-
* @arg USART_FLAG_IDLE: Idle Line detection flag
-
空闲线路探测标志
-
* @arg USART_FLAG_ORE: OverRun Error flag
-
覆盖错误标志
-
* @arg USART_FLAG_NE: Noise Error flag
-
噪声错误标志
-
* @arg USART_FLAG_FE: Framing Error flag
-
框架错误标志
-
* @arg USART_FLAG_PE: Parity Error flag
-
奇偶校验错误标志
-
* @retval The new state of USART_FLAG (SET or RESET).
-
*/
-
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
-
{
-
FlagStatus bitstatus = RESET;
-
/* Check the parameters */
-
assert_param(IS_USART_ALL_PERIPH(USARTx));
-
assert_param(IS_USART_FLAG(USART_FLAG));
-
/* The CTS flag is not available for UART4 and UART5 */
-
if (USART_FLAG == USART_FLAG_CTS)
-
{
-
assert_param(IS_USART_123_PERIPH(USARTx));
-
}
-
-
if ((USARTx->SR & USART_FLAG) != (
uint16_t)RESET)
// SR状态寄存器
-
{
-
bitstatus = SET;
-
}
-
else
-
{
-
bitstatus = RESET;
-
}
-
return bitstatus;
-
}
USART1->SR&0X40 !=set or reset
- 串口1操作状态寄存器的第7位 置0或置1
- stm32中很多标记位,只能硬件置1,软件写1是没有效果的,但是可以软件写0。
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); // USART_FLAG_TXE 发送数据寄存器空标志位
1.3、USART_ClearFlag()
功能:清除 USARTx 的待处理标志位。
注意:
- PE (Parity error 奇偶错误 ), FE (Framing error帧错误), NE (Noise error噪声错误), ORE (OverRun error 溢出错误) and IDLE (Idle line detected 检测到空闲线路错误) flags are cleared by software sequence: a read operation to USART_SR register (USART_GetFlagStatus()) followed by a read operation to USART_DR register (USART_ReceiveData()). - RXNE flag can be also cleared by a read to the USART_DR register (USART_ReceiveData()).
- PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun error)和IDLE (IDLE line detected)标志被软件序列清除:一个读操作到USART SR寄存器(USART GetFlagStatus()),然后一个读操作到USART DR。
- TC标志也可以通过软件序列清除:一个到USART SR寄存器的读操作(USART GetFlagStatus()),接着一个到USART DR寄存器的写操作(USART SendData())。
- TXE标志仅通过写入USART DR寄存器来清除 (USART SendData())。
-
/**
-
* @brief Clears the USARTx's pending flags.
-
* @param USARTx: Select the USART or the UART peripheral.
-
* This parameter can be one of the following values:
-
* USART1, USART2, USART3, UART4 or UART5.
-
* @param USART_FLAG: specifies the flag to clear.
-
* This parameter can be any combination of the following values:
-
* @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
-
* @arg USART_FLAG_LBD: LIN Break detection flag.
-
* @arg USART_FLAG_TC: Transmission Complete flag.
-
* @arg USART_FLAG_RXNE: Receive data register not empty flag.
-
*
-
* @note
-
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
-
* error) and IDLE (Idle line detected) flags are cleared by software
-
* sequence: a read operation to USART_SR register (USART_GetFlagStatus())
-
* followed by a read operation to USART_DR register (USART_ReceiveData()).
-
* - RXNE flag can be also cleared by a read to the USART_DR register
-
* (USART_ReceiveData()).
-
* - TC flag can be also cleared by software sequence: a read operation to
-
* USART_SR register (USART_GetFlagStatus()) followed by a write operation
-
* to USART_DR register (USART_SendData()).
-
* - TXE flag is cleared only by a write to the USART_DR register
-
* (USART_SendData()).
-
* @retval None
-
*/
-
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
-
{
-
/* Check the parameters */
-
assert_param(IS_USART_ALL_PERIPH(USARTx));
-
assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
-
/* The CTS flag is not available for UART4 and UART5 */
-
if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)
-
{
-
assert_param(IS_USART_123_PERIPH(USARTx));
-
}
二、printf函数格式
printf("<格式化字符串>",<参量表>)
2.1、常用格式化规定字符:
- %d 按照十进制整形数打印
- %6d 按照十进制整形数打印,至少6个字符宽
- %f 按照浮点数打印
- %6f 按照浮点数打印,至少6个字符宽
- %.2f 按照浮点数打印,小数点后2位小数
- %6.2f 按照浮点数打印,至少6个字符宽,小数点后有2位小数
- %x 按照十六进制打印
- %c 打印字符
- %s 打印字符串
三、编写printf重定向
-
int fputc(int ch,FILE *p) //函数默认的,在使用printf函数时自动调用
-
{
-
USART_SendData(USART1,(u8)ch);
-
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
// USART_FLAG_TXE 发送数据寄存器空标志位
-
return ch;
-
}
-
#include "system.h"
-
#include "SysTick.h"
-
#include "led.h"
-
#include "usart.h"
-
-
-
/*******************************************************************************
-
* 函 数 名 : main
-
* 函数功能 : 主函数
-
* 输 入 : 无
-
* 输 出 : 无
-
*******************************************************************************/
-
int main()
-
{
-
u8 i=
0;
-
u16 data=
1234;
-
float fdata=
12.34;
-
char str[]=
"Hello World!";
-
SysTick_Init(
72);
-
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//中断优先级分组 分2组
-
LED_Init();
-
USART1_Init(
115200);
-
-
while(
1)
-
{
-
i++;
-
if(i%
50==
0)
-
{
-
LED1=!LED1;
-
-
printf(
"输出整型数data=%d\r\n",data);
-
printf(
"输出浮点型数fdata=%0.2f\r\n",fdata);
-
printf(
"输出十六进制数data=%X\r\n",data);
-
printf(
"输出八进制数data=%o\r\n",data);
-
printf(
"输出字符串str=%s\r\n",str);
-
-
}
-
delay_ms(
10);
// i每次自加的延时时间 500ms LED状态翻转一次 50*10ms = 500ms
-
}
-
}
usart .c
-
#include "usart.h"
-
-
int fputc(int ch,FILE *p) //函数默认的,在使用printf函数时自动调用
-
{
-
USART_SendData(USART1,(u8)ch);
-
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
// USART_FLAG_TXE 发送数据寄存器空标志位
-
return ch;
-
}
-
-
//串口1中断服务程序
-
//注意,读取USARTx->SR能避免莫名其妙的错误
-
u8 USART1_RX_BUF[USART1_REC_LEN];
//接收缓冲,最大USART_REC_LEN个字节.
-
//接收状态
-
//bit15, 接收完成标志
-
//bit14, 接收到0x0d
-
//bit13~0, 接收到的有效字节数目
-
u16 USART1_RX_STA=
0;
//接收状态标记
-
-
-
/*******************************************************************************
-
* 函 数 名 : USART1_Init
-
* 函数功能 : USART1初始化函数
-
* 输 入 : bound:波特率
-
* 输 出 : 无
-
*******************************************************************************/
-
void USART1_Init(u32 bound)
-
{
-
//GPIO端口设置
-
GPIO_InitTypeDef GPIO_InitStructure;
-
USART_InitTypeDef USART_InitStructure;
-
NVIC_InitTypeDef NVIC_InitStructure;
-
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
-
-
-
/* 配置GPIO的模式和IO口 */
-
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
//TX //串口输出PA9
-
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
-
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
//复用推挽输出
-
GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 初始化串口输入IO */
-
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
//RX //串口输入PA10
-
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
//模拟输入
-
GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 初始化GPIO */
-
-
-
//USART1 初始化设置
-
USART_InitStructure.USART_BaudRate = bound;
//波特率设置
-
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
//字长为8位数据格式
-
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);
//初始化串口1
-
-
USART_Cmd(USART1, ENABLE);
//使能串口1
-
-
USART_ClearFlag(USART1, USART_FLAG_TC);
-
-
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//开启相关中断
-
-
//Usart1 NVIC 配置
-
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//串口1中断通道
-
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=
3;
//抢占优先级3
-
NVIC_InitStructure.NVIC_IRQChannelSubPriority =
3;
//子优先级3
-
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ通道使能
-
NVIC_Init(&NVIC_InitStructure);
//根据指定的参数初始化VIC寄存器、
-
}
-
-
/*******************************************************************************
-
* 函 数 名 : USART1_IRQHandler
-
* 函数功能 : USART1中断函数
-
* 输 入 : 无
-
* 输 出 : 无
-
*******************************************************************************/
-
void USART1_IRQHandler(void) //串口1中断服务程序
-
{
-
u8 r;
-
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//接收中断
-
{
-
r =USART_ReceiveData(USART1);
//(USART1->DR); //读取接收到的数据
-
if((USART1_RX_STA&
0x8000)==
0)
//接收未完成
-
{
-
if(USART1_RX_STA&
0x4000)
//接收到了0x0d
-
{
-
if(r!=
0x0a)USART1_RX_STA=
0;
//接收错误,重新开始
-
else USART1_RX_STA|=
0x8000;
//接收完成了
-
}
-
else
//还没收到0X0D
-
{
-
if(r==
0x0d)USART1_RX_STA|=
0x4000;
-
else
-
{
-
USART1_RX_BUF[USART1_RX_STA&
0X3FFF]=r;
-
USART1_RX_STA++;
-
if(USART1_RX_STA>(USART1_REC_LEN
-1))USART1_RX_STA=
0;
//接收数据错误,重新开始接收
-
}
-
}
-
}
-
}
-
}
usart.h
-
#ifndef _usart_H
-
#define _usart_H
-
-
#include "system.h"
-
#include "stdio.h"
-
-
#define USART1_REC_LEN 200 //定义最大接收字节数 200
-
-
extern u8 USART1_RX_BUF[USART1_REC_LEN];
//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
-
extern u16 USART1_RX_STA;
//接收状态标记
-
-
-
void USART1_Init(u32 bound);
-
-
-
#endif
-
-
转载:https://blog.csdn.net/RONG_YAO/article/details/115746940