打印
[学习资料]

PIC单片机之EUSART串行通信接口

[复制链接]
849|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kxsi|  楼主 | 2019-7-25 11:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
  PIC 单片机的EUSART是一种串行通信接口,我们可以利用他让不同设备之间传输数据,我们来讲讲我们最常用的串行异步接收和发送。

管脚

  串行异步接收和发送。如果只要两个引脚,一个是接收RX 一个是发送TX。

数据格式

   我们先来讲讲TX是如何发送出数据的,数据格式具体是什么样的。





     如果我们要向其他设备发送个大写字母A。将是什么样的呢。"A"这个字母对应的ASCII码是65,对应的八位二进制数则是 01000100。TX就将对应的二进制码发送出去。

     发送时用高电平来代表1,用低电平代表0. 那不发送数据的时候管脚就一直为高电平。


使用特权

评论回复
沙发
kxsi|  楼主 | 2019-7-25 11:27 | 只看该作者
启动位和停止位

      怎么区分现在是在发送数据还是在常态呢?所以在每次发送一个字节的数据之前TX脚都会先输出一小段的低电平。来告诉对方,我要发送数据了这一小段低电平便是启动位(起始位)。

    如果我们发送的不仅仅只有一个字节,而是好几个字节,两个数据之间总要有个间隔吧!要不然分不清谁跟谁。所以每发送完一个字节的数据,TX脚就会输出一小段的高电平这便是停止位。

  波特率

      在数据发送中每个位的时间都要事先定好,而且发送和接收的双方都必须事先知道并设置好。那这个时间是怎么确定的呢?这就牵扯的一个东西波特率。在这里波特率=比特率。比特率也就是 一秒钟发送多少位的数据。如果要一秒钟发送为9600个位,我们将波特率设置为9600。1/9600约等于0.0001s 也就是每个位的发送时间。


小端发送

    如果 发送大写字母“ A ”也就是发送二进制数 “01000100”,串行通信是从低位开始发送。

下图为字母”A”数据发送的时序图.



使用特权

评论回复
板凳
kxsi|  楼主 | 2019-7-25 11:27 | 只看该作者
实例:我们可以利用PC机的串口和单片机进行异步串行通信,单片机接收到什么样的数据,就在给PC机发送数据,波特率为115200。不过单片机输出的TTL信号,需TTL转232.PC机才能接收。有关这方面的硬件设计网上很多故不赘述。

在官方的数据手册有对应配置步骤,不过我将根据我的实例来讲解其实也是大同小异。

1,配置端口

   1.1配置备用功能

      我们可以看单片机的引脚图,第13和第6脚都标有TX说明这两个引脚是可以作为EUSART数据输出。第12和第5脚都标有RX说明这两个引脚是都可以作为EUSART数据输入的。但是同时只有一个引脚作为RX或者TX。不可以同时有两个RX或TX。RX与TX的选择是通过APFCON。我们这里选择13脚作为TX,选择12脚作为RX.配置如下:

       APFCONbits.TXCKSEL = 1;//RA0

       APFCONbits.RXDTSEL = 1;//RA1




使用特权

评论回复
地板
kxsi|  楼主 | 2019-7-25 11:27 | 只看该作者
1.2将RX脚配置位数字输入。

      我们可以看第12脚上标有AN1,说明该引脚还带有模拟输入的功能。所以我们必须将其设置为数字输入。配置如下:

      TRISA1 = 1;//RA1 RX input

      ANSELAbits.ANSA1=0;

使用特权

评论回复
5
kxsi|  楼主 | 2019-7-25 11:28 | 只看该作者
2 配置波特率

      如何设置波特率为115200呢,这里我们必须先要知道计算公式。在官方的数据手册中有给我们提供表格。到底选择那个公式由SYNC,BRG16,BRGH这三个位的配置决定。

我们选在异步通信模式故SYNC为0;

波特率发生器位,可以选择8位或者16位。不过选择16位。波特率的精度会更高。所以选择16位。BRG16为1.

我们这里选择高速的波特率BRGH为1;

配置如下:

    TXSTAbits.BRGH   =1; //high speed

    BAUDCONbits.BRG16  =1; //16bit Baud rate Generator is used

TXSTAbits.SYNC   =0; //Asynchronous mode



   我们可以得出我们的计算公式为 波特率=FOSC/[4(n+1)];

我们的波特率为115200,时钟定为32MHz。计算出n的值。

115200=32MHz/[4(n+1)];可以得到n=68.444 即n=0x44;

将0x44存入到SPBRGH和SPBRGL中,配置如下

SPBRGH = 0x00;//

SPBRGL = 0x44;// Baud rate 115200


使用特权

评论回复
6
kxsi|  楼主 | 2019-7-25 11:28 | 只看该作者
3,配置接收中断

   实际可以根据自己的需求配置是否用中断接收。不过这里设置为中断接收,配置如下。

    PIE1bits.RCIE = 1; //enables the USART Receive interrupt

    INTCONbits.PEIE = 1;

INTCONbits.GIE  = 1;

使用特权

评论回复
7
kxsi|  楼主 | 2019-7-25 11:28 | 只看该作者
4,开启串口的功能

    开启接收,开启发送,开启串口功能,配置如下:

    RCSTAbits.CREN = 1;//Enables receiver

    TXSTAbits.TXEN = 1;//Transmit enabled

RCSTAbits.SPEN   =1; //serial port enable

使用特权

评论回复
8
kxsi|  楼主 | 2019-7-25 11:28 | 只看该作者
实例代码:单片机型PIC16LF1823,开发环境MPLAB X IDE.

#include<pic.h>

__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_ON&CPD_OFF&BOREN_ON

                   &CLKOUTEN_OFF&IESO_ON&FCMEN_ON);//这个要放到上一行去

__CONFIG(PLLEN_OFF&LVP_OFF) ;

unsigned char RC_DATA;

unsigned char RC_FLAG;

void init_fosc(void)

{

 OSCCON = 0xF0;//32MHz

}

使用特权

评论回复
9
kxsi|  楼主 | 2019-7-25 11:29 | 只看该作者
void init_eusart()

{

    APFCONbits.TXCKSEL = 1;//RA0

    APFCONbits.RXDTSEL = 1;//RA1

    TRISA1 = 1;//RA1 RX input

    ANSELAbits.ANSA1=0;

    SPBRGH = 0x00;//

    SPBRGL = 0x44;// Baud rate 115200

    TXSTAbits.BRGH   =1; //high speed

    BAUDCONbits.BRG16  =1; //16bit Baud rate Generator is used

    TXSTAbits.SYNC   =0; //Asynchronous mode

    PIE1bits.RCIE = 1; //enables the USART Receive interrupt

    INTCONbits.PEIE = 1;

    INTCONbits.GIE  = 1;

    RCSTAbits.CREN = 1;//Enables receiver

    TXSTAbits.TXEN = 1;//Transmit enabled

    RCSTAbits.SPEN   =1; //serial port enable

}

使用特权

评论回复
10
kxsi|  楼主 | 2019-7-25 11:29 | 只看该作者
void tx_eusart(unsigned char tx_data)

{

    TXREG = tx_data;

    while(TRMT==0);// loop

}

使用特权

评论回复
11
kxsi|  楼主 | 2019-7-25 11:29 | 只看该作者
void interrupt isr(void)

{

     if (RCIE && RCIF) {

        RC_DATA=RCREG;

        RC_FLAG=1;

        LATA2 = 1;

    }

}

使用特权

评论回复
12
kxsi|  楼主 | 2019-7-25 11:30 | 只看该作者
int main(int argc, char** argv) {

    init_fosc();

    init_eusart();

    RC_FLAG=0;

    TRISA2 = 0;

    LATA2 = 0;

    while(1)

    {

      

      if(RC_FLAG > 0)

       {

        tx_eusart(RC_DATA);

        RC_FLAG=0;

        LATA2=0;

       }

    }

}

使用特权

评论回复
13
mjs0528| | 2019-10-6 20:01 | 只看该作者
感谢分享,感谢楼主!!!

使用特权

评论回复
14
wahahaheihei| | 2019-10-7 07:47 | 只看该作者
好多UART,前面那些字母是啥意思。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

3304

帖子

2

粉丝