搜索
bottom↓
回复: 5

9234模拟串口源代码

[复制链接]

出0入0汤圆

发表于 2010-7-29 13:26:49 | 显示全部楼层 |阅读模式
由于9234只有一个通讯口,所以在需要多个通讯口的场合就很不方便,换芯片的话成本就会增加很多,所以就研究了模拟串口的方法。

在该方案中,波特率采用4800,1位起始位,8位数据位,偶校验,两位停止位,波特率是用定时器来控制的,经过测试,在常温和70度左右的情况下,通讯出错率均小于1%。基于硬件限制,收发数据依然采用P43,P44口,该口工作于I/O端口状态

希望这个程序对大家有用。

欢迎大家加我的QQ:386132185,留言说明是在学习nec的,我们可以互相学习,共同提高

另欢迎大家加入  12580452 QQ群。


由于本人经验有限,程序中难免会有缺陷,欢迎大家拍砖。



点击此处下载 ourdev_571508.pdf(文件大小:59K) (原文件名:9234模拟串口通讯.pdf)



/*******************************************************************************
//功能:        模拟UART,当芯片自身的通讯口有限时,可以用该方法模拟通讯
//数据模式:    波特率:4800,1位起始位,8位数据位,偶校验,2位停止位,
//              经过测试,通讯出错率小于1%
//              基于硬件限制,该程序中用于模拟通讯的口仍选择P43,P44口,P43,P44口
//              工作在I/O口状态
//作者:        范 坤
//公司:        上海耘和空调科技有限公司
//完成日期:    2010.07.28
*******************************************************************************/
#include<io78f9234.h>
#include<intrinsiCS.h>

/*--------------------选项字节配置------------------------*/
/*-----------------------------------------------------------
内部时钟,
-----------------------------------------------------------*/
#pragma location = 0X0080
__root const unsigned char XUAN=0X9c;//选项字节,设置实用内部高速时钟电路,低速内部振荡器时钟可由软件停止

#define uchar  unsigned char
#define uint   unsigned int
#define ushort   unsigned short

/*以下声明是对寄存器的操作,分别对寄存器的某一位清零或置一*/
#define        clearbit(Reg, ClrBitMap)        Reg &= ~ClrBitMap//清零操作
#define        setbit(Reg, SetBitMap)        Reg |= SetBitMap//置1操作

#define        DI()        __disable_interrupt()//屏蔽所有中断
#define        EI()        __enable_interrupt()//使能所有中断
#define        NOP()        __no_operation()//空操作


#define P00 P0_bit.no0
#define P01 P0_bit.no1
#define P02 P0_bit.no2
#define P03 P0_bit.no3

#define P120 P12_bit.no0
#define P121 P12_bit.no1
#define P122 P12_bit.no2
#define P123 P12_bit.no3

#define P130 P13_bit.no0

#define P20 P2_bit.no0
#define P21 P2_bit.no1
#define P22 P2_bit.no2
#define P23 P2_bit.no3

#define P30 P3_bit.no0
#define P31 P3_bit.no1
#define P32 P3_bit.no2
#define P33 P3_bit.no3

#define P40 P4_bit.no0
#define P41 P4_bit.no1
#define P42 P4_bit.no2
#define P43 P4_bit.no3
#define P44 P4_bit.no4
#define P45 P4_bit.no5
#define P46 P4_bit.no6
#define P47 P4_bit.no7

#define TXD P4_bit.no3
#define RXD P4_bit.no4


__saddr uchar sendbuffer[4];//发送缓存
__saddr uchar recbuffer[4];//接收缓存
__saddr uchar rxd_count;//该组参数用于记录接收或发送的数据的位数



void clock();//时钟初始化函数
void PORT_Init();//端口初始化函数
void TMH1_Init();//定时器初始化函数
void main();//主函数
void TMH1_Start();//启动定时器函数
void TMH1_Stop();//停止定时器函数
void delayms(uint ms);//准确延时1ms,当ms=1时

void send_data(uchar data);//发送数据函数
uchar rec_data();//接收数据函数,返回值为接收到数据的内容



/****简单延时函数,在该延时函数中,当ms=1时,可以准确实现延时1ms***************/
void delayms(uint ms)//准确延时1ms,当ms=1时
{
  uint i,j;
  for(i=0;i<ms;i++)
    for(j=0;j<460;j++);
}

/**********************时钟初始化函数,系统时钟为8MHz***************************/
void clock()
{
  PPCC=0X00;
  PCC=0X00;
}

/******************************端口初始化函数**********************************/
void PORT_Init(void)
{
        clearbit(PM3,0X02);//P31设定为输出口
        clearbit(PM4,0X28);//P43,P45设定为输出口
        setbit(PM4,0X10);//P44设定为输入口
        
        setbit(P4, 0x08);                /* port setting in transmit/receive mode */
        
        PM2=0X00;
}


/********************定时器初始化函数,定时204us,实现4800波特率***************/
void TMH1_Init(void)
{
        TMHE1 = 0;        /* disable TMH1 counter */
        TMMKH1 = 1;        /* disable INTTMH1 */
        TMIFH1 = 0;        /* enable INTTMH1 */
        /* TMH1 interval mode */
        TMHMD1 = 0x20;
        CMP01 = 0x68;
}

/***************************启动定时器函数*************************************/
void TMH1_Start(void)
{
        TMHE1 = 1;        /* enable TMH1 counter */
}

/***************************停止定时器函数*************************************/
void TMH1_Stop(void)
{
        TMHE1 = 0;        /* disable TMH1 counter */
}

/********************************发送数据函数**********************************/
void send_data(uchar data)
{
  uchar txd_count=0;//该参数用于记录发送数据的位数
  uchar even_count=0;//该参数用于记录发送的数据位1的位数,从而判断发送的偶校验位的值
  P31=1;//发送数据使能
  NOP();
  
  /*************发送起始位,1位起始位,低电平***********/
  TXD=0;
  TMH1_Start();//开定时器中断
  while(!TMIFH1) //没有产生中断就等待
    NOP();
  TMIFH1=0;

  /*************发送数据位,8位数据位***********/
  while(txd_count<8)
  {
    if(data&0x01)
    {
      TXD=1;
      even_count++;
    }
    else
      TXD=0;
   
    TMH1_Start();//开定时器中断
    while(!TMIFH1)
      NOP();
    TMIFH1=0;
    txd_count++;
    data=data>>1;
  }
  
  /*************发送校验位,在该系统中采用偶校验的方式***********/
  if(even_count%2) TXD=1;
  else TXD=0;
  while(!TMIFH1)
    NOP();
  TMIFH1=0;
  TMH1_Start();//开定时器中断
  
  /*************发送停止位,两位停止位***********/
  TXD=1;
  while(!TMIFH1)
    NOP();
  TMIFH1=0;
  TMH1_Start();//开定时器中断
  TXD=1;
  while(!TMIFH1)
    NOP();
  TMIFH1=0;
  TMH1_Stop();
}

/********************************接收数据函数**********************************/
uchar rec_data()
{
  uchar data=0xff;//该参数用于记录接收到的数据
  uchar rxd_count=8;//该参数用于记录接收数据的位数
  uchar even_count=0;//该参数用于记录发送的数据位1的位数,从而判断发送的偶校验位的值
  uchar even;//该参数用于存储接收到的校验位
  uchar a,b;//该组参数用于存储接收到的停止位
  
  P31=0;//接收数据使能
  while(RXD&0X01)//等待起始位
  {
    NOP();
  }
  CMP01 = 0x9c;//错后半位,抗干扰
  TMH1_Start();//开定时器中断
  while(!TMIFH1) //没有产生中断就等待
    NOP();
  TMIFH1=0;
  while(rxd_count)
  {
    data>>=1;//低位在前传送
      
    if(RXD)
    {
      data=data|0X80;
      even_count++;
    }
    else
    {
      data=data|0X00;
    }
      
    CMP01 = 0x68;//保持错后半位检测
    TMH1_Start();//开定时器中断
    while(!TMIFH1) //没有产生中断就等待
      NOP();
    TMIFH1=0;
    rxd_count--;
  }
  even=RXD;//接收到的校验位
  TMH1_Start();//开定时器中断
  while(!TMIFH1) //没有产生中断就等待
    NOP();
  TMIFH1=0;
  a=RXD;
  while(!TMIFH1) //没有产生中断就等待
    NOP();
  TMIFH1=0;
  b=RXD;
  while(!TMIFH1) //没有产生中断就等待
    NOP();
  TMIFH1=0;
  
  TMH1_Stop();
  
  recbuffer[0]=data;
  if(even&&a&&b)
    return 0;
  else
    return 1;
}

/************************************主函数*************************************/
void main()
{
  DI();//关总中断
  LSRSTOP=0x01;//停止低速内部振荡器
  WDTM=0X77;//屏蔽看门狗
  clock();//时钟初始化
  PORT_Init();//端口初始化
  TMH1_Init();//定时器初始化
  EI();//开总中断
  while(1)
  {
    rec_data();
    send_data(recbuffer[0]);
    delayms(10);
    /*------------------------
    for(uchar i=0;i<8;i++)
    {
      P45=recbuffer[0]&0x01;
      recbuffer[0]=recbuffer[0]>>1;
      delayms(10);
    }
    -----------------------*/
  }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2010-8-13 11:39:02 | 显示全部楼层
留个记号,顶!

出0入0汤圆

 楼主| 发表于 2010-8-25 09:36:23 | 显示全部楼层
自己顶一下

出0入0汤圆

发表于 2010-12-31 15:01:53 | 显示全部楼层
有需要 F9234 开发板的联系 QQ:277581646
提供技术支持
http://ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4454176&bbs_page_no=1&bbs_id=3013

出0入0汤圆

发表于 2011-2-7 21:08:44 | 显示全部楼层
谢谢楼主分享快乐,学习一下。

出0入0汤圆

发表于 2011-2-15 11:50:36 | 显示全部楼层
好东西,谢谢分享
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 07:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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