这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 瑞萨M32C单片机串口发送问题

共13条 1/2 1 2 跳转至

瑞萨M32C单片机串口发送问题

菜鸟
2009-07-31 10:48:50     打赏

现在用瑞萨M30870单片机 100引脚,采用UART3发送接收数据。我写了两个函数一个初始化串口程序,一个是发送函数。波特率采用19200 数据位:8 停止位:1   无奇偶校验。
void ut_Uart_init(void)
{

 PRCR.PRC2 = 1;
 PD9.PD9_2 = 1;
 PRCR.PRC2 = 1;
 PS3.PS3_2 = 1;
 PSL3.PSL3_2 = 0;

 PRCR.PRC2 = 1;
 PD9.PD9_1 = 0;
 PRCR.PRC2 = 1;
 PS3.PS3_1 = 0;

 S3RIC.all= 0x07;
 S3TIC.all = 0x07;
 U3BRG = 65; 
 U3MR.all = B00000101;  //1 //数据位8停止位1无奇偶校验内部时钟
 U3C0.all = B00010000;  //1 //f1  CTS/RTS无效
 U3C1.all = B00000100;//0x05;  //1 //TXD RXD 使能
   
 U3SMR.all = 0x00;
 U3SMR2.all = 0x00;
 U3SMR3.all = 0x00;
 U3SMR4.all = 0x00;

 S3RIC.all= 0x04;
 S3TIC.all = 0x04;
}
发送函数为:
void ut_UART4_transmit( )
{
 uchar i;
 uchar d_transmit_cmd[15];

 memcpy(d_transmit_cmd,"ABCDEFGHI",9);

 for(i = 0;i < 9;i++){
 
  U3TB = d_transmit_cmd[i];
  U3C1_TE = 1;
  while(U3C1_TI==0);
  
  U3C1_TE = 0;

 }

}
函数中的寄存器是我重新宏定义过的。
但是设备的串口与电脑串口相连没有接收到单片机发送的数据。发送函数在程序运行到某个动作时启动发送功能。请大家帮我看下函数那里写错了。谢谢了




关键词: 瑞萨     单片机     串口     发送     问题    

助工
2009-08-03 12:27:23     打赏
2楼
楼主串口调试中,MCU和电脑串口连接的是什么设备?485转232的转换器?

关于未能接收数据,建议确认下:
发送模式,数据格式,波特率等(在有些文章看到过波特率太高容易出问题,可用9600等)
特别注意接收中断程序,是否发生接收错误,可以通过查看UART接收缓冲寄存器的一些标志位来确定。

菜鸟
2009-08-04 12:09:14     打赏
3楼

 如果你的宏定义没有问题的话,你的发送函数有问题。

首先,你是使用中断发送么?如果不是,你得s3tic为什么不是0?
这个问题很重要,如果使用中断发送的,请上传中断函数。

假设不使用中断:
瑞萨UART采用双寄存器结构(移位寄存器+缓冲寄存器)
TI标志仅表示缓冲寄存器空,而TI=0时移位可能并没有完成,所以此时TE=0的话,将无法发送成功。

正确的流程:
void ut_UART4_transmit(uchar* string, uchar len )
{
  U3C1_TE = 1;  //允许发送
  while ( len > 0 )
  {
    while(U3C1_TI==0);   //等待缓冲寄存器空,可以接受下一个数据
    U3TB = *string;           //写数据
    string ++;                   //下一个数据
    len --;                         //长度--
  }
  while(U3C1_TI==0); //等待缓冲寄存器空
  while(U3C0_TXEPT == 0); //等待移位寄存器空(真正的发送完成)  
  U3C1_TE = 0; //关闭发送
 }


菜鸟
2009-08-05 09:56:50     打赏
4楼

Fishs_new_life 你好。谢谢你的回复。以前一直在用51开发,现在改用瑞萨的M32C开发发现有很多跟51不同的设置。网上找资料也不是很多。请问你有MSN或者其他什么通讯工具吗?想跟你交个朋友。


菜鸟
2009-08-05 11:15:46     打赏
5楼

Fishs_new_life 你好 我没有采用中断发送而是采用查看寄存器的方式发送。你上面的程序有个地方我有些疑惑。 while(U3C1_TI==0); //等待缓冲寄存器空
  while(U3C0_TXEPT == 0); //等待移位寄存器空(真正的发送完成)  这两条语句是否应该放到上面的while循环中。这样才是发送一个字节的完整流程吧。我采用你的流程改写程序后还是没有办法接收到设备发出的信息。进行单步调试的时候发现我在向U3TB赋值后,U3C1_TI却一直为1,而没有变成0。是否是那里还有需要设置的?


菜鸟
2009-08-06 16:01:34     打赏
6楼

不应该放在循环中。我前面说过了,是双buffer结构。所以只需要在最后一个字节保证移位完成就行。


助工
2009-08-20 22:45:27     打赏
7楼
还请 Fishs_new_life 能给出一个使用中断的方式进行发送和接收的程序啊,谢谢。我做的一个发送和接收能实现,但是有些不稳定。

菜鸟
2009-08-22 19:05:47     打赏
8楼

中断比较复杂。尤其是中断发送,个人建议使用中断接收,查询发送。因为接收是不可预测的,而发送使自己主动。
首先需要注意下面3点:
是否允许接收中断:sxtic = 1~7
是否允许可屏蔽中断:asm("FSET I");
是否正确指定中断函数:#pragma interrupt UART3RecvInt (vect = xxx)

其次中断接收需要和主程序结合使用。
下面的例子是使用ring buffer接收
char       ring_buf_w_ptr;
char       ring_buf_r_ptr;
char       ring_buf[256];

main ( )
{
       //此处省略初始化等
       while ( 1 );
       {
            if ( ring_buf_r_ptr != ring_buf_w_ptr )  //如果接收到新数据           
            {
                  //处理
                  ring_buf_r_ptr 
            }
       }
}

#pragma    interrupt    UART3RecvInt
void   UART3RecvInt( )
{
       int  temp_data = u3rb;          //读出数据
       if ( ( ring_buf_r_ptr - ring_buf_w_ptr ) > 1 )  //如果还有足够的空间
       {
             ring_buf[ring_buf_w_ptr] = temp_data;
             ring_buf_w_ptr  ++;
      }
}


助工
2009-08-23 10:43:49     打赏
9楼
Thanks a lot !再品读一下~~  
不过感觉有个地方好像不对:  while(1);  这个语句后面的 ";" 不用的吧。

菜鸟
2009-08-26 11:59:51     打赏
10楼

谢谢qlm指正,确实写错了。。。。。。


共13条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]