STM32外部中断与串口通信不能一起运行,急!

STM32外部中断与串口通信不能一起运行,急!,第1张

int UART_WriteBuf(u8 byCom, u8 pBuf, u16 Len)

{

int i = 0;;

if(Len == 0)

return 0;

switch(byCom)

{

case 1 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_ITConfig(USART1, USART_IT_TC, ENABLE);

USART_SendData(USART1, pBuf);

break;

case 2 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_ITConfig(USART2, USART_IT_TC, ENABLE);

USART_SendData(USART2, pBuf);

break;

case 3 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_SendData(USART3, pBuf);

USART_ITConfig(USART3, USART_IT_TXE, ENABLE);

break;

}

return Len;

}

void USART3_IRQHandler(void)

{

int j = 0;

if(USART_GetITStatus(USART3,USART_IT_RXNE))

{

USART_ClearITPendingBit(USART3,USART_IT_RXNE);

Uart_datarec_buff[Uart_datarec_len] = USART_ReceiveData(USART3);

Uart_datarec_len ++;

if(Uart_datarec_len >= UART_DATA_SIZE) //防止数组越界

Uart_datarec_len = UART_DATA_SIZE - 1;

}

else if(USART_GetITStatus(USART3,USART_IT_TXE))

{

USART_ClearITPendingBit(USART3,USART_IT_TXE);

USART_ClearFlag(USART3,USART_FLAG_TC);

if(Uart_dataj <= Uart_datasend_len)

{

// printf("TC = %d,TXE = %d,FLAG_TC = %d\n\r",USART_GetITStatus(USART3,USART_IT_TC),USART_GetITStatus(USART3,USART_IT_TXE),USART_GetFlagStatus (USART3,USART_FLAG_TC));

USART_SendData(USART3,Uart_datasend_buff[Uart_dataj]);

while(j < 800)

j++;

// printf("interrupt:j = %d,len = %d,buff[%d] = %c,buff = %s\n\n\r",Uart_dataj,Uart_datalen,Uart_dataj,Uart_databuff[Uart_dataj],Uart_databuff);

}

else

USART_ITConfig(USART3, USART_IT_TXE, DISABLE);

Uart_dataj++;

}

}

串口时钟使能,GPIO 时钟使能

2) 串口复位

3) GPIO 端口模式设置

4) 串口参数初始化

5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)

6) 使能串口

7) 编写中断处理函数

串口时钟使能。串口是挂载在 APB2 下面的外设,所以使能函数为:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);

2串口复位。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置

这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外

设的 *** 作。复位的是在函数 USART_DeInit()中完成:

void USART_DeInit(USART_TypeDef USARTx);//串口复位

比如我们要复位串口 1,方法为:

USART_DeInit(USART1); //复位串口 1

3串口参数初始化。串口初始化是通过 USART_Init()函数实现的,

void USART_Init(USART_TypeDef USARTx, USART_InitTypeDef USART_InitStruct);

这个函数的第一个入口参数是指定初始化的串口标号,这里选择 USART1。

第二个入口参数是一个 USART_InitTypeDef 类型的结构体指针,这个结构体指针的成员变量用

来设置串口的一些参数。一般的实现格式为:

USART_InitStructureUSART_BaudRate = bound; //一般设置为 9600;

USART_InitStructureUSART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式

USART_InitStructureUSART_StopBits = USART_StopBits_1; //一个停止位

USART_InitStructureUSART_Parity = USART_Parity_No; //无奇偶校验位

USART_InitStructureUSART_HardwareFlowControl

= USART_HardwareFlowControl_None; //无硬件数据流控制

USART_InitStructureUSART_Mode = USART_Mode_Rx | USART_Mode_Tx;

//收发模式

USART_Init(USART1, &USART_InitStructure); //初始化串口

从上面的初始化格式可以看出初始化需要设置的参数为:波特率,字长,停止位,奇偶校验位,

硬件数据流控制,模式(收,发)。我们可以根据需要设置这些参数。

4数据发送与接收。STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是

一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收

到数据的时候,也是存在该寄存器内。

STM32 库函数 *** 作 USART_DR 寄存器发送数据的函数是:

void USART_SendData(USART_TypeDef USARTx, uint16_t Data);

通过该函数向串口寄存器 USART_DR 写入一个数据。

STM32 库函数 *** 作 USART_DR 寄存器读取串口接收到的数据的函数是:

uint16_t USART_ReceiveData(USART_TypeDef USARTx);

通过该函数可以读取串口接受到的数据。

5串口状态。串口的状态可以通过状态寄存器 USART_SR 读取。USART_SR 的各位描述如

这里我们关注一下两个位,第 5、6 位 RXNE 和 TC。

RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并

且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将

该位清零,也可以向该位写 0,直接清除。

TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如

果设置了这个位的中断,则会产生中断。该位也有两种清零方式:1)读 USART_SR,写

USART_DR。2)直接向该位写 0。

状态寄存器的其他位我们这里就不做过多讲解,大家需要可以查看中文参考手册。

在我们固件库函数里面,读取串口状态的函数是:

FlagStatus USART_GetFlagStatus(USART_TypeDef USARTx, uint16_t USART_FLAG);

这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如上面讲解的

RXNE(读数据寄存器非空)以及 TC(发送完成)。例如我们要判断读寄存器是否非空(RXNE), ***

作库函数的方法是:

USART_GetFlagStatus(USART1, USART_FLAG_RXNE);

我们要判断发送是否完成(TC), *** 作库函数的方法是:

USART_GetFlagStatus(USART1, USART_FLAG_TC);

这些标识号在 MDK 里面是通过宏定义定义的:

你的串口是通过查询方式来发送数据的,为什么要打开收发收发中断呢?关闭收发中断。

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //初始化发送中断使能

USART_ITConfig(USART1,USART_IT_TXE,ENABLE); //初始化接收中断使能

改为:

USART_ITConfig(USART1,USART_IT_RXNE,DISABLE); //初始化发送中断使能

USART_ITConfig(USART1,USART_IT_TXE,DISABLE); //初始化接收中断使能

  USART是通用(U)同步(S)异步(A)收(R)发(T)器。

  STM32F103VGT6上有3个USART和2个UART。

  同步与异步的区别是:

  通信时是否需要对外提供时钟输出。

官方的usart头文件为:

stm32f10x_usarth

  USART有2个结构体:

与USART运行相关:

USART_InitTypeDef

成员有:

  // 波特率

  USART_BaudRate

  // 字长

  USART_WordLength

  // 停止位

  USART_StopBits

  // 校验位

  USART_Parity

  // USART模式

  USART_Mode

  // 硬件流控制

  USART_HardwareFlowControl

与该成员相关的宏定义有:

  USART_WordLength

    USART_WordLength_8b

    USART_WordLength_9b

  USART_Stop_Bits

    USART_StopBits_1

    USART_StopBits_0_5

    USART_StopBits_2

    USART_StopBits_1_5

  USART_Parity

    USART_Parity_No

    USART_Parity_Even

    USART_Parity_Odd

  USART_Mode

    USART_Mode_Rx

    USART_Mode_Tx

  USART_Hardware_Flow_Control

    USART_HardwareFlowControl_None

    USART_HardwareFlowControl_RTS

    USART_HardwareFlowControl_CTS

    USART_HardwareFlowControl_RTS_CTS

另一个结构体与同步通信相关。

USART_ClockInitTypeDef

成员有:

  USART_Clock // 时钟使能控制

  USART_CPOL // 时钟极性控制

  USART_CPHA // 时钟相位控制

  USART_LastBit // 最尾位时钟脉冲控制

该类成员相关的宏定义

  USART_Clock

    USART_Clock_Disable

    USART_Clock_Enable

  USART_CPOL

    USART_CPOL_Low

    USART_CPOL_High

  USART_CPHA

    USART_CPHA_1Edge

    USART_CPHA_2Edge

  USART_LastBit

    USART_LastBit_Disable

    USART_LastBit_Enable

// 使用输入的配置信息USART_InitStruct对于USARTx,进行初始化

USART_Init(USART_TypeDef USARTx,USART_InitTypeDef USART_InitStruct);

// 使能串口接收中断

USART_ITConfig(USART_TypeDef USARTx,uint16_t USART_IT, FunctionalState NewState);

// 使能串口USARTx,NewState=>(ENABLE/DISABLE)

USART_Cmd(USART_TypeDef USARTx, FunctionalState NewState);

// 在 USARTx 中发送数据Data

USART_SendData(USART_TypeDef USARTx, uint16_t Data);

// 确认串口USARTx的一些标志位是 set状态还是reset状态

USART_GetFlagStatus(USART_TypeDef USARTx, uint16_t USART_FLAG);

  USART_FLAG有:

    USART_FLAG_CTS

    USART_FLAG_LBD

    USART_FLAG_TXE 数据发送寄存器是否为空

    USART_FLAG_TC 数据发送完成标志

    USART_FLAG_RXNE 数据接收寄存器是否不为空

    USART_FLAG_IDLE

    USART_FLAG_ORE

    USART_FLAG_NE

    USART_FLAG_FE

    USART_FLAG_PE

// 类似USART_GetFlagStatus,但是专门用来判断中断时间的状态

USART_GetITStatus(USART_TypeDef USARTx, uint16_t USART_IT);

  USART_IT有:

    USART_IT_CTS

    USART_IT_LBD

    USART_IT_TXE

    USART_IT_TC

    USART_IT_RXNE 数据接收寄存器是否不为空

    USART_IT_IDLE

    USART_IT_ORE_RX

    USART_IT_ORE_ER

    USART_IT_NE

    USART_IT_FE

    USART_IT_PE

// 获取USARTx接收到的数据

USART_ReceiveData(USART_TypeDef USARTx);

  如果想使用printf来打印调试信息,则生成项目时候需要如下勾选:

  会生成两个文件:

    syscallsc和tiny_printfc

修改 syscallsc 中的 _write 函数如下:

并在开头加入:

这样就能使用printf了。

程序中自己编写“bsp_usartc”,“bsp_usarth”,“mainc”这三个文件:

“bsp_usartc”文件如下:

“bsp_usarth”文件如下:

主函数如下:

TrueSTUDIO自带串口通信工具:

由此可见 \r\n 才是真正的回车。

如果你仔细研究USART_Init()函数,你会发现,这程序在配置波特率时会读取RCC有关的寄存器来计算当前CPU实际的工作频率是多少,然后计算参数来实现你需要的波特率——就是说不管你把单片机设置为什么样的工作频率,这函数都能让串口以你要求的波特率工作。当然如果你把原来8M的晶振换掉了,那你就需要修改系统中的一个定义:在文件stm32f10xh中的定义HSE_Value,这参数定义了单片机使用外部晶振或时钟源的频率,一般就是8000000,即使用的8MHz晶振。如果你的STM32用了什么73728、110592或者25MHz晶振时,你就要修改HSE_Value定义的值,这样保证串口通信波特率正确。

TXE由硬件来管理。当 if(USART_GetITStatus(USART1,USART_IT_TXE) != RESET) 时表明:

数据已经从TDR 移送到移位寄存器,数据发送已经开始;TDR 寄存器被清空;下一个数据可以被写进USART_DR 寄存器而不会覆盖先前的数据,如USART_SendData(USART1, Framewaitsndbuf[ptrshowfra][ptrusart1]),如果此时USART 正在发送数据,对USART_DR 寄存器的写 *** 作把数据存进TDR 寄存器,并在当前传输结束时把该数据复制进移位寄存器。如果此时USART 没有在发送数据,处于空闲状态,对USART_DR 寄存器的写 *** 作直接把数据放进移位寄存器,数据传输开始,TXE 位立即被置起。通常串口中断发送用这种方式。

当一帧发送完成时(停止位发送后),TC 位被置起,并且如果USART_CR1 寄存器中的

TCIE 位被置起时,中断产生。先读一下USART_SR 寄存器,再写一下USART_DR 寄存器,可以完成对TC 位的清零。

以上就是关于STM32的串口中断中的变量拿出来用全部的内容,包括:STM32的串口中断中的变量拿出来用、STM32串口通信编程的7大步骤有哪些、STM32外部中断与串口通信不能一起运行,急!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/8822818.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-22
下一篇2023-04-22

发表评论

登录后才能评论

评论列表(0条)

    保存