查看: 2098|回复: 5

[S12] s12zvh128 sci 中断方式

[复制链接]

该用户从未签到

6

主题

13

帖子

0

注册会员

Rank: 2

积分
128
最后登录
2019-1-26
发表于 2016-4-25 09:40:33 | 显示全部楼层 |阅读模式
我写的sci中断方式,可是不成功,不知道是哪里的问题啊~能不能帮忙看一下
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define BaudRate 9600
void  interrupt 24 SCI0_re(void)
{
unsigned char ch;
ch=SCI_Rx();
SCI_Tx(ch);
}
void SCIinit(void){


  SCI0BD =  BUS_CLOCK / BaudRate ;
            
SCI0CR1 = 0x00;                                         //8位数据位,1位停止位,无校验
SCI0SR2 = 0x00;                                         //极性正转,发送接收可以分开设置
SCI0CR2 = 0x2C;                                         //接收中断使能,使能发送与接收

}

void SCI_Tx(byte TxData)                              //发送函数,几乎不用
{

unsigned char ReadStatus1;                         //为清除标志位,读状态寄存器
ReadStatus1 = SCI0SR1;
SCI0DRH  = 0;
SCI0DRL = TxData;                                   //将待发数据写入寄存器
while( !SCI0SR1_TDRE ){;}                        //等待发送结束                          
      
      
}

byte SCI_Rx()                                           //接收函数
{
if(SCI0SR1_RDRF==1)                              //表明数据从位移寄存器传输到SCI数据寄存器
{
SCI0SR1_RDRF = 1;                               //读取数据寄存器会将RDRF清除  重新置位
return SCI0DRL;                                    //返回数据寄存器的数据
}
}

void main(void) {
   

  /* include your code here */
    System_clock_init();
    SCIinit();
    EnableInterrupts;
    for(;;) {

  } /* loop forever */
  /* please make sure that you never leave main */
}



System_clock_init();为时钟设置初始化,sci查询方式我试过,是可以的,所以时钟初始化和波特率设置应该是没问题的,所以这里我就不贴时钟初始化了。

求好心人帮忙看看~谢谢了~

我知道答案 目前已有5人回答
回复

使用道具 举报

  • TA的每日心情
    慵懒
    2018-11-15 16:18
  • 签到天数: 39 天

    [LV.5]常住居民I

    16

    主题

    259

    帖子

    3

    高级会员

    Rank: 4

    积分
    993
    最后登录
    2023-1-6
    发表于 2016-4-25 10:30:12 | 显示全部楼层
      你是和外部设备通讯还是开那个LOOP寄存器自循环测试,如果是自循环测试,你要先发字节才能进接收中断,但你没先发字节。如果是和外部设备通讯的话,那就要看手册了,看有没有什么寄存器配置错了,而且外部设备是不是先发数据,tx/rx线连对了没(一个设备的tx要连到另外个设备的rx)。还有中断里尽量别嵌套函数,也别把发送的执行代码放中断,你可以中断里设个变量置1,然后主程序里判断那变量等于1不,等于1就执行发送数据,然后清零那个变量。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    6

    主题

    13

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2019-1-26
     楼主| 发表于 2016-4-25 10:57:44 | 显示全部楼层
    小华-415468 发表于 2016-4-25 10:30
    你是和外部设备通讯还是开那个LOOP寄存器自循环测试,如果是自循环测试,你要先发字节才能进接收中断, ...

    我不是自循环测试,我是MCU连到PC,然后PC在串口助手中发送数据,MCU接收后再发送到PC,在串口助手中显示。原先使用查询方式时,发送多字节,会经常出现数据丢失的情况,这又是为什么呢?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-11-15 16:18
  • 签到天数: 39 天

    [LV.5]常住居民I

    16

    主题

    259

    帖子

    3

    高级会员

    Rank: 4

    积分
    993
    最后登录
    2023-1-6
    发表于 2016-4-25 13:33:14 | 显示全部楼层
    姚荨沭 发表于 2016-4-25 10:57
    我不是自循环测试,我是MCU连到PC,然后PC在串口助手中发送数据,MCU接收后再发送到PC,在串口助手中显示 ...

    #include <hidef.h> /* for EnableInterrupts macro */
    #include "derivative.h" /* include peripheral declarations */
    #define BaudRate 9600unsigned char ch;
    unsigned char RxFlag=0;
    unsigned char TxData;
    void  interrupt 24 SCI0_re(void)
    {
    if(SCI0SR1_RDRF==1)                              //表明数据从位移寄存器传输到SCI数据寄存器
    {   (void)SCISR1;
      //SCI0SR1_RDRF = 1;                               //读取数据寄存器会将RDRF清除  重新置位
      ch=SCI0DRL;                                    //返回数据寄存器的数据
      RxFlag=1;
    }
    }
    void SCIinit(void){


      SCI0BD =  BUS_CLOCK / BaudRate ;
                
    SCI0CR1 = 0x00;                                         //8位数据位,1位停止位,无校验
    SCI0SR2 = 0x00;                                         //极性正转,发送接收可以分开设置
    SCI0CR2 = 0x2C;                                         //接收中断使能,使能发送与接收

    }





    void main(void) {
       

      /* include your code here */
        System_clock_init();
        SCIinit();
        EnableInterrupts;
        for(;;)
      {
       if(RxFlag==1)
      {
          if(SCI0SR1_TDRE==1)
          {
              SCICR2_RIE=0;
              SCI0DRH  = 0;
              SCI0DRL = TxData;                                   //将待发数据写入寄存器
              while( !SCI0SR1_TDRE ){;}                        //等待发送结束                          
              SCICR2_RIE=1;
          }
         RxFlag=0;
      }
      } /* loop forever */
      /* please make sure that you never leave main */
    }





    这样试试吧。

    回复 支持 反对

    使用道具 举报

    该用户从未签到

    6

    主题

    13

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2019-1-26
     楼主| 发表于 2016-4-25 16:51:59 | 显示全部楼层
    小华-415468 发表于 2016-4-25 13:33
    #include  /* for EnableInterrupts macro */
    #include "derivative.h" /* include peripheral declarati ...

    还是不行~不过有个奇怪的现象,就是我用串口助手不断的发送数据,无规律间歇性的会收到数据,不过收到数据的频率很小。
    还有想请教的,中断怎么初始化,我看芯片的说明书不是很懂。。
    麻烦你了,非常感谢你能帮我看程序,还给我支招~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-11-15 16:18
  • 签到天数: 39 天

    [LV.5]常住居民I

    16

    主题

    259

    帖子

    3

    高级会员

    Rank: 4

    积分
    993
    最后登录
    2023-1-6
    发表于 2016-4-26 08:54:07 | 显示全部楼层
    看你的初始化也没问题,我帮你写的这代码是工作于半双工的状态,如果发的时候就把收数据的中断关了,等发完数据再把收数据的中断开启。

      if(RxFlag==1)
      {
          if(SCI0SR1_TDRE==1)
          {
              SCICR2_RIE=0;
              SCI0DRH  = 0;
              SCI0DRL = TxData;                                   //将待发数据写入寄存器
              while( !SCI0SR1_TDRE ){;}                        //等待发送结束                          
              SCICR2_RIE=1;
          }
         RxFlag=0;
      }

    把以下这句
    SCI0DRL = TxData;                                   //将待发数据写入寄存器
    改成
    SCI0DRL = ch;

    那样你发给单片机啥数据,就回你啥数据了,前提是你要一个字节发完间隔几毫秒,如果你要发一串字节,中断里要放个数组接受这一串,等这一串数据收满再置RxFlag=1
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 07:45 , Processed in 0.122712 second(s), 25 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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