当前位置:   article > 正文

CC26xx(CortexM3) UARTs

cc26xx

简述

UART在嵌入式开发中非常重要,因为很容易在PC找到串口,用来跟嵌入式设备进行简单的通信。比如常见的命令行交互方式……可以输出Log,可以输入命令等等。因此几乎所有的IC都会支持有UART功能。

CC26xx UART功能

速度可达到3Mbps
单独的328的TX FIFO和3212的RX FIFO,这里FIFO应当是32bit的宽度,TX可以FIFO 8个这样的元素,RX可以FIFO 12个这样的元素。FIFO长度可编程,可配为深度为1。
FIFO trigger levels of ⅛, ¼, ½, ¾, and ⅞
支持硬件流控

UART框架

这里写图片描述

UART FIFO图示

这里写图片描述
上图可看出,TX FIFO和RX FIFO的最大深度都是32 Bytes,只是RX FIFO每个单元除了一个Byte,还有额外的4个状态信息的bit。

UART FIFO说明

  1. 初始状态与打开:复位后FIFO功能关闭,相当于只能存入一个Byte的普通register,需要通过UART:LCRH FEN寄存器使能FIFO功能;
  2. 状态监测:通过UART Flag Register (UART:FR)和UART Receive Status Register (UART:RSR)两个寄存器来监测,UART:FR中是TX & RX FIFO的Full, Empty标志,UART:RSR中有接收数据超出的bit标志;
  3. 触发点:即设定FIFO在何种条件下触发中断,这个是通过UART Interrupt FIFO Level Select Register (UART:IFLS)寄存器来设定,TX & RX FIFO可以分别设定其触发点,可配置的触发点有⅛, ¼, ½, ¾, and ⅞,这里的基数应该是32。2640的spec上举例说¼触发点就是收到4个Byte数据就触发中断,我觉得应该是⅛触发点才对,从其driver代码也可以看出。

UART中断说明

  1. 种类:Overrun error, Break error, Parity error, Framing error, Receive timeout, Transmit, Receive,一次只能产生一个中断,可在ISR中通过UART Masked Interrupt Status Register (UART:MIS)寄存器来识别是哪个中断发生。 UART Interrupt Mask Register (UART:IMSC) 可以关闭和开启对应的中断源种类;
  2. 中断清除:通过UART Interrupt Clear Register (UART:ICR)寄存器可以清除掉产生的某次中断;
  3. Receive timeout中断:当RX FIFO非空,而且在一个32-bit的时间间隔后没有收到其余的数据,就会触发这个中断。当RX FIFO数据被读走,或者用UART:ICR就会清除这个中断;
  4. Transmit中断:FIFO功能开启时,TX FIFO中数据小于或等于设置的FIFO触发点时,产生中断,而要往TX FIFO写数据使其中数据多于FIFO触发点时才能清除该中断(或者通过UART:ICR清除)。FIFO功能关闭时,TX FIFO(深度为1)为空时就会产生中断,往其中写入数据就能清除该中断;
  5. Receive中断:FIFO功能开启时,接收数据(RX FIFO中data)到达设置的FIFO触发点,产生中断,而只要取出一个Byte,就能清除该中断。FIFO功能关闭时,只要收到一个Byte,就会产生中断,而读取出数据就将清除该中断。

UART Driver说明

串口驱动说明:

  1. UART_read():调用该函数,RX enable(RX disable要调用UART_readCancel()),开始从RX FIFO读数据,如果有持续的数据到达,必须在读完数据后立即又调用该函数继续读,以免RX FIFO溢出。在持续RX的使用场景下,用CallBack方式,可以直接在CallBack中调用UART_read();
    在Block模式下,发生RX timeout时,RX还是打开的,此时还是要调用UART_read()从RX FIFO去读数据
  2. UART_write():调用该函数后,TX enable,调用该函数成功后,TX disable;
  3. 超时机制:只有在Block模式下才有read和write的超时机制,超时发生时将会返回已经接收到的data,而RX在超时后仍然是enable的。而在Callback模式下,没有超时机制,只有显式调用UART_readCancel()或UART_writeCancel()才能取消操作。重新开始一次read或write都会将UART_Object.status的值重置为UART_OK;
  4. Power的管理:在调用UART_open()之后,仍然可以进入standby模式,在UART_read()期间不能进入standby模式,在RX error发生后允许进入standby模式。在UART_read()成功读到数据后,如果没有再继续调用该函数,RX仍然开着的,可以进入standby模式,但是此期间RX接收到的数据都会被丢掉。
    在调用UART_write()期间,不能进入standby模式,在UART_write()调用成功后,或UART_writeCancel()被调用后,或在Block模式下发生write timeout,都可以进入standby模式。
Generic API functionAPI functionDescription
UART_init()UARTCC26XX_init()Initialize UART driver
UART_open()UARTCC26XX_open()Initialize UART HW and set system dependencies
UART_close()UARTCC26XX_close()Disable UART HW and release system dependencies
UART_control()UARTCC26XX_control()Configure an already opened UART handle
UART_read()UARTCC26XX_read()Start read from UART
UART_readCancel()UARTCC26XX_readCancel()Cancel ongoing read from UART
UART_write()UARTCC26XX_write()Start write to UART
UART_writeCancel()UARTCC26XX_writeCancel()Cancel ongoing write to UART

UART DMA方式

这里写图片描述
– TX和RX有自己独立的DMA通道
– 只要FIFO有数据时,可以从FIFO一个一个接收data,也可以在FIFO level达到时一次性接收data
– 只要FIFO有空间时,可以一个一个写data到FIFO,也可以一次写FIFO level个data

UART使用示例

基本的接收方式

如下的实例是Block方式UART接收方式,一次接收100个Byte的数据

 // ## Basic Receive #
 //  Receive 100 bytes over UART in ::UART_MODE_BLOCKING.
 //  @code
 UART_Handle handle;
 UART_Params params;
 uint8_t rxBuf[100];         // Receive buffer
 uint32_t timeoutUs = 5000;  // 5ms timeout, default timeout is no timeout (BIOS_WAIT_FOREVER)
 
 // Init UART and specify non-default parameters
 UART_Params_init(&params);
 params.baudRate      = 9600;
 params.writeDataMode = UART_DATA_BINARY;
 params.readTimeout   = timeoutUs / Clock_tickPeriod; // Default tick period is 10us
 
 // Open the UART and do the read
 handle = UART_open(Board_UART, &params);
 int rxBytes = UART_read(handle, rxBuf, 100);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

接收部分串口数据

Block模式下接收部分数据

 // ## Receive with Return Partial #
 // This use case will read in ::UART_MODE_BLOCKING until the wanted amount of bytes is
 // received or until a started reception is inactive for a 32-bit period.
 // This UART_read() call can also be used when unknown amount of bytes shall
 // be read. Note: The partial return is also possible in ::UART_MODE_CALLBACK mode.
 UART_Handle handle;
 UART_Params params;
 uint8_t rxBuf[100];      // Receive buffer

 // Init UART and specify non-default parameters
 UART_Params_init(&params);
 params.baudRate      = 9600;
 params.writeDataMode = UART_DATA_BINARY;
 
 // Open the UART and initiate the partial read
 handle = UART_open(Board_UART, &params);
 // Enable RETURN_PARTIAL
 UART_control(handle, UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE, NULL);
 // Begin read
 int rxBytes = UART_read(handle, rxBuf, 100));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

基本的发送方式

 //## Basic Transmit #
 // This case will configure the UART to send the data in txBuf in BLOCKING_MODE.
 UART_Handle handle;
 UART_Params params;
 uint8_t txBuf[] = "Hello World";    // Transmit buffer
 
 // Init UART and specify non-default parameters
 UART_Params_init(&params);
 params.baudRate      = 9600;
 params.writeDataMode = UART_DATA_BINARY;
 
 // Open the UART and do the write
 handle = UART_open(Board_UART, &params);
 UART_write(handle, txBuf, sizeof(txBuf));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

持续接收数据

 //## Receive Continously in ::UART_MODE_CALLBACK \anchor USE_CASE_CB #
 // This case will configure the UART to receive continously in
 // ::UART_MODE_CALLBACK, 16 bytes at the time and transmit them back via UART TX.
 // Note that UART_Params.readTimeout is not in use when using ::UART_MODE_CALLBACK mode.

 #define MAX_NUM_RX_BYTES    1000   // Maximum RX bytes to receive in one go
 #define MAX_NUM_TX_BYTES    1000   // Maximum TX bytes to send in one go
 
 uint32_t wantedRxBytes;            // Number of bytes received so far
 int8_t rxBuf[MAX_NUM_RX_BYTES];   // Receive buffer
 uint8_t txBuf[MAX_NUM_TX_BYTES];   // Transmit buffer
 
 // Callback function
 static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
 {
     // Copy bytes from RX buffer to TX buffer
     for(size_t i = 0; i < size; i++)
         txBuf[i] = ((uint8_t*)rxBuf)[i];
 
     // Echo the bytes received back to transmitter
     UART_write(handle, txBuf, size);
 
     // Start another read, with size the same as it was during first call to
     // UART_read()
     UART_read(handle, rxBuf, wantedRxBytes);
 }
 
 static void taskFxn(UArg a0, UArg a1)
 {
     UART_Handle handle;
     UART_Params params;
 
     // Init UART and specify non-default parameters
     UART_Params_init(&params);
     params.baudRate      = 9600;
     params.writeDataMode = UART_DATA_BINARY;
     params.readMode      = UART_MODE_CALLBACK;
     params.readDataMode  = UART_DATA_BINARY;
     params.readCallback  = readCallback;
 
     // Open the UART and initiate the first read
     handle = UART_open(Board_UART, &params);
     wantedRxBytes = 16;
     int rxBytes = UART_read(handle, rxBuf, wantedRxBytes);
 
     while(true); // Wait forever
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

主要API的具体实现

从上面的Demo看到,主要是用到了UART_Write()和UART_Read()这两个接口,其具体实现的流程图如下:

UART_Write()

这里写图片描述

UART_Read()

这里写图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/150512
推荐阅读
相关标签
  

闽ICP备14008679号