使用TIM3设计一个时间基准,通过USART1每3秒发送一次字符串"HELLO"。

使用TIM3设计一个时间基准,通过USART1每3秒发送一次字符串"HELLO"。该怎么写?


#include "stm32f1xx.h"

void TIM3_IRQHandler(void)
{
    if (TIM3->SR & TIM_SR_UIF)
    {
        TIM3->SR &= ~TIM_SR_UIF; // 清除更新事件标志位
        USART1->DR = 'H'; // 发送字符'H'
    }
}

void USART1_IRQHandler(void)
{
    if (USART1->SR & USART_SR_TXE)
    {
        USART1->DR = 'E'; // 发送字符'E'
    }
}

int main(void)
{
    // 启用相应外设的时钟,配置引脚等

    // 配置TIM3定时器
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // 启用TIM3时钟
    TIM3->PSC = 7199; // 设置预分频器,72MHz / (7199 + 1) = 10kHz
    TIM3->ARR = 29999; // 设置自动重载寄存器,10kHz * 3s = 30000个时钟周期
    TIM3->DIER |= TIM_DIER_UIE; // 启用更新事件中断
    NVIC_EnableIRQ(TIM3_IRQn); // 使能TIM3中断

    // 配置USART1串口
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // 启用USART1时钟
    USART1->BRR = 72000000 / 9600; // 设置波特率为9600
    USART1->CR1 |= USART_CR1_TE; // 使能发送
    USART1->CR1 |= USART_CR1_TXEIE; // 启用发送中断
    NVIC_EnableIRQ(USART1_IRQn); // 使能USART1中断

    // 启动定时器
    TIM3->CR1 |= TIM_CR1_CEN;

    while (1)
    {
        // 主循环中可以执行其他操作
    }
}

  • 以下回答由chatgpt基于相关博客总结生成:

    首先需要对TIM3模块进行配置,以每3秒触发一次中断。具体步骤如下:

    1. 配置时钟使能,使能TIM3的时钟源:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    1. 配置TIM3为定时器模式,设置预分频器和计数值:

    TIM_TimeBaseStructure.TIM_Prescaler = 72-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 9000-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    其中,预分频器和计数值的设置需要结合主频和需要的计数时间进行计算。

    1. 开启TIM3中断,并设置优先级:

    NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);

    1. 开启TIM3计数器:

    TIM_Cmd(TIM3, ENABLE);

    1. 编写中断处理函数,在每次中断触发时向USART1发送字符串“HELLO”:

    void TIM3_IRQHandler(void)
    {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    char * hello = "HELLO\n";
    while(hello)
    {
    USART_SendData(USART1,
    hello);
    hello++;
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    }
    }
    }

    其中,使用了USART1发送数据,根据题目要求需要设置波特率为115200,1位停止位,无校验位。USART1的配置也需要在代码中实现,具体步骤如下:

    1. 配置时钟使能,使能USART1的时钟源:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    1. 配置USART1工作模式,设置波特率、数据位、停止位和校验位:

    USART_InitStructure.USART_BaudRate = 115200; 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); USART_Cmd(USART1, ENABLE);

    1. 在main函数中,开启串口数据发送:

    char * start = "Start\n";
    while(start)
    {
    USART_SendData(USART1,
    start);
    start++;
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    }

    完整代码如下:

    include "stm32f10x.h"

    include "stdio.h"

    include "string.h"

    USART_InitTypeDef USART_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    int main(void)
    {
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 串口时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 定时器时钟使能

    USART_InitStructure.USART_BaudRate = 115200;  // 波特率为115200
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 数据位8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;  // 停止位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; // 置位RX和TX模式
    USART_Init(USART1, &USART_InitStructure);  // 初始化串口1
    USART_Cmd(USART1, ENABLE);  // 开启串口1
    
    TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;  // 预分频器为72,计数1秒,需要设置1000ms/1440=0.694ms计数一次
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // TIM向上计数模式
    TIM_TimeBaseStructure.TIM_Period = 2083-1;  // 计数2083次,即3秒
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分割1
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;  // 重复计数器
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  // 初始化TIM3
    
    // 定时器中断优先级0
    NVIC_InitTypeDef NVIC_InitStructure; 
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;    
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_Cmd(TIM3, ENABLE);  // 开启计数器
    
    char * start = "Start\n";
    while(*start)  
    {  
        USART_SendData(USART1, *start);  
        start++;  
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  
    }
    

    while(1);
    }

    void TIM3_IRQHandler(void)
    {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    char * hello = "HELLO\n";
    while(hello)
    {
    USART_SendData(USART1,
    hello);
    hello++;
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    }
    }
    }

    这样,就可以实现每3秒发送一次字符串“HELLO”到USART1上,达到题目要求。需要注意的是,在调试过程中可能会遇到一些问题,例如串口调试助手不显示字符串,此时可以调整波特率或尝试其他串口调试工具。