STM32使用串口接收变长数据(利用空闲中断)---寄存器版

#include "usart.h"

/* 初始化串口1 */
void usart1_init(void)
{
    /* 1 开启时钟  1<<14 = 0x4000*/
    /* 1.1 开启 usart1 时钟 */
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    /* 1.2 开启 GPIOA 时钟 */
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    /* 2 配置引脚: PA9(Tx)和PA10(Rx) */
    /* 2.1 PA9 配置为推挽输出 mode=11 cnf=10*/
    GPIOA->CRH |= (GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1);
    /* 2.2 PA10 配置为浮空输入 */
    GPIOA->CRH |= GPIO_CRH_CNF10_0;

    /* 3 配置波特率为:115200*/
    USART1->BRR = 0x271;

    /* 4 使能usart1的发送和接收 */
    USART1->CR1 |= (USART_CR1_TE | USART_CR1_RE);

    /* 5 使能usart1接收中断  */
    USART1->CR1 |= USART_CR1_RXNEIE;

    /* 6. 使能空闲中断 */
    USART1->CR1 |= USART_CR1_IDLEIE; /* 空闲中断使能 */

    /* 7. 设置NVIC */
    NVIC_SetPriorityGrouping(4);
    NVIC_SetPriority(USART1_IRQn, 2);
    NVIC_EnableIRQ(USART1_IRQn);

    /* 8.使能usart1 */
    USART1->CR1 |= USART_CR1_UE;
}
/*
    通过串口1发送数据:
    参数1:要发送的数据
    参数2:要发送的数据的长度

 */
void send_string(uint8_t *str, uint32_t len)
{
    uint32_t i;
    for (i = 0; i < len; i++)
    {
        send_char(str[i]);
    }
}

/*
    向串口1发送一个字符
*/
void send_char(uint8_t c)
{
    /* 等待发送缓冲区为空。 SR_TXE为1表示已经移到移位寄存器, 0表示还没有 */
    while ((USART1->SR & USART_SR_TXE) == 0)
    {
    }
    /* 把要发送的数据写入到数据寄存器 */
    USART1->DR = c;
}
/* 中断服务函数: 利用空闲中断接收变长数据 */
uint8_t buff[1000]; /* 缓存就收到的字节数据 */
uint8_t count = 0; /* 对接收到的字节计数 */
void USART1_IRQHandler(void)
{
    if (USART1->SR & USART_SR_RXNE) // 接收到一个字节
    {
        uint8_t c = USART1->DR & 0xff;
        buff[count] = c; // 把数据存入到缓冲区
        count++; /* 计数加1 */
    }
    else if (USART1->SR & USART_SR_IDLE) // 产生了空闲中断
    {
        /* 先清除空闲中断位: 先读SR,再读DR */
        USART1->SR;
        USART1->DR;
        send_string(buff, count); /* 发送给接收端 */
        count = 0; /* 计数清除,用于下一个变长数据的接收 */
    }
}

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用空闲中断寄存器本实现stm32串口接收数据的示例代码: ```c #include "stm32f10x.h" #define USART1_DR_Base 0x40013804 // USART1 Data register base address void USART1_IRQHandler(void) { if (USART1->SR & USART_SR_IDLE) // check if IDLE flag is set { volatile uint32_t tmp; // create a temporary variable to store data tmp = USART1->SR; // read status register tmp = USART1->DR; // read data register (void)tmp; // avoid warning for unused variable } } int main(void) { // enable USART1 clock RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // configure USART1 pins RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // enable GPIOA clock GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9); // clear PA9 configuration GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0; // set PA9 as alternate function output push-pull GPIOA->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_MODE10); // clear PA10 configuration GPIOA->CRH |= GPIO_CRH_CNF10_0; // set PA10 as floating input // configure USART1 USART1->BRR = 0x271; // set baud rate to 115200 USART1->CR1 = USART_CR1_RE | USART_CR1_IDLEIE | USART_CR1_RXNEIE | USART_CR1_UE; // enable receiver, IDLE interrupt, RXNE interrupt, and USART1 // enable USART1 interrupt NVIC_EnableIRQ(USART1_IRQn); while (1) { // do something else } } ``` 在上面的代码中,我们首先定义了USART1的数据寄存器地址,然后实现了一个USART1的中断处理函数。在中断处理函数中,我们首先检查IDLE标志是否被设置,如果设置了,就读取状态寄存器数据寄存器,然后清除IDLE标志。在主函数中,我们首先使能了USART1的时钟,并配置了USART1的引脚。然后我们设置了波特率为115200,使能了接收器、IDLE中断、接收寄存器非空中断和USART1。最后,我们使能了USART1的中断,并进入了一个无限循环。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值