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); //关闭UART1uart_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) //复用功能和电器属性
{//TXIOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX,0);//设置为复用功能IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,0x10b0);//电器属性//RXIOMUXC_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