注册 登录
查看: 697|回复: 9

串口发送多个字节有问题

[复制链接]
发表于 2014-3-13 13:56:18 | 显示全部楼层 |阅读模式
芯片是kl26,用电脑发送一个字节可已接收,但是多个字节发送就不行,程序如下
void uart0_handler(void)
{
    char ch[10],i;
    UARTn_e uratn = UART0;

    if(UART_S1_REG(UARTN[uratn]) & UART_S1_RDRF_MASK)   //接收数据寄存器满
    {
        //用户需要处理接收数据
        //uart_getchar   (uratn, &ch);                    //无限等待接受1个字节
        i = uart_querystr(UART0,ch,10);
        uart_putchar   (uratn , i);                    //发送字符串
    }
}


发送三个数据最终在上位机显示返回的值是01  01  01

回复

使用道具 举报

 楼主| 发表于 2014-3-13 16:09:25 | 显示全部楼层
风落小鱼 发表于 2014-3-13 15:58
很简单,KL26 处理完成中断后,串口模块还没有接收到第二字符,所以就退出。等接收到第二个字符后再进入中 ...

哦,知道了,换成uart_getchar可以了
回复 支持 1 反对 0

使用道具 举报

发表于 2014-3-13 13:57:21 | 显示全部楼层
中断时间太长,CPU处理不过来导致接收失败的。
中断程序里去掉串口发送吧,或者超频
回复 支持 反对

使用道具 举报

发表于 2014-3-13 13:59:19 | 显示全部楼层
不对,你是发送 接收到多少个字节。
你既然发送了3个字节,那么就会进入3次中断,中断了每次接收一个字节,所以上位机看到结果就是 01 01 01 ,符合你的代码设置
回复 支持 反对

使用道具 举报

发表于 2014-3-13 14:00:37 | 显示全部楼层
另外,你的编程不规范,局部变量没有赋初值,随机值会导致各种异常情况发生的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-13 15:51:27 | 显示全部楼层
丁玉 发表于 2014-3-13 13:57
中断时间太长,CPU处理不过来导致接收失败的。
中断程序里去掉串口发送吧,或者超频

去掉串口发送依然一样,我已经超频到最高了,PLL220,bus40应该不是这个问题
回复 支持 反对

使用道具 举报

发表于 2014-3-13 15:53:11 | 显示全部楼层
Venice 发表于 2014-3-13 15:51
去掉串口发送依然一样,我已经超频到最高了,PLL220,bus40应该不是这个问题

哥们,你发送的是接收长度啊!!接收了3次,每次一个字节,有啥问题呢?
  1. i = uart_querystr(UART0,ch,10);
  2. uart_putchar   (uratn , i);                    //发送字符串
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-13 15:56:22 | 显示全部楼层
丁玉 发表于 2014-3-13 13:59
不对,你是发送 接收到多少个字节。
你既然发送了3个字节,那么就会进入3次中断,中断了每次接收一个字节, ...

/*!
*  @brief      查询接收1个字符
*  @param      UARTn_e       模块号(UART0~UART5)
*  @param      ch          接收地址
*  @return     1为接收成功,0为接收失败
*  @since      v5.0
*  @note       如果需要等待接收,可用 uart_getchar
*  Sample usage:       char ch ;
                        if( uart_querychar (UART3,&ch) == 1)     //查询接收1个字符,保存到 ch里
                        {
                            printf("成功接收到一个字节");
                        }
*/
char uart_querychar (UARTn_e uratn, char *ch)
{
    if(uratn == UART0)
    {
        if(UART0_S1 & UART0_S1_RDRF_MASK)
        {
            *ch = UART0_D;
            return 1;
        }
    }
    else
    {
        if(UART_S1_REG(UARTN[uratn]) & UART_S1_RDRF_MASK)
        {
            *ch = UART_D_REG(UARTN[uratn]);
            return 1;
        }
    }

    return 0;                                   //返回0表示接收失败
}


/*!
*  @brief      查询接收字符串
*  @param      UARTn_e       模块号(UART0~UART5)
*  @param      str         接收地址
*  @param      max_len     最大接收长度
*  @return     接收到的字节数目
*  @since      v5.0
*  Sample usage:       char str[100];
                        uint32 num;
                        num = uart_pendstr (UART3,&str,100);
                        if( num != 0 )
                        {
                            printf("成功接收到%d个字节:%s",num,str);
                        }
*/
char uart_querystr (UARTn_e uratn, char *str, uint32 max_len)
{
    uint32 i = 0;
    while(uart_querychar(uratn, str + i)  )
    {
        if( *(str + i) == NULL )    //接收到字符串结束符
        {
            return i;
        }

        i++;
        if(i >= max_len)            //超过设定的最大值,退出
        {
            return i;
        }
    };

    return i;
}

这是山外本身的库函数,用来接收多个字符的,应该是把所有的字符都接收并统计字符数啊,怎么会分三次进入中断,虽然说现况就是这样,但按我的想法他应该发送回来一个03啊。。。
回复 支持 反对

使用道具 举报

发表于 2014-3-13 15:58:32 | 显示全部楼层
Venice 发表于 2014-3-13 15:56
/*!
*  @brief      查询接收1个字符
*  @param      UARTn_e       模块号(UART0~UART5)

很简单,KL26 处理完成中断后,串口模块还没有接收到第二字符,所以就退出。等接收到第二个字符后再进入中断。

你可以改成等待接收的,等待接收完全部数据再退出。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-13 16:00:29 | 显示全部楼层
丁玉 发表于 2014-3-13 14:00
另外,你的编程不规范,局部变量没有赋初值,随机值会导致各种异常情况发生的

这个我承认,但是我赋值后依然不出效果啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回列表 返回顶部