主题 : 求教:UART口的多字节数据发送 复制链接 | 浏览器收藏 | 打印
勺饮不器盛沧海,拳石频移磊泰山
级别: 侠客
UID: 15752
精华: 0
发帖: 71
金钱: 355 两
威望: 71 点
综合积分: 142 分
注册时间: 2010-03-09
最后登录: 2010-10-19
楼主  发表于: 2010-04-09 12:31

 求教:UART口的多字节数据发送

大家好,我在做串口通信的实验,之前利用单片机的串口实验成功,现在想利用mini2440的UART0来实现。
问题说明:(1)在网上找到的UART通信程序都是发送字符串的,我现在想发送的是16进制整数,目前已经实现单个字节的发送;实现程序如下:
#include "def.h"
#include "option.h"
#include "2440addr.h"    
#include "2440lib.h"
#include "2440slib.h"      
//================================
static int UartNum=0;   //串口选择的标志位,可以省略,只是方便多个串口选择
#define uchar unsigned char
#define uint unsigned int
//===============================================================
static uchar RcvComDataBuff[8]; //串口接收数据缓冲区
static uchar SndComDataBuff[8]; //串口发送数据缓冲区
static uchar *rcvp=RcvComDataBuff; //接收数据指针
static uchar *sndp=SndComDataBuff; //发送数据指针
//===============================================================
void dely(U32 tt)
{
   U32 i;
   for(;tt>0;tt--)
   {
     for(i=0;i<10000;i++){}
   }
}
//对Uart进行初始化,以所需要的波特率为输入参数
void myUart_Init(int whichuart, int baud)
{
   if(whichuart==0)   //判断是否选择串口0,假如选择串口1,则应该初始化串口1的寄存器
   {
        UartNum=0;   //串口选择的标志位
    rGPHCON = rGPHCON & (~(0xffff)) ;
        rGPHCON = rGPHCON | (0xaaa0) ;
        rGPHUP  = 0x0;  // 使用内部上拉电阻。
    rUFCON0=0x00;   //不使用FIFO
        rUMCON0=0x00;   //不使用自动流控制
    rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
    rUCON0=0x245;   //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止  //信号,传输模式为中断请求模式,接收模式也为中断请求模式。
    rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );
       dely(10);
    }
}

void SndComData(uchar data) //单字节发送数据的函数
{
       if (UartNum ==0)      //判断是否选择串口0,在这里也可以不用这句,
                          //只是方便多个串口选择时用
    {
    myUart_Init(0,9600);//载波模块的波特率为9600
    while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空
    dely(100);
    WrUTXH0(data);    //串口0发送一个字节数据
    }
}    

int Main(int argc, char **argv)
{
    U32 mpll_val=0;
    mpll_val = (92<<12)|(1<<4)|(1);
    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
    ChangeClockDivider(14,12);    
    
    MMU_DisableICache();
    MMU_DisableDCache();

    Port_Init();
    Isr_Init();
    while(1)
    {
        SndComData(0x01);
    }  
   return 0;
}
运行结果:串口调试助手循环打印01
          (2)想利用指针进行一次性4个字节的发送,但是串口调试助手的接收始终是最好的一个字节。实现程序如下:
#include "def.h"
#include "option.h"
#include "2440addr.h"    
#include "2440lib.h"
#include "2440slib.h"      
//================================
static int UartNum=0;   //串口选择的标志位,可以省略,只是方便多个串口选择
#define uchar unsigned char
#define uint unsigned int
//===============================================================
static uchar RcvComDataBuff[8]; //串口接收数据缓冲区
static uchar SndComDataBuff[8]; //串口发送数据缓冲区
static uchar *rcvp=RcvComDataBuff; //接收数据指针
static uchar *sndp=SndComDataBuff; //发送数据指针
//===============================================================
void dely(U32 tt)
{
   U32 i;
   for(;tt>0;tt--)
   {
     for(i=0;i<10000;i++){}
   }
}
//对Uart进行初始化,以所需要的波特率为输入参数
void myUart_Init(int whichuart, int baud)
{
   if(whichuart==0)   //判断是否选择串口0,假如选择串口1,则应该初始化串口1的寄存器
   {
        UartNum=0;   //串口选择的标志位
    rGPHCON = rGPHCON & (~(0xffff)) ;
        rGPHCON = rGPHCON | (0xaaa0) ;
        rGPHUP  = 0x0;  // 使用内部上拉电阻。
    rUFCON0=0x00;   //不使用FIFO
        rUMCON0=0x00;   //不使用自动流控制
    rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
    rUCON0=0x245;   //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止  //信号,传输模式为中断请求模式,接收模式也为中断请求模式。
    rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );
        dely(10);
    }
}

/*******************************************************************/
void SndComData(uchar *p, uchar len) //串口发送数据的函数(多个字节)
{

        if (UartNum ==0)      //判断是否选择串口0,在这里也可以不用这句,
                          //只是方便多个串口选择时用
    {
    myUart_Init(0,9600);//载波模块的波特率为9600
    while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空
    *p = 0x06;
     *(p+1) = 0x00;
     *(p+2) = 0x01;
     *(p+3) = 0x02;
    dely(100);
    while(len)
    {
         WrUTXH0(*p);    //串口0发送数据
      p++;
         len--;
    }
   }    
}

int Main(int argc, char **argv)
{
    
     U32 mpll_val=0;
     mpll_val = (92<<12)|(1<<4)|(1);
     ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
     ChangeClockDivider(14,12);    
     MMU_DisableICache();
     MMU_DisableDCache();
     Port_Init();
     Isr_Init();
     while(1)
    {
        SndComData(sndp,4);
    }  
   return 0;
}
勺饮不器盛沧海,拳石频移磊泰山
级别: 侠客
UID: 4843
精华: 0
发帖: 102
金钱: 810 两
威望: 554 点
综合积分: 204 分
注册时间: 2009-03-31
最后登录: 2012-11-14
1楼  发表于: 2010-04-09 12:41
    myUart_Init(0,9600);//载波模块的波特率为9600
//    while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空
    *p = 0x06;
     *(p+1) = 0x00;
     *(p+2) = 0x01;
     *(p+3) = 0x02;
    dely(100);
    while(len)
    {
    while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空 // try here
         WrUTXH0(*p);    //串口0发送数据

      p++;
         len--;
    }
勺饮不器盛沧海,拳石频移磊泰山
级别: 侠客
UID: 15752
精华: 0
发帖: 71
金钱: 355 两
威望: 71 点
综合积分: 142 分
注册时间: 2010-03-09
最后登录: 2010-10-19
2楼  发表于: 2010-04-11 20:54

 回 1楼(ofourme) 的帖子

实验已成功,太感谢您了!
勺饮不器盛沧海,拳石频移磊泰山
I believe i can fly i can touch the sky
级别: 新手上路
UID: 63528
精华: 0
发帖: 9
金钱: 45 两
威望: 9 点
综合积分: 18 分
注册时间: 2012-02-21
最后登录: 2013-03-07
3楼  发表于: 2012-03-22 17:18
向个位 请教学习!!