当前位置:   article > 正文

S32K144 UART通讯_s32k 144 串口

s32k 144 串口

一、UART工作原理:

UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收

⑴输出缓冲寄存器,它接收CPU从数据总线上送来的并行数据,并加以保存。uart基本结构

⑵ 输出移位寄存器,它接收从输出缓冲器送来的并行数据,以发送时钟的速率把数据逐位移出,即将并行数据转换为串行数据输出

⑶ 输入移位寄存器,它以接收时钟的速率把出现在串行数据输入线上的数据逐位移入,当数据装满后,并行送往输入缓冲寄存器,即将串行数据转换成并行数据。

⑷ 输入缓冲寄存器,它从输入移位寄存器中接收并行数据,然后由CPU取走。

控制寄存器,它接收CPU送来的控制字,由控制字的内容,决定通信时的传输方式以及数据格式等。例如采用异步方式还是同步方式,数据字符的位数,有无奇偶校验,是奇校验还是偶校验,停止位的位数等参数。

状态寄存器。状态寄存器中存放着接口的各种状态信息,例如输出缓冲区是否空,输入字符是否准备好等。在通信过程中,当符合某种状态时,接口中的状态检测逻辑将状态寄存器的相应位置"1",以便让CPU查询。

1.帧格式:

2.通讯过程:

UART发送数据时先发低位后发高位。当总线处于空闲状态时,线路保持高电平。以发送数据0x96为例,发送数据前会先发一个0,让总线从高电平变成低电平,提醒数据接收方做好准备,然后依次从低位到高位发送八位数据。传输完成后,会发一个1,让总线重新回到高电平。

UART数据发送过程中,包含8位数据位,一位起始位,一位停止位。一共10位。如若需要发送新的数据,则重新从起始位开始。

UART属于异步通讯,这意味着没有时钟信号,取而代之的是在数据包中添加开始和停止位。这些位定义了数据包的开始和结束,因此接收UART知道何时读取这些数据。

个人理解:单片机设备和PC串口调试通讯时:

1.单片机发送字符串:发送前,STAT寄存器发送bit状态为空,此时往DATA寄存器上写一个字符,即发送了一个字符,STAT寄存器发送bit状态变为满;此时,PC串口调试助手,马上就收一个字符,STAT寄存器发送bit状态变为空,依次

2.单片机接受字符:接受前,STAT寄存器接受bit为满,从DATA寄存器读取一个字符后,STAT寄存器接受bit变为空。此时,PC串口调试助手检测到STAT发送bit状态为空,马上又发送一个字符,STAT寄存器接受bit变为满,依次

二、S32K44 UART通讯:

1.主要寄存器说明:

BAUD:

配置生成波特率

CTRL:

是能串口功能

STAT:

判断通讯是否可以进行

DATA:

数据收发

2.三种通讯方式:

2.1.使用DATA寄存器普通通讯,亲测接口如下:

void SOSC_init_8MHz(void) {
    SCG->SOSCDIV=0x00000101;  /* SOSCDIV1 & SOSCDIV2 =1: divide by 1 */
    SCG->SOSCCFG=0x00000024;  /* Range=2: Medium freq (SOSC betw 1MHz-8MHz)*/
                            /* HGO=0:   Config xtal osc for low power */
                            /* EREFS=1: Input is external XTAL */
    while(SCG->SOSCCSR & SCG_SOSCCSR_LK_MASK); /* Ensure SOSCCSR unlocked */
    SCG->SOSCCSR=0x00000001;  /* LK=0:          SOSCCSR can be written */
                            /* SOSCCMRE=0:    OSC CLK monitor IRQ if enabled */
                            /* SOSCCM=0:      OSC CLK monitor disabled */
                            /* SOSCERCLKEN=0: Sys OSC 3V ERCLK output clk disabled */
                            /* SOSCLPEN=0:    Sys OSC disabled in VLP modes */
                            /* SOSCSTEN=0:    Sys OSC disabled in Stop modes */
                            /* SOSCEN=1:      Enable oscillator */
    while(!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)); /* Wait for sys OSC clk valid */
}

void SPLL_init_160MHz(void) {
    while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
    SCG->SPLLCSR = 0x00000000;  /* SPLLEN=0: SPLL is disabled (default) */
    SCG->SPLLDIV = 0x00000302;  /* SPLLDIV1 divide by 2; SPLLDIV2 divide by 4 */
    SCG->SPLLCFG = 0x00180000;  /* PREDIV=0: Divide SOSC_CLK by 0+1=1 */
                              /* MULT=24:  Multiply sys pll by 4+24=40 */
                              /* SPLL_CLK = 8MHz / 1 * 40 / 2 = 160 MHz */
    while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
    SCG->SPLLCSR = 0x00000001; /* LK=0:        SPLLCSR can be written */
                             /* SPLLCMRE=0:  SPLL CLK monitor IRQ if enabled */
                             /* SPLLCM=0:    SPLL CLK monitor disabled */
                             /* SPLLSTEN=0:  SPLL disabled in Stop modes */
                             /* SPLLEN=1:    Enable SPLL */
    while(!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)); /* Wait for SPLL valid */
}

void NormalRUNmode_80MHz (void) {  /* Change to normal RUN mode with 8MHz SOSC, 80 MHz PLL*/
    SCG->RCCR=SCG_RCCR_SCS(6)      /* PLL as clock source*/
    |SCG_RCCR_DIVCORE(0b01)      /* DIVCORE=1, div. by 2: Core clock = 160/2 MHz = 80 MHz*/
    |SCG_RCCR_DIVBUS(0b01)       /* DIVBUS=1, div. by 2: bus clock = 40 MHz*/
    |SCG_RCCR_DIVSLOW(0b10);     /* DIVSLOW=2, div. by 2: SCG slow, flash clock= 26 2/3 MHz*/
    while (((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT ) != 6) {}
                                 /* Wait for sys clk src = SPLL */
}

void LPUART1_init(void)  /* Init. summary: 9600 baud, 1 stop bit, 8 bit format, no parity */
{
    PCC->PCCn[PCC_LPUART1_INDEX] &= ~PCC_PCCn_CGC_MASK;    /* Ensure clk disabled for config */
    PCC->PCCn[PCC_LPUART1_INDEX] |= PCC_PCCn_PCS(0b001)    /* Clock Src= 1 (SOSCDIV2_CLK) */
                               |  PCC_PCCn_CGC_MASK;     /* Enable clock for LPUART1 regs */

    LPUART1->BAUD = 0x0F000034;  /* Initialize for 9600 baud, 1 stop: */
                               /* SBR=52 (0x34): baud divisor = 8M/9600/16 = ~52 */
                               /* OSR=15: Over sampling ratio = 15+1=16 */
                               /* SBNS=0: One stop bit */
                               /* BOTHEDGE=0: receiver samples only on rising edge */
                               /* M10=0: Rx and Tx use 7 to 9 bit data characters */
                               /* RESYNCDIS=0: Resync during rec'd data word supported */
                               /* LBKDIE, RXEDGIE=0: interrupts disable */
                               /* TDMAE, RDMAE, TDMAE=0: DMA requests disabled */
                               /* MAEN1, MAEN2,  MATCFG=0: Match disabled */

    LPUART1->CTRL=0x000C0000;    /* Enable transmitter & receiver, no parity, 8 bit char: */
                               /* RE=1: Receiver enabled */
                               /* TE=1: Transmitter enabled */
                               /* PE,PT=0: No hw parity generation or checking */
                               /* M7,M,R8T9,R9T8=0: 8-bit data characters*/
                               /* DOZEEN=0: LPUART enabled in Doze mode */
                               /* ORIE,NEIE,FEIE,PEIE,TIE,TCIE,RIE,ILIE,MA1IE,MA2IE=0: no IRQ*/
                               /* TxDIR=0: TxD pin is input if in single-wire mode */
                               /* TXINV=0: TRansmit data not inverted */
                               /* RWU,WAKE=0: normal operation; rcvr not in statndby */
                               /* IDLCFG=0: one idle character */
                               /* ILT=0: Idle char bit count starts after start bit */
                               /* SBK=0: Normal transmitter operation - no break char */
                               /* LOOPS,RSRC=0: no loop back */
}

void LPUART1_transmit_char(char send) {    /* Function to Transmit single Char */
    while((LPUART1->STAT & LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT==0);
                                   /* Wait for transmit buffer to be empty */
    LPUART1->DATA=send;              /* Send data */
}

void LPUART1_transmit_string(char data_string[])  {  /* Function to Transmit whole string */
    uint32_t i=0;
    while(data_string[i] != '\0')  {           /* Send chars one at a time */
    LPUART1_transmit_char(data_string[i]);
    i++;
    }
}

char LPUART1_receive_char(void) {    /* Function to Receive single Char */
    char recieve;
    while((LPUART1->STAT & LPUART_STAT_RDRF_MASK)>>LPUART_STAT_RDRF_SHIFT==0);
                                     /* Wait for received buffer to be full */
    recieve= LPUART1->DATA;            /* Read received data*/
    return recieve;
}

void assert(char flag)
{
    while (!flag);
}

char stringCompare(const char *source, const char *dest)
{
    assert(source && dest);
    char ret = 0;

    while (*source != '\0') {
        if (*source++ != *dest++) {
            ret = -1;
            break;
        }
    }

    return ret;
}
#include <string.h>
void LPUART1_receive_and_echo_char(void)  {  /* Function to echo received char back */
    char send[128], i = 0, recvEndFlag = 1;
    char buf[128] = {0};

    for (; i < 127; i++) {
      buf[i] = 'a';
    }
    i = 0;
    while (recvEndFlag) {
      send[i++] = LPUART1_receive_char();
      if (send[i-1] == '\0') {
          recvEndFlag = 0;
      }
    }

    if (!strcmp(send, buf)) {
      LPUART1_transmit_string("dsdaavdad");
    }
}

char data=0;
void PORT_init (void) {
    PCC->PCCn[PCC_PORTC_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
    PORTC->PCR[6]|=PORT_PCR_MUX(2);           /* Port C6: MUX = ALT2,UART1 TX */
    PORTC->PCR[7]|=PORT_PCR_MUX(2);           /* Port C7: MUX = ALT2,UART1 RX */
}

int main(void)
{
    SOSC_init_8MHz();      /* Initialize system oscilator for 8 MHz xtal */
    SPLL_init_160MHz();    /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
    NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
    PORT_init();           /* Configure ports */

    LPUART1_init();        /* Initialize LPUART @ 9600*/
    LPUART1_transmit_string("Running LPUART example\n\r");     /* Transmit char string */
    LPUART1_transmit_string("Input character to echo...\n\r"); /* Transmit char string */

    for(;;) {
      LPUART1_receive_and_echo_char();    /* Wait for input char, receive & echo it*/
    }
}
 

2.2.使用中断通讯,测试接口如下:

void LPUART1_init(void)  /* Init. summary: 9600 baud, 1 stop bit, 8 bit format, no parity */
{
  PCC->PCCn[PCC_LPUART1_INDEX] &= ~PCC_PCCn_CGC_MASK;    /* Ensure clk disabled for config */
  PCC->PCCn[PCC_LPUART1_INDEX] |= PCC_PCCn_PCS(0b001)    /* Clock Src= 1 (SOSCDIV2_CLK) */
                               |  PCC_PCCn_CGC_MASK;     /* Enable clock for LPUART1 regs */

  LPUART1->BAUD = 0x0F000034;  /* Initialize for 9600 baud, 1 stop: */
                               /* SBR=52 (0x34): baud divisor = 8M/9600/16 = ~52 */
                               /* OSR=15: Over sampling ratio = 15+1=16 */
                               /* SBNS=0: One stop bit */
                               /* BOTHEDGE=0: receiver samples only on rising edge */
                               /* M10=0: Rx and Tx use 7 to 9 bit data characters */
                               /* RESYNCDIS=0: Resync during rec'd data word supported */
                               /* LBKDIE, RXEDGIE=0: interrupts disable */
                               /* TDMAE, RDMAE, TDMAE=0: DMA requests disabled */
                               /* MAEN1, MAEN2,  MATCFG=0: Match disabled */

  LPUART1->CTRL=0x000C0000;    /* Enable transmitter & receiver, no parity, 8 bit char: */
                               /* RE=1: Receiver enabled */
                               /* TE=1: Transmitter enabled */
                               /* PE,PT=0: No hw parity generation or checking */
                               /* M7,M,R8T9,R9T8=0: 8-bit data characters*/
                               /* DOZEEN=0: LPUART enabled in Doze mode */
                               /* ORIE,NEIE,FEIE,PEIE,TIE,TCIE,RIE,ILIE,MA1IE,MA2IE=0: no IRQ*/
                               /* TxDIR=0: TxD pin is input if in single-wire mode */
                               /* TXINV=0: TRansmit data not inverted */
                               /* RWU,WAKE=0: normal operation; rcvr not in statndby */
                               /* IDLCFG=0: one idle character */
                               /* ILT=0: Idle char bit count starts after start bit */
                               /* SBK=0: Normal transmitter operation - no break char */
                               /* LOOPS,RSRC=0: no loop back */
  // Enable LPUART interrupt.
      S32_NVIC->ISER[(uint32_t)(LPUART1_RxTx_IRQn) >> 5U] = (uint32_t)(1UL << ((uint32_t)(LPUART1_RxTx_IRQn) & (uint32_t)0x1FU));
}

void LPUART1_transmit_char(char send) {    /* Function to Transmit single Char */
  while((LPUART1->STAT & LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT==0);
                                   /* Wait for transmit buffer to be empty */
  LPUART1->DATA=send;              /* Send data */
}

void LPUART1_transmit_string(char data_string[])  {  /* Function to Transmit whole string */
  uint32_t i=0;
  while(data_string[i] != '\0')  {           /* Send chars one at a time */
    LPUART1_transmit_char(data_string[i]);
    i++;
  }
}

char LPUART1_receive_char(void) {    /* Function to Receive single Char */
  char recieve;
  while((LPUART1->STAT & LPUART_STAT_RDRF_MASK)>>LPUART_STAT_RDRF_SHIFT==0);
                                     /* Wait for received buffer to be full */
  recieve= LPUART1->DATA;            /* Read received data*/
  return recieve;
}
#include <string.h>
UART_DATA_t uart_data;
void LPUART1_receive_and_echo_char(void)  {  /* Function to echo received char back */
    char send[1024] = {0};
    char buf[128] = {0};
    char i = 0, recvEndFlag = 1;

    for (; i < 127; i++) {
      buf[i] = 'a';
    }
    i = 0;
    //uart_data.rxLen = 128;
    while (recvEndFlag) {
        uart_data.rxBuff = &send[i++];
        uart_data.rxSize = 128;
        if (send[i-1] == '\0') {
            recvEndFlag = 0;
        }
        /* Enable receive data full interrupt */
        LPUART1->CTRL |= 1 << LPUART_CTRL_RIE_SHIFT;
    }
while (uart_data.rxSize);
    if (!strncmp(send, buf, strlen(buf))) {
        LPUART1_transmit_string("我喜欢罗紫屹,不吵架以后!");
    }
}

void LPUART1_RxTx_IRQHandler(void)
{
    UART_DATA_t *data_type = &uart_data;

    /* Handle receive data full interrupt */
    if (LPUART1->CTRL >> LPUART_CTRL_RIE_SHIFT)
    {
        if (LPUART1->STAT >> LPUART_STAT_RDRF_SHIFT)
        {
            /* Get data and put in receive buffer  */
            // 8 bit per char, 9 and 10bit ??? TODO:
            *data_type->rxBuff = (U8)LPUART1->DATA;

            /* Update the internal state */
            ++data_type->rxBuff;
            --data_type->rxSize;
            //data_type->rxLen--;

            /* Finish reception if this was the last byte received */
            if (data_type->rxSize == 0U)
            {
                /* Complete transfer, will disable rx interrupt */
                LPUART1->CTRL |= (1 << LPUART_CTRL_RIE_SHIFT) ;
            }
        }
    }


}

void SOSC_init_8MHz(void) {
  SCG->SOSCDIV=0x00000101;  /* SOSCDIV1 & SOSCDIV2 =1: divide by 1 */
  SCG->SOSCCFG=0x00000024;  /* Range=2: Medium freq (SOSC betw 1MHz-8MHz)*/
                            /* HGO=0:   Config xtal osc for low power */
                            /* EREFS=1: Input is external XTAL */
  while(SCG->SOSCCSR & SCG_SOSCCSR_LK_MASK); /* Ensure SOSCCSR unlocked */
  SCG->SOSCCSR=0x00000001;  /* LK=0:          SOSCCSR can be written */
                            /* SOSCCMRE=0:    OSC CLK monitor IRQ if enabled */
                            /* SOSCCM=0:      OSC CLK monitor disabled */
                            /* SOSCERCLKEN=0: Sys OSC 3V ERCLK output clk disabled */
                            /* SOSCLPEN=0:    Sys OSC disabled in VLP modes */
                            /* SOSCSTEN=0:    Sys OSC disabled in Stop modes */
                            /* SOSCEN=1:      Enable oscillator */
  while(!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)); /* Wait for sys OSC clk valid */
}

void SPLL_init_160MHz(void) {
  while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
  SCG->SPLLCSR = 0x00000000;  /* SPLLEN=0: SPLL is disabled (default) */
  SCG->SPLLDIV = 0x00000302;  /* SPLLDIV1 divide by 2; SPLLDIV2 divide by 4 */
  SCG->SPLLCFG = 0x00180000;  /* PREDIV=0: Divide SOSC_CLK by 0+1=1 */
                              /* MULT=24:  Multiply sys pll by 4+24=40 */
                              /* SPLL_CLK = 8MHz / 1 * 40 / 2 = 160 MHz */
  while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
  SCG->SPLLCSR = 0x00000001; /* LK=0:        SPLLCSR can be written */
                             /* SPLLCMRE=0:  SPLL CLK monitor IRQ if enabled */
                             /* SPLLCM=0:    SPLL CLK monitor disabled */
                             /* SPLLSTEN=0:  SPLL disabled in Stop modes */
                             /* SPLLEN=1:    Enable SPLL */
  while(!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)); /* Wait for SPLL valid */
}

void NormalRUNmode_80MHz (void) {  /* Change to normal RUN mode with 8MHz SOSC, 80 MHz PLL*/
  SCG->RCCR=SCG_RCCR_SCS(6)      /* PLL as clock source*/
    |SCG_RCCR_DIVCORE(0b01)      /* DIVCORE=1, div. by 2: Core clock = 160/2 MHz = 80 MHz*/
    |SCG_RCCR_DIVBUS(0b01)       /* DIVBUS=1, div. by 2: bus clock = 40 MHz*/
    |SCG_RCCR_DIVSLOW(0b10);     /* DIVSLOW=2, div. by 2: SCG slow, flash clock= 26 2/3 MHz*/
  while (((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT ) != 6) {}
                                 /* Wait for sys clk src = SPLL */
}

main.c
#include "S32K144.h" /* include peripheral declarations S32K144 */

char data=0;
void PORT_init (void) {
  PCC->PCCn[PCC_PORTC_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
  PORTC->PCR[6]|=PORT_PCR_MUX(2);           /* Port C6: MUX = ALT2,UART1 TX */
  PORTC->PCR[7]|=PORT_PCR_MUX(2);           /* Port C7: MUX = ALT2,UART1 RX */
}

int main(void)
{
  SOSC_init_8MHz();      /* Initialize system oscilator for 8 MHz xtal */
  SPLL_init_160MHz();    /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
  NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
  PORT_init();           /* Configure ports */

  LPUART1_init();        /* Initialize LPUART @ 9600*/
  LPUART1_transmit_string("Running LPUART example\n\r");     /* Transmit char string */
  LPUART1_transmit_string("Input character to echo...\n\r"); /* Transmit char string */

  for(;;) {
      LPUART1_receive_and_echo_char();    /* Wait for input char, receive & echo it*/
  }
}

2.3.使用FIFO通讯

暂未使用,可以继续深入研究点:

数据位:8bit                        优化:其他bit数据通讯7、9、10
停止位:1bit                        优化:2bit停止位
校验位:disable                  优化:开启奇偶检验
数据通讯方式:UART模块DATA寄存器  优化:1.DMA;2.FIFO 轮询;3.FIFO中断

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

闽ICP备14008679号