微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > ARM技术讨论 > 跪求解答!基于arm7的UART通信乱码问题

跪求解答!基于arm7的UART通信乱码问题

时间:10-02 整理:3721RD 点击:
跪求高手解答!
为什么输入8个字节时能正确通信,输入8个以上的字节会出现乱码?
程序如下:
/*******************************************************************************
*File: main.c
*功能:使用串口UART1接收上位机发送的数据,当接收到8个连续数据后,取反LED控制,并将
*     数据原封不动地发送回上位机
*******************************************************************************/
#include <intrinsics.h>
#include "inc/config.h"
#include <iolpc2103.h>
#include <stdio.h>
/*定义串口模式设置数据结构*/
typedef  struct UartMode
{
  U8 datab;                    //字长度,5/6/7/8
  U8 stopb;                    //停止位,1/2
  U8 parity;                   //奇偶校验位,0为无校验,1为奇数校验,2为偶数校验
} UARTMODE;
U8 rcv_buf[8];                //UART0数据接收缓冲区
U8 rcv_new;                   //接收新数据标志
/*************************************************************************
*                函数名称:irq_handler
*************************************************************************/
#pragma vector=IRQV
__irq __arm void irq_handler (void)
{
void (*interrupt_function)();//定义一个指针变量,指针指向void ()(void)函数,获得中断服务函数的地址,赋值给一个函数指针,然后通过这个指针调用中断服务函数。
unsigned int vector;
  vector = VICVectAddr;     //获得中断向量
  interrupt_function = (void(*)())vector;
  if(interrupt_function != NULL)
  {
    interrupt_function();  //调用中断指向的函数
  }
  else
  {
    VICVectAddr = 0;      //清除在VIC中的中断
  }
}
/*******************************************************************************
*名称: IRQ_UART1(void)
*功能: 串口UART0接收中断
*******************************************************************************/
void IRQ_UART1(void)
{
  U8 rece;
  if((U1IIR&0x0f)==0x04)
  {  
    rcv_new=1;    //设置接收到新的数据标志
    for(rece=0;rece<8;rece++)
    {
      while(U1LSR&0x01==0);
      rcv_buf[rece]=U1RBR;  //读取FIFO的数据,并清除中断标志
    }
  }
  U1FCR=0x83;            //清零Rx FIFO
  VICVectAddr=0x00;           //中断处理结束
}
/*******************************************************************************
*名称: SendByte()
*功能: 向串口发送字节数据
*入口参数:data       要发送的数据
*******************************************************************************/
void SendByte(U8 data)
{
  U1THR=data;
  while((U1LSR&0x20)==0);       //等待数据发送
}
/*******************************************************************************
*名称: ISendBuf()
*功能: 将缓冲区的数据发送回主机,并等待发送完毕
*******************************************************************************/
void ISendBuf(void)
{
  U8  send;
  for(send=0;send<8;send++)
  {  
    SendByte(rcv_buf[send]);
  }
  while((U1LSR&0x20)==0);               //等待数据发送
  U1FCR=0x85;                           //清零Tx FIFO
}
/*******************************************************************************
*名称: UART0_Ini()
*功能: 初始化串口0. 设置其工作模式及波特率
*入口参数: baud      波特率
           set       模式设置 (UARTMODE数据结构)
*出口参数:返回值为1时表示初始化成功,为0表示参数出错
*******************************************************************************/
void UART1_Ini(U32 baud,UARTMODE set)
{
  U32  bak;
  /*设置串口波特率*/
  U1LCR=0x80;                         //DLAB位置1
  bak=(Fpclk>>4)/baud;
  U1DLM=bak>>8;
  U1DLL=bak&0xff;
  /*设置串口模式*/
  bak=set.datab-5;                    //设置字长度
  if(set.stopb==2) bak|=0x04;          //判断是否为2位停止位
  if(set.parity!=0)
  {
    set.parity=set.parity-1;
    bak|=0x08;     //使能奇偶校验
  }
  bak|=set.parity<<4;                 //设置奇偶校验
  U1LCR=bak;
}
/*******************************************************************************
*名称: main()
*功能: 初始化串口,并等待接收到串口数据
*******************************************************************************/  
int main(void)
{  
   UARTMODE  uart1_set;
   PINSEL0 = 0x00050000;                // 设置P0.8与P0.9连接到UART0
   PINSEL1 = 0x00000000;                 //其他为GPIO口
   IODIR=LED1CON;                   //设置LED控制口为输出,其它I/O为输入
   rcv_new=0;
   uart1_set.datab=8;               //8位数据位
   uart1_set.stopb=2;               //1位停止位
   uart1_set.parity=0;              //无奇偶校验位
   UART1_Ini(9600,uart1_set);       //初始化串口模式,波特率9600
   U1FCR=0x81;                      //使能FIFO,并设置触发点为8字节
   U1IER=0x01;                         //允许RBR中断,即接收中断
   /*设置中断允许*/
   // Assign to IRQ
  VICIntSelect_bit.UART1 = 0;   //分配TIMER0为IRQ型
  // Set interrupt slots
  VICVectAddr1 = (unsigned int) IRQ_UART1;
  //[4:0]请求的中断编号;[5]:使能该编号
  VICVectCntl1_bit.NUMBER = VIC_UART1;  //VIC_TIMER0的值为4
  VICVectCntl1_bit.ENABLED = 1;
  // Timer 0 interrupt enable
  VICIntEnable_bit.UART1 = 1;
   __enable_interrupt();
   while(1)                         //等待中断
   {
     if(1==rcv_new)
     {
       ISendBuf();                    //将接收到的数据发送回主机
       rcv_new=0;
     }     
   }
}

为什么输入8个字节时能正确通信,输入8个以上的字节会出现乱码?---------
---------------------------------
U8 rcv_buf[8];                //UART0数据接收缓冲区
-------------
因为你的接收数据缓冲区只有8个字节 数据溢出了 可以设置大一些 比如rcv_buf[64]

小编,我建议你去看一下UART通信的一直协议知识

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top