OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12432|回复: 4

关于430G2553 IO模拟串口接收问题

[复制链接]

1

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2014-11-27
在线时间
88 小时
发表于 2020-5-13 15:02:22 | 显示全部楼层 |阅读模式
10金钱
   现在项目用到430G2553接收3路串口数据,目前使用定时器加外部中断模拟串口,发现3路数据同时发送时,数据会丢失。急需解决。如果用输入捕获来模拟串口,是否可以避免此问题。
   模拟串口代码如下:
#include "dev_duart.h"
#include "dev_TimeA1.h"
#include "UserData.h"
#include "dev_key.h"
#include "paramSave.h"
#include "config.h"

  // 模拟串口参数定义
  #define DuartChannelNum         4                       // 模拟串口通道数量
  #define DuartNotEnable          0                       // 模拟串口通道是否反相
  #define DuartBaurdB             128                       // 波特率倍数
  #define DuartReadB              16                       // 读数位置
//8 和6 时 为2048波特率 7和4时为2400波特率


#ifndef DuartNotEnable
#error "没有定义DuartNotEnable(通道输入是否反相)"
#endif
#ifndef DuartChannelNum
#error "没有定义DuartChannelNum(通道数量)"
#endif
#ifndef DuartBaurdB
#error "没有定义DuartBaurdB(波特波周期数)"
#endif
#ifndef DuartReadB
#error "没有定义DuartReadB(读数周期数)"
#endif
//通道PIN定义(P2)

#define dUartChannelAll (BIT0|BIT1|BIT3|BIT4)
const uint8_t  dUartChannelTable[DuartChannelNum] = {BIT4,BIT0,BIT1,BIT3};
DUartInfo       dUartInfo[DuartChannelNum];
uint8_t        dUartState;                  //打开状态标志(与通道引脚对应)
uint8_t        dUartTimeState;              //定时器打开状态

inline void DUartOpenPinInt(uint16_t channel);
inline void DUartClosePinInt(uint16_t channel);
uint8_t  DuartReadB_buf[3]= {94,95,96};

void TimeA1Init(void)                          //定时30us                                                
{
  TA1CTL = TASSEL_1 | ID_0 | TACLR;             //30.5us/(1000000us/32768)=1
  TA1CCTL0 = CCIE;
  TA1CCR0 = 1;
}

#if TIMEA1_USER_DEF_ENALBE != 1
void TimeA1Open(uint8_t id)
{
  if((id != 0) && timeA1State == 0)
    TA1CTL |= MC_1 | TACLR;
  timeA1State |= id;
}

void TimeA1Close(uint8_t id)
{
  timeA1State &= ~id;
  if(timeA1State == 0)
    TA1CTL &= ~MC_3;
}
#endif

#pragma vector = TIMER1_A0_VECTOR
__interrupt void Time1IRQ(void)
{
  if((timeA1State & TimeA1DUart) != 0)
    if(DUartTime1IRQ())
      LPM3_EXIT;
}


void DUartInit(void)
{
  TimeA1Init();
#if DuartNotEnable == 1
  P2IES &= ~dUartChannelAll;
#else
  P2IES |= dUartChannelAll;     //下降沿中断
#endif
}

void DUartOpen(uint16_t channel)
{
  if((RunParGet()->state & GErrIsAMode) == 0)
  {
    if(channel >= DuartChannelNum)
      return;
  }
  else
  {
    if(channel >= DuartChannelNum - 1)
      return;
  }
  dUartState |= dUartChannelTable[channel];
  DUartOpenPinInt(channel);
}

void DUartClose(uint16_t channel)
{
}

void DUartOpenTimer(uint16_t channel)
{
  if((dUartTimeState & dUartChannelTable[channel]) != 0)
    return;
  dUartTimeState |= dUartChannelTable[channel];
  if(dUartTimeState == dUartChannelTable[channel])
    TimeA1Open(TimeA1DUart);
}

void DUartCloseTimer(uint16_t channel)
{
  dUartTimeState &= ~dUartChannelTable[channel];
  if(dUartTimeState == 0)
    TimeA1Close(TimeA1DUart);
}

//打开通道引脚中断
inline void DUartOpenPinInt(uint16_t channel)
{
  P2IFG &= ~dUartChannelTable[channel];
  P2IE |= dUartChannelTable[channel];
}

//打开通道引脚中断
inline void DUartClosePinInt(uint16_t channel)
{
  P2IE &= ~dUartChannelTable[channel];
}

void DUartStartReceive(uint16_t channel)
{
  if(channel >= DuartChannelNum)
    return;
  dUartInfo[channel].curbit = 0;
  dUartInfo[channel].curTimebit = 0;
  dUartInfo[channel].rdata = 0;
  dUartInfo[channel].rReadyFlag = false;
  DUartOpenTimer(channel);
}

void DUartReadBit(uint16_t channel)
{
  if(channel >= DuartChannelNum)
    return;
}

#pragma vector = PORT2_VECTOR
__interrupt void Port2Int(void)
{
  uint8_t num = DuartChannelNum;
  if((RunParGet()->state & GErrIsAMode) != 0)
    num --;
  for(uint8_t i = 0;i < num;i++)
  {//检测全部通道
    if(P2IFG == 0)
      break;
    if((P2IFG & dUartChannelTable[i]) != 0)
    {//当前通道产生了中断,开始接收数据
      DUartClosePinInt(i);
      P2IFG &= ~dUartChannelTable[i];
      DUartStartReceive(i);
    }
  }
}

bool DUartTime1IRQ(void)
{
  bool flag = false;
  uint8_t PinIn = P2IN;
  uint8_t num = DuartChannelNum;
  if((RunParGet()->state & GErrIsAMode) != 0)
    num --;
  for(uint8_t i = 0;i < num;i++)
  {//4个通道的定时
    if((dUartTimeState & dUartChannelTable[i]) != 0)
    {//该通道已经启动定时器
      dUartInfo[i].curTimebit++;
      if(dUartInfo[i].curTimebit >= DuartBaurdB)
        dUartInfo[i].curTimebit = 0;
      if(dUartInfo[i].curTimebit == DuartReadB)//((DuartBaurdB + 1) >> 1) + 1)
      {//当时为一个位的第5个时钟周期,进行数据的读取
        if(dUartInfo[i].curbit == 9)
        {//读取停止位
#if DuartNotEnable == 1
          if((PinIn & dUartChannelTable[i]) == 0)
#else
          if((PinIn & dUartChannelTable[i]) != 0)
#endif
          {
            dUartInfo[i].rReadyFlag = true;
            flag = true;
            WriteOne(i,dUartInfo[i].rdata);
          }
          dUartInfo[i].curbit = 10;
          DUartCloseTimer(i);
          DUartOpenPinInt(i);
        }
        else
        {//起始位及数据
          dUartInfo[i].rdata >>= 1;
#if DuartNotEnable == 1
          if((PinIn & dUartChannelTable[i]) == 0)
#else
          if((PinIn & dUartChannelTable[i]) != 0)
#endif
            dUartInfo[i].rdata |= 0x80;
          dUartInfo[i].curbit ++;
        }
      }
    }
  }
  return flag;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5562

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10541
金钱
10541
注册时间
2017-2-18
在线时间
1908 小时
发表于 2020-5-13 17:17:23 | 显示全部楼层
回复

使用道具 举报

1

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2014-11-27
在线时间
88 小时
 楼主| 发表于 2020-5-13 17:50:54 | 显示全部楼层

有没有好的建议,目前在调试输入捕获。
回复

使用道具 举报

3

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
332
金钱
332
注册时间
2019-6-3
在线时间
102 小时
发表于 2020-5-29 01:01:06 来自手机 | 显示全部楼层
模拟串口波特率高不了的。之前我模拟串口只能做到9600
回复

使用道具 举报

1

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2014-11-27
在线时间
88 小时
 楼主| 发表于 2020-5-30 14:50:11 | 显示全部楼层
nonoxy2019 发表于 2020-5-29 01:01
模拟串口波特率高不了的。之前我模拟串口只能做到9600

已经调到最低,128
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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