• STM32G0开发笔记-Platformio+libopencm3-串口中断


    【原文】https://makerinchina.cn/article_dfa2d9ee8875.html


    title: STM32G0开发笔记-Platformio+libopencm3-串口中断
    tags:

    • STM32
    • MCU
    • STM32G070
    • libopencm3
    • MonkeyPi
      categories:
      • STM32
        date: 2022-9-5 09:33:05

    使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为串口中断的使用。

    1 新建项目
    • 建立uart项目

    在PIO的Home页面新建项目,项目名称uart,选择开发板为上一次建立的自定义开发板型号 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;

    • 项目建立完成后在src目录下新建main.c主程序文件;
    • 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:
    upload_protocol = cmsis-dap
    debug_tool = cmsis-dap
    
    2 编写程序
    • 时钟设置
    //system clock
    rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
    
    //uart pin
    rcc_periph_clock_enable(RCC_USART1);
    rcc_periph_clock_enable(RCC_GPIOB);
    

    先设置系统时钟为内部PLL生成64MHz,然后设置串口外设和串口引脚外设的时钟;

    • 引脚复用功能设置
    gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);
    gpio_set_af(GPIOB,GPIO_AF0,GPIO6|GPIO7);
    

    根据芯片datasheet文档,使用USART1其引脚为PA9\PA10,复用功能AF1为串口功能;

    • 串口设置
    usart_set_baudrate(USART1,115200);
    usart_set_databits(USART1,8);
    usart_set_stopbits(USART1,USART_STOPBITS_1);
    usart_set_parity(USART1,USART_PARITY_NONE);
    usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
    usart_set_mode(USART1,USART_MODE_TX_RX);
    
    //uart isr
    nvic_enable_irq(NVIC_USART1_IRQ);
    
    usart_enable(USART1);
    
    usart_enable_rx_interrupt(USART1);
    

    先设置串口波特率、数据位数、停止位、校验、流控等设置,再开启串口中断,使能串口和其接收中断;

    • 串口发送
    char buff[32] = "hello, makerinchina.cn\n";
    for(int i=0; i<strlen(buff); i++){
        usart_send_blocking(USART1, buff[i]);
    }
    

    发送直接使用 usart_send_blocking 接口发送一个字节数据;

    • 串口接收
    /**
     * @brief uart1 isr function
     * 
     */
    void usart1_isr(void)
    {
        //receive interrupt
    	if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
    	    ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {
    
            if(recv_index < BUFF_SIZE){
                recv_buff[recv_index++] = usart_recv(USART1);
            }else{
                recv_index = 0;
            }
    	}
    }
    

    串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来:

    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    volatile uint8_t recv_index = 0;
    volatile uint8_t send_index = 0;
    
    #define BUFF_SIZE 64
    uint8_t recv_buff[BUFF_SIZE] = {0};
    
    int main(void)
    {
        ...
            
        while (1)
        {
    
            if(recv_index != send_index){ 
    
                if(send_index < BUFF_SIZE){
                    usart_send_blocking(USART1, recv_buff[send_index++]);
                }else{
                    send_index = 0;
                }
            }
    
        }
    }
    

    注:recv_index、send_index需要声明为volatile类型;

    3 烧写测试

    点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样;

    4 printf使用

    如果要使用printf功能,需要定义如下函数,将串口重定向:

    /*
     * Called by libc stdio fwrite functions
     */
    int
    _write(int fd, char *ptr, int len)
    {
    	int i = 0;
    
    	/*
    	 * Write "len" of char from "ptr" to file id "fd"
    	 * Return number of char written.
    	 *
    	 * Only work for STDOUT, STDIN, and STDERR
    	 */
    	if (fd > 2) {
    		return -1;
    	}
    	while (*ptr && (i < len)) {
    		usart_send_blocking(USART1, *ptr);
    		if (*ptr == '\n') {
    			usart_send_blocking(USART1, '\r');
    		}
    		i++;
    		ptr++;
    	}
    	return i;
    }
    

    现在就可以直接使用printf函数进行打印显示到串口设备;

  • 相关阅读:
    Blockchain for Internet of Energy management: Review, solutions, and challenges
    网站都变成灰色,其实几行代码就搞定了!
    【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )
    改变this指向
    C# 后台处理 webp图片
    Java_代码块/单例设计模式(饿汉式 / 懒汉式)
    SpringSecurity 认证详解
    [iptables] 基于iptables实现的跨网络通信
    49_Iterator迭代器
    基于javaweb的在线美食网站系统(java+ssm+jsp+mysql)
  • 原文地址:https://blog.csdn.net/roctwo/article/details/127099306