打印
[Kinetis]

使用K20 同时使用两个串口为什么只有一个有用?

[复制链接]
2141|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fyge2015|  楼主 | 2015-1-23 11:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
同时使用两个串口,只有一个可以,当单独使用时都可以,求解答?(是在官方例程基础上改的)

相关帖子

沙发
FSL_TICS_ZJJ| | 2015-1-23 11:16 | 只看该作者
楼主芯片全称是什么?
你是怎么配置两个串口的?

使用特权

评论回复
板凳
fyge2015|  楼主 | 2015-1-23 14:08 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-23 11:16
楼主芯片全称是什么?
你是怎么配置两个串口的?

MK20DX128VLH5  就是将串口0和串口2分别用官方给的例程给初始化,再用中断来分别打印数据,可是只有一个有用, #define TERM_PORT           UART2_BASE_PTR  这个东西该成哪个串口,哪个就有用,我自己写的收发啊,没用到它啊,怎么还会起作用

使用特权

评论回复
地板
fyge2015|  楼主 | 2015-1-23 14:17 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-23 11:16
楼主芯片全称是什么?
你是怎么配置两个串口的?

附件就是代码

k20d50m_sc_baremetal.zip

1.32 MB

使用特权

评论回复
5
FSL_TICS_ZJJ| | 2015-1-23 14:51 | 只看该作者
fyge2015 发表于 2015-1-23 14:08
MK20DX128VLH5  就是将串口0和串口2分别用官方给的例程给初始化,再用中断来分别打印数据,可是只有一个 ...

你看下sysinit.c中,如下代码你修改了没有:
#ifndef CONSOLE_SUPPORT
      /* Enable the pins for the selected UART */
         if (TERM_PORT == UART0_BASE_PTR)
         {
            /* Enable the UART0_TXD function on PTB17 */
             PORTB_PCR17 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin

             /* Enable the UART0_RXD function on PTB16 */
             PORTB_PCR16 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin   
         }

         if (TERM_PORT == UART1_BASE_PTR)
       {
           /* Enable the UART0_TXD function on PTE0 (1) */
            PORTE_PCR0 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin

            /* Enable the UART0_RXD function on PTE1 (2) */
            PORTE_PCR1 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin   
      }

      if (TERM_PORT == UART2_BASE_PTR)
      {
                 /* Enable the UART2_TXD function on PTD3 */
          PORTD_PCR3 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin

          /* Enable the UART2_RXD function on PTD2 */
          PORTD_PCR2 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
      }
        
      /* UART0 and UART1 are clocked from the core clock, but all other UARTs are
         * clocked from the peripheral clock. So we have to determine which clock
         * to send to the uart_init function.
         */
        if ((TERM_PORT == UART0_BASE_PTR) | (TERM_PORT == UART1_BASE_PTR))
            uart_init (TERM_PORT, core_clk_khz, TERMINAL_BAUD);
        else
          uart_init (TERM_PORT, periph_clk_khz, TERMINAL_BAUD);
#endif

如果还是这样,那么你每次只会初始化一个,而且串口模块是由TERM_PORT定义为哪个决定的。

使用特权

评论回复
6
fyge2015|  楼主 | 2015-1-23 15:29 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-23 14:51
你看下sysinit.c中,如下代码你修改了没有:
#ifndef CONSOLE_SUPPORT
      /* Enable the pins for the ...

这个我改了,每次都是初始化两个的

使用特权

评论回复
7
FSL_TICS_ZJJ| | 2015-1-23 15:40 | 只看该作者
fyge2015 发表于 2015-1-23 15:29
这个我改了,每次都是初始化两个的

你怎么初始化的,贴出来我看看。

使用特权

评论回复
8
fyge2015|  楼主 | 2015-1-23 15:48 | 只看该作者
void uart_select(int uart_num)
{
       
        switch(uart_num)
        {
                case 1://uart0
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        break;
                case 2://uart1,uart0
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART1_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        break;
                case 3://uart0,uart1,uart2
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART1_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART2_BASE_PTR, periph_clk_khz, TERMINAL_BAUD);       
                        break;
                default:
                        printf("value overflow !!!\n");
                        break;
        }
}




void uart_init (UART_MemMapPtr uartch, int sysclk, int baud)
{
    register uint16 sbr, brfa;
    uint8 temp;
   
   
    //使能引脚,配置复用引脚为TXD功能
    if (TERM_PORT == UART0_BASE_PTR)
           {
            
               PORTB_PCR17 = PORT_PCR_MUX(0x3);
               PORTB_PCR16 = PORT_PCR_MUX(0x3);     
           }

    else   if (TERM_PORT == UART1_BASE_PTR)
             {
            
              PORTE_PCR0 = PORT_PCR_MUX(0x3);
              PORTE_PCR1 = PORT_PCR_MUX(0x3);  
            }

    else if (TERM_PORT == UART2_BASE_PTR)
            {
                  
                    PORTD_PCR3 = PORT_PCR_MUX(0x3);
                           PORTD_PCR2 = PORT_PCR_MUX(0x3);
            }
   

        //使能串口时钟   
    if(uartch == UART0_BASE_PTR)
                SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
    else
            if (uartch == UART1_BASE_PTR)
                        SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
            else
                    if (uartch == UART2_BASE_PTR)
                            SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;


    //禁止发送接收
    UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK
                                | UART_C2_RE_MASK );

    //配置成8位,无校验模式
    UART_C1_REG(uartch) = 0;       
   
    //计算波特率  串口0、1为系统时钟   其他串口为外设时钟
    sbr = (uint16)((sysclk*1000)/(baud * 16));
        
    /* Save off the current value of the UARTx_BDH except for the SBR field */
    temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));
   
    UART_BDH_REG(uartch) = temp |  UART_BDH_SBR(((sbr & 0x1F00) >> 8));
    UART_BDL_REG(uartch) = (uint8)(sbr & UART_BDL_SBR_MASK);
   
   
    brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));
   
   
    temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));
   
    UART_C4_REG(uartch) = temp |  UART_C4_BRFA(brfa);   

    //使能发送接收
        UART_C2_REG(uartch) |= (UART_C2_TE_MASK
                                | UART_C2_RE_MASK );
       
       
}


//-------------------------------------------------------------------------*
//函数名 : uart_putchar 发送单个字节*
//功 能: 串行发送1个字节 *
//参 数: uartch: 串口号  *
// ch: 要发送的字节 *
//返 回: 无 *
//说 明:
//-------------------------------------------------------------------------*
void uart_putchar (UART_MemMapPtr channel, char ch)
{
    //等待发送缓冲区空
    while(!(UART_S1_REG(channel) & UART_S1_TDRE_MASK));
   
    //发送数据ch
    UART_D_REG(channel) = (uint8)ch;
}

//-------------------------------------------------------------------------*
//函数名 : uart_getchar *
//功 能: 串行接受1个字节 *
//参 数: uartch: 串口号  *
// ch: 接收到的字节 *
//返 回: 成功:1; 失败:0 *
//说 明:  *
//-------------------------------------------------------------------------*

char uart_getchar (UART_MemMapPtr channel, uint8 *ch)
{   
    uint32 k;
    for(k = 0; k < 0xfbb; k ++)
    {
            if((UART_S1_REG(channel) & UART_S1_RDRF_MASK) != 0)
            {
                    *ch = UART_D_REG(channel);
                    return 1;
             }
     }       
    if(k >= 0xfbbb)
    {
            return 0;
    }
           
            return 0;
}

//-------------------------------------------------------------------------*
//函数名 : uart_sendN *
//功 能: 串行 接收n个字节  *
//参 数: uartch: 串口号  *
// buff: 发送缓冲区  *
// len: 发送长度  *
//返 回: 无 *
//说 明:  *
//-------------------------------------------------------------------------*

void uart_sendN (UART_MemMapPtr channel, uint8 *buff, uint16 len)
{
        int i;
        for(i = 0; i < len; i ++)
        {
                uart_putchar(channel, buff[i]);
               
        }
}

//-------------------------------------------------------------------------*
//函数名 : uart_reN *
//功 能: 串行 接收n个字节 *
//参 数: uartch: 串口号  *
// buff: 接收缓冲区 *
// len: 接收长度  *
//返 回: 1: 成功;0: 失败 *
//说 明:  *
//-------------------------------------------------------------------------*

uint8 uart_reN(UART_MemMapPtr channel, uint8 *buff, uint16 len)
{
        uint16 m = 0;
        while(m < len)
        {
                if(0 == uart_getchar (channel,&buff[m]))
                        return 0;
                else m ++;
               
        }
        return 1;
}

//-------------------------------------------------------------------------*
//函数名 : enableuartreint *
//功 能: 开串口接收中断 *
//参 数: uartch: 串口号 *
// irqno: 对应irq号  *
//返 回: 无 *
//说 明: *
//-------------------------------------------------------------------------*
void enableuartreint(UART_MemMapPtr uartch,uint8 irqno)
{
        UART_C2_REG(uartch)|=UART_C2_RIE_MASK; //开放UART接收中断
        enable_irq(irqno); //开接收引脚的IRQ中断
}

//-------------------------------------------------------------------------*
//函数名 : disableuartreint *
//功 能: 关串口接收中断 *
//参 数: uartch: 串口号 *
// irqno: 对应irq号 *
//返 回: 无 *
//说 明: *
//-------------------------------------------------------------------------*
void disableuartreint(UART_MemMapPtr uartch,uint8 irqno)
{
UART_C2_REG(uartch)&=~UART_C2_RIE_MASK; //禁止UART接收中断
disable_irq(irqno); //关接收引脚的IRQ中断
}




int uart_getchar_present (UART_MemMapPtr channel)
{
    return (UART_S1_REG(channel) & UART_S1_RDRF_MASK);
}

使用特权

评论回复
9
fyge2015|  楼主 | 2015-1-23 15:51 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-23 15:40
你怎么初始化的,贴出来我看看。


void uart_select(int uart_num)
{
        
        switch(uart_num)
        {
                case 1://uart0
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        break;
                case 2://uart1,uart0
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART1_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        break;
                case 3://uart0,uart1,uart2
                        uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART1_BASE_PTR, core_clk_khz, TERMINAL_BAUD);
                        uart_init (UART2_BASE_PTR, periph_clk_khz, TERMINAL_BAUD);        
                        break;
                default:
                        printf("value overflow !!!\n");
                        break;
        }
}




void uart_init (UART_MemMapPtr uartch, int sysclk, int baud)
{
    register uint16 sbr, brfa;
    uint8 temp;
   
   
    //使能引脚,配置复用引脚为TXD功能
    if (TERM_PORT == UART0_BASE_PTR)
           {
            
               PORTB_PCR17 = PORT_PCR_MUX(0x3);
               PORTB_PCR16 = PORT_PCR_MUX(0x3);     
           }

    else   if (TERM_PORT == UART1_BASE_PTR)
             {
            
              PORTE_PCR0 = PORT_PCR_MUX(0x3);
              PORTE_PCR1 = PORT_PCR_MUX(0x3);  
            }

    else if (TERM_PORT == UART2_BASE_PTR)
            {
                  
                    PORTD_PCR3 = PORT_PCR_MUX(0x3);
                           PORTD_PCR2 = PORT_PCR_MUX(0x3);
            }
   

        //使能串口时钟   
    if(uartch == UART0_BASE_PTR)
                SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
    else
            if (uartch == UART1_BASE_PTR)
                        SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
            else
                    if (uartch == UART2_BASE_PTR)
                            SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;


    //禁止发送接收
    UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK
                                | UART_C2_RE_MASK );

    //配置成8位,无校验模式
    UART_C1_REG(uartch) = 0;        
   
    //计算波特率  串口0、1为系统时钟   其他串口为外设时钟
    sbr = (uint16)((sysclk*1000)/(baud * 16));
        
    /* Save off the current value of the UARTx_BDH except for the SBR field */
    temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));
   
    UART_BDH_REG(uartch) = temp |  UART_BDH_SBR(((sbr & 0x1F00) >> 8));
    UART_BDL_REG(uartch) = (uint8)(sbr & UART_BDL_SBR_MASK);
   
   
    brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));
   
   
    temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));
   
    UART_C4_REG(uartch) = temp |  UART_C4_BRFA(brfa);   

    //使能发送接收
        UART_C2_REG(uartch) |= (UART_C2_TE_MASK
                                | UART_C2_RE_MASK );
        
        
}


//-------------------------------------------------------------------------*
//函数名 : uart_putchar 发送单个字节*
//功 能: 串行发送1个字节 *
//参 数: uartch: 串口号  *
// ch: 要发送的字节 *
//返 回: 无 *
//说 明:
//-------------------------------------------------------------------------*
void uart_putchar (UART_MemMapPtr channel, char ch)
{
    //等待发送缓冲区空
    while(!(UART_S1_REG(channel) & UART_S1_TDRE_MASK));
   
    //发送数据ch
    UART_D_REG(channel) = (uint8)ch;
}

//-------------------------------------------------------------------------*
//函数名 : uart_getchar *
//功 能: 串行接受1个字节 *
//参 数: uartch: 串口号  *
// ch: 接收到的字节 *
//返 回: 成功:1; 失败:0 *
//说 明:  *
//-------------------------------------------------------------------------*

char uart_getchar (UART_MemMapPtr channel, uint8 *ch)
{   
    uint32 k;
    for(k = 0; k < 0xfbb; k ++)
    {
            if((UART_S1_REG(channel) & UART_S1_RDRF_MASK) != 0)
            {
                    *ch = UART_D_REG(channel);
                    return 1;
             }
     }        
    if(k >= 0xfbbb)
    {
            return 0;
    }
            
            return 0;
}

//-------------------------------------------------------------------------*
//函数名 : uart_sendN *
//功 能: 串行 接收n个字节  *
//参 数: uartch: 串口号  *
// buff: 发送缓冲区  *
// len: 发送长度  *
//返 回: 无 *
//说 明:  *
//-------------------------------------------------------------------------*

void uart_sendN (UART_MemMapPtr channel, uint8 *buff, uint16 len)
{
        int i;
        for(i = 0; i < len; i ++)
        {
                uart_putchar(channel, buff);
               
        }
}

//-------------------------------------------------------------------------*
//函数名 : uart_reN *
//功 能: 串行 接收n个字节 *
//参 数: uartch: 串口号  *
// buff: 接收缓冲区 *
// len: 接收长度  *
//返 回: 1: 成功;0: 失败 *
//说 明:  *
//-------------------------------------------------------------------------*

uint8 uart_reN(UART_MemMapPtr channel, uint8 *buff, uint16 len)
{
        uint16 m = 0;
        while(m < len)
        {
                if(0 == uart_getchar (channel,&buff[m]))
                        return 0;
                else m ++;
               
        }
        return 1;
}

//-------------------------------------------------------------------------*
//函数名 : enableuartreint *
//功 能: 开串口接收中断 *
//参 数: uartch: 串口号 *
// irqno: 对应irq号  *
//返 回: 无 *
//说 明: *
//-------------------------------------------------------------------------*
void enableuartreint(UART_MemMapPtr uartch,uint8 irqno)
{
        UART_C2_REG(uartch)|=UART_C2_RIE_MASK; //开放UART接收中断
        enable_irq(irqno); //开接收引脚的IRQ中断
}

//-------------------------------------------------------------------------*
//函数名 : disableuartreint *
//功 能: 关串口接收中断 *
//参 数: uartch: 串口号 *
// irqno: 对应irq号 *
//返 回: 无 *
//说 明: *
//-------------------------------------------------------------------------*
void disableuartreint(UART_MemMapPtr uartch,uint8 irqno)
{
UART_C2_REG(uartch)&=~UART_C2_RIE_MASK; //禁止UART接收中断
disable_irq(irqno); //关接收引脚的IRQ中断
}




int uart_getchar_present (UART_MemMapPtr channel)
{
    return (UART_S1_REG(channel) & UART_S1_RDRF_MASK);
}

使用特权

评论回复
10
FSL_TICS_ZJJ| | 2015-1-23 15:56 | 只看该作者
fyge2015 发表于 2015-1-23 15:48
void uart_select(int uart_num)
{
       

你现在是单独的UART0, UART1,UART2这么配置都可以,但是一起配置就不行?

使用特权

评论回复
11
fyge2015|  楼主 | 2015-1-23 15:58 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-23 15:56
你现在是单独的UART0, UART1,UART2这么配置都可以,但是一起配置就不行?
...

单个的都可以,但我现在需要同时用两个串口,但运行起来只有一个可以出数据

使用特权

评论回复
12
justperky| | 2015-1-25 20:09 | 只看该作者
我也来学习一下

使用特权

评论回复
13
FSL_TICS_ZJJ| | 2015-1-26 10:48 | 只看该作者
fyge2015 发表于 2015-1-23 14:08
MK20DX128VLH5  就是将串口0和串口2分别用官方给的例程给初始化,再用中断来分别打印数据,可是只有一个 ...

楼主每次都有一个有用,是中断优先级高的那个有用吗?
还有,你是一直在发吗?
如果优先级高的那个中断,发慢一点,低优先级是不是可以使用?

使用特权

评论回复
14
园希| | 2015-3-5 16:59 | 只看该作者
FSL_TICS_ZJJ 发表于 2015-1-26 10:48
楼主每次都有一个有用,是中断优先级高的那个有用吗?
还有,你是一直在发吗?
如果优先级高的那个中断, ...

遇到一样的问题,低优先级的中断不了,高的可以

使用特权

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

本版积分规则

1

主题

24

帖子

0

粉丝