当前位置: 首页 > article >正文

Linux-Ubuntu之串口通信

Linux-Ubuntu之串口通信

  • 一,串口通信
    • 1.串口通信寄存器配置
    • 2.串口通信软件实现
      • ①手动波特率
      • ②自动波特率
      • ③主函数
  • 二,printf和scanf实现串口的输入显示

一,串口通信

1.串口通信寄存器配置

在这里插入图片描述

串口通信利用接口是这个TTL,下载程序用的是OTG,先连接OTG下载程序,然后再连接到TTL接口,利用SecureCRT观察串口通信,这个Secure就像是板子的串口显示屏,能观察发送和接收的信息。
对寄存器配置,先设置UART1的复用属性和电气属性,然后关闭串口对内部的奇偶校验、停止位、起始位以及波特率进行配置,波特率一般选择115200,最后使能串口,在主函数里面调用相应函数,实现显示。

2.串口通信软件实现

#include "dsp_uart.h"
#include "dsp_gpio.h"
#include "dsp_uart.h"
#include "dsp_gpio.h"

void uart_init(void)
{
    /*初始化GPIO即UART1的复用以及电器属性*/
    uart_IO_init();

    /*初始化:波特率等信号*/
    uart_disable(UART1); //关闭UART1
    uart_soft(UART1);//复位UART1


    /*配置UART1*/
    UART1->UCR1 = 0;
    UART1->UCR1 &= ~(1<<14);


    /*UART1具体配置,数据位八位。奇偶校验无,停止位1位*/
    UART1->UCR2 = 0;  
    UART1->UCR2 |=(1<<1)|(1<<2)|(1<<5)|(1<<14);
    UART1->UCR3 |=(1<<2);

    /*设置波特率 115200*/
    UART1->UFCR &=~(7<<7);
    UART1->UFCR = (5<<7);
    UART1->UBIR = 71;
    UART1->UBMR =3124;
    /*使能串口*/
    uart_enable(UART1);
}


/*关闭串口*/
void uart_disable(UART_Type *base)
{
    base->UCR1 &= ~(1<<0);
}
/*打开串口*/
void uart_enable(UART_Type *base)
{
    base->UCR1 |= (1<<0);
}
/*复位UART*/
void uart_soft(UART_Type *base)
{
    base->UCR2 &= ~(1<<0);
    while((base->UCR2 & 0x01)==0);
}
void uart_IO_init(void) //复用功能和电器属性
{
    //TX
    IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX,0);//设置为复用功能
    IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,0x10b0);//电器属性
    
    //RX
    IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX,0);//设置为复用功能
    IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,0x10b0);//电器属性
}

/*发送一个字符*/
void putc(unsigned char c)
{
    while(((UART1->USR2 >>3)&0X01) == 0);//判断上次发送完成
    UART1->UTXD = c&0xff;
}

/*接收字符*/
unsigned char getc(void)
{
    while((UART1->USR2 &0X01)==0);//判断有数据可以接收
    return UART1->URXD;    
}
/* 发送一串字符*/
void puts(char *str)
{
    char *p = str;
    while(*p)
    {
        putc(*p++);
    }
}
void uart_setbaudrate(UART_Type *base, unsigned int baudrate, unsigned int srcclock_hz)
{
    uint32_t numerator = 0u;		//鍒嗗瓙
    uint32_t denominator = 0U;		//鍒嗘瘝
    uint32_t divisor = 0U;
    uint32_t refFreqDiv = 0U;
    uint32_t divider = 1U;
    uint64_t baudDiff = 0U;
    uint64_t tempNumerator = 0U;
    uint32_t tempDenominator = 0u;

    /* get the approximately maximum divisor */
    numerator = srcclock_hz;
    denominator = baudrate << 4;
    divisor = 1;

    while (denominator != 0)
    {
        divisor = denominator;
        denominator = numerator % denominator;
        numerator = divisor;
    }

    numerator = srcclock_hz / divisor;
    denominator = (baudrate << 4) / divisor;

    /* numerator ranges from 1 ~ 7 * 64k */
    /* denominator ranges from 1 ~ 64k */
    if ((numerator > (UART_UBIR_INC_MASK * 7)) || (denominator > UART_UBIR_INC_MASK))
    {
        uint32_t m = (numerator - 1) / (UART_UBIR_INC_MASK * 7) + 1;
        uint32_t n = (denominator - 1) / UART_UBIR_INC_MASK + 1;
        uint32_t max = m > n ? m : n;
        numerator /= max;
        denominator /= max;
        if (0 == numerator)
        {
            numerator = 1;
        }
        if (0 == denominator)
        {
            denominator = 1;
        }
    }
    divider = (numerator - 1) / UART_UBIR_INC_MASK + 1;

    switch (divider)
    {
        case 1:
            refFreqDiv = 0x05;
            break;
        case 2:
            refFreqDiv = 0x04;
            break;
        case 3:
            refFreqDiv = 0x03;
            break;
        case 4:
            refFreqDiv = 0x02;
            break;
        case 5:
            refFreqDiv = 0x01;
            break;
        case 6:
            refFreqDiv = 0x00;
            break;
        case 7:
            refFreqDiv = 0x06;
            break;
        default:
            refFreqDiv = 0x05;
            break;
    }
    /* Compare the difference between baudRate_Bps and calculated baud rate.
     * Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)).
     * baudDiff = (srcClock_Hz/divider)/( 16 * ((numerator / divider)/ denominator).
     */
    tempNumerator = srcclock_hz;
    tempDenominator = (numerator << 4);
    divisor = 1;
    /* get the approximately maximum divisor */
    while (tempDenominator != 0)
    {
        divisor = tempDenominator;
        tempDenominator = tempNumerator % tempDenominator;
        tempNumerator = divisor;
    }
    tempNumerator = srcclock_hz / divisor;
    tempDenominator = (numerator << 4) / divisor;
    baudDiff = (tempNumerator * denominator) / tempDenominator;
    baudDiff = (baudDiff >= baudrate) ? (baudDiff - baudrate) : (baudrate - baudDiff);

    if (baudDiff < (baudrate / 100) * 3)
    {
        base->UFCR &= ~UART_UFCR_RFDIV_MASK;
        base->UFCR |= UART_UFCR_RFDIV(refFreqDiv);
        base->UBIR = UART_UBIR_INC(denominator - 1); //瑕佸厛鍐橴BIR瀵勫瓨鍣紝鐒跺悗鍦ㄥ啓UBMR瀵勫瓨鍣紝3592椤� 
        base->UBMR = UART_UBMR_MOD(numerator / divider - 1);
        //base->ONEMS = UART_ONEMS_ONEMS(srcclock_hz / (1000 * divider));
    }

}
void raise(int sig_nr) 
{

}

①手动波特率

    /*设置波特率 115200*/
    UART1->UFCR &=~(7<<7);
    UART1->UFCR = (5<<7);
    UART1->UBIR = 71;
    UART1->UBMR =3124;

②自动波特率

利用函数uart_setbaudrate进行设置,串口引入的时钟为80MHZ。

uart_setbaudrate(UART1,115200,80000000);

③主函数

int main(void)

{

    unsigned char kkkk=0;

    int_init();//中断初始化

    imx6u_clkinit();//时钟初始化

    key_init();//按键初始化

    clk_enable();//时钟初始化

    uart_init();//串口初始化

    beep_init();//凤鸣器初始化

    led_init();//led初始化

    

    while(1)

    {

        led_mode(ON);

        puts("请输入字符:");

        kkkk=getc();

        putc(kkkk);

        puts("\r\n");



        puts("您输入的字符为:");

        putc(kkkk);

        puts("\r\n");

        led_mode(OFF);

        

    }

    return 0;    

}

二,printf和scanf实现串口的输入显示

添加include文件夹,然后将Makefile文件进行对应修改,添加相应路径,在主函数中调用printf和scanf的stdio头文件,在软件上输入数值,实现串口的输入发送,终于感觉能进行交互了。
主函数:

#include "main.h"

#include "dsp_clk.h"

#include "dsp_led.h"

#include "dsp_delay.h"

#include "beep.h"

#include "dsp_key.h"

#include "dsp_int.h"

#include "dsp_exti.h"

#include "dsp_epit.h"

#include "dsp_uart.h"

#include "stdio.h"

int main(void)

{

    int a,b;

    unsigned char kkkk=0;

    int_init();//中断初始化

    imx6u_clkinit();//时钟初始化

    key_init();//按键初始化

    clk_enable();//时钟初始化

    uart_init();//串口初始化

    beep_init();//凤鸣器初始化

    led_init();//led初始化

    

    while(1)

    {

        printf("输入两个整数:\r\n");

        scanf("%d %d",&a,&b);

        printf("%d + %d = %d \r\n",a,b,a+b);

        led_mode(!kkkk);

        kkkk=!kkkk;





        // led_mode(ON);

        // puts("请输入字符:");

        // kkkk=getc();

        // putc(kkkk);

        // puts("\r\n");



        // puts("您输入的字符为:");

        // putc(kkkk);

        // puts("\r\n");

        // led_mode(OFF);

        

    }

    return 0;    

}

最终实现界面:
在这里插入图片描述
关于这个软件的安装设置:https://blog.csdn.net/qq_52089863/article/details/132722671


http://www.kler.cn/a/454889.html

相关文章:

  • VUE3+VITE简单的跨域代理配置
  • Github优质项目推荐(第九期)
  • 新品:SA628F39大功率全双工音频传输模块
  • Stream API 的设计融合了多个经典设计模式
  • Markdown语法字体字号讲解
  • Thinkphp 使用workerman消息实现消息推送完整示例
  • ChatGPT助力数据可视化与数据分析效率的提升(二)
  • lua debug相关方法详解
  • leetcode82:删除链表中的重复元素II
  • 【蓝桥杯】走迷宫
  • 题海拾贝:蓝桥杯 2020 省AB 乘法表
  • 免费资源网站
  • ANSYS EMC Plus:谐振腔中的天线
  • Markdown语法字体字号讲解
  • git revert
  • 【C#】WPF设置Separator为垂直方向
  • (icml2024)SLAattention,基于原文时序模型进行改进
  • 【AIGC篇】AIGC 引擎:点燃创作自动化的未来之火
  • 项目报 OutOfMemoryError 、GC overhead limit exceeded 问题排查以及解决思路实战
  • LeetCode 热题 100_二叉树的中序遍历(36_94_简单_C++)(二叉树;递归(中序遍历);迭代)
  • 如何在 Ubuntu 22.04 上安装 Ansible 教程
  • OpenStack系列第三篇:CentOS7 上部署 OpenStack(Train版)集群教程 Ⅲ Nova Neutron 服务部署
  • Go语言反射从入门到进阶
  • js 生成二维码(qrcodejs2-fix)
  • Intel AMD Hygon CPU缓存
  • 分阶段总结:建材制造业“数字化转型”总体架构与实现路径