找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5537|回复: 9
打印 上一主题 下一主题
收起左侧

大佬们,有人能把STC12C5A60S2的C语言程序翻译成STC89C52的吗?

[复制链接]
跳转到指定楼层
楼主
ID:217180 发表于 2017-7-5 07:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    各位前辈,我最近在做一个用STC89C52和PN532的NFC身份识别系统,我在网上找到了一个用STC12C5A60S2做的,只是我对STC12C5A60S2了解极少,再加上我的单片机处于刚刚起步阶段,所以虽然有程序但是几乎做不到两个单片机相互翻译,时间催的又紧,所以说只能向各位大佬求助了,如果各位大佬能不吝赐教,晚辈在此不胜感激并将程序好好钻研。我看看能不能把程序贴出来。
********************************************************************************
* STC12C5A60S2控制PN532进行寻卡操作
* STC12C5A60S2通过UART与PN532相连
* 通过中断实现接收UART数据,并通过定时判断PN532的响应是否超时
********************************************************************************/
#include "reg52.h"
#include <intrins.h>
#define ERR_NO        0
#define ERR_TIMEOUT   1
#define ERR_SENDDATA  2
#define ERR_RECVACK   3
#define ERR_RECVDATA  4
//-----------------------------UART1部分使用的全局变量---------------------------
xdata unsigned char gPn532Data[100];            //13.56M RF数据缓存
xdata unsigned char *gpPn532RxBuf, gPn532RxLen; //用于中断函数处理接收buf
xdata unsigned char gi;     //用于接收数据与接收ack之间进行区别
//-------------------------------------------------------------------------------
unsigned char gTimeMult;
unsigned char gTimeOutFlag;
unsigned char gUart1RecvFlag;
sbit p25 = P2^5;
void C51InitIo(void)
{   
P2M0 |= 0x20;
P2M1 |= 0x00;//配置P2.5为强上拉输出
}
//定时时间=num*25ms
void C51InitTimer(unsigned char num)
{
//AUXR |= 0xC0;//bit7->T0x12:0->12T,1->1T;bit6->T1x12:0->12T,1->1T,默认情况下是传统8051速度
TMOD |= 0x01;
TH0 = 0x4C;
TL0 = 0x00;//0x4C00=19456,(65536-19456)*12/22118400=0.025s=25ms
gTimeMult = num;//25*40=1000ms=1s
ET0 = 1;
TR0 = 1;
}
void C51StopTimer()
{
TR0 = 0;
}
/**************************************************
Function: init_uart();
Description:
  set uart working mode,
  使用独立波特率发生器作为波特率发生器
**************************************************/
void C51InitUart(void)
{
AUXR |= 0x18; //BRTR=1,启动独立波特率发生器,S2SMOD=1,串口2波特率*2,S1BRS=1,串口1使用独立波特率发生器作为波特率发生器,S1BRS=0,串口1使用定时器1作为波特率发生器
     
SCON |= 0x50; //UART1工作于模式1(8位uart,加上起始位与停止位共10位),可变速率f=((2^SMOD)/32)*BRT,ren==1->允许串行接收
PCON |= 0x80; //smod=1,
TMOD |= 0x20; //定时器工作与方式2,由TR1控制定时器的开启与关闭
TH1   = 0xFF; //22.1184MHz:0xF4->9600, 0xFA->19200, 0xFD->38400, 0xFE->57600, 0xFF->115200
TL1   = 0xFF;
TR1   = 1;  //启动定时器1   
ES    = 1;     //允许串口1中断
S2CON |= 0x50; //UART2工作于模式1(8位uart,加上起始位与停止位共10位),可变速率f=((2^S2SMOD)/32)*BRT,ren==1->允许串行接收  
BRT    = 0xF4; //BRTx12=0;0xFF->115200,0xF4->9600,0xA0->1200
IE2   |= 0x01; //允许串口2中断
}
//串口1发送一个字节函数
void C51Uart1SendByte(unsigned char num)
{
ES = 0;  
TI = 0;
SBUF = num;
while (0==TI);
TI = 0;
ES = 1;
}
//---------串口2发送与接收一个字节函数----------
void C51Uart2SendByte(unsigned char num)
{
IE2   &= 0xFE; //允许串口2中断,需要增加关闭、打开中断语句,不然串口2工作不正常
S2CON = S2CON&0xFD;//清除发送中断标志
S2BUF = num;
while (0==(S2CON&0x02));//等于1说明发送完成
S2CON = S2CON&0xFD;//清除发送中断标志
IE2   |= 0x01; //允许串口2中断
}
//延时n*1us函数
void C51Delay1us(unsigned short n)
{
while (--n)
{
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}
}
/*****************************************************************
* 函数名:  PN532SendData
* 函数功能:主控器向PN532发送数据
* 输入参数:
pBuf:需要发送给PN532的帧数据
len: pBuf的长度
* 输出参数:
        返回是否成功标志
            成功:SUCCESS
            失败:相应的错误代码
********************************************************************/
unsigned char PN532SendData(unsigned char *pBuf, unsigned char len)
{
unsigned char i;
WDT_CONTR = 0x3F;
for (i=0; i<len; i++)
{
  C51Uart1SendByte(pBuf);
}      
    return ERR_NO;
}
/***************************************************
* 函数名:  PN532RecvData
* 函数功能:主控器从PN532接收数据
* 输入参数:
        
* 输出参数:
        pBuf:
            接收帧缓存
        返回是否成功标志
            成功:SUCCESS
            失败:相应的错误代码
***************************************************/
unsigned char PN532RecvData(unsigned char *pBuf)
{  
gTimeOutFlag = 0;
gUart1RecvFlag = 0;
C51InitTimer(4);
gpPn532RxBuf = pBuf;        //Start of RX buffer
    gPn532RxLen = 6;            // Load RX byte counter
gi = 0;
while (!(gTimeOutFlag||gUart1RecvFlag));//只要有一个为1则退出循环
C51StopTimer();
if (1==gUart1RecvFlag)
{
     return ERR_NO;
}
else
{
  return ERR_TIMEOUT;
}
}
/****************************************
* 函数名:  PN532SendAck
* 函数功能:主控器向PN532发送ACK帧
* 输入参数:
* 输出参数:
        返回是否成功标志
            成功:SUCCESS
            失败:相应的错误代码
*****************************************/
unsigned char PN532SendAck()
{  
unsigned char pAckBuf[6] = {0x00,0x00,0xFF,0x00,0xFF,0x00};
unsigned char i;
for (i=0; i<6; i++)
{
  C51Uart1SendByte(pAckBuf);
}   
    return ERR_NO;
}
/***********************************************
* 函数名:  PN532RecvAck
* 函数功能:主控器从PN532接收ACK帧
* 输入参数:
* 输出参数:
        pBuf:
            接收ACK帧缓存
        返回是否成功标志
            成功:SUCCESS
            失败:相应的错误代码
*************************************************/
unsigned char PN532RecvAck(unsigned char *pBuf)
{  
gTimeOutFlag = 0;
gUart1RecvFlag = 0;
C51InitTimer(1);
gpPn532RxBuf = pBuf;        //Start of RX buffer
    gPn532RxLen = 6;            // Load RX byte counter
gi = 0;
while (!(gTimeOutFlag||gUart1RecvFlag));//只要有一个为1则退出循环
C51StopTimer();
if (1==gUart1RecvFlag)
{
     return ERR_NO;
}
else
{
  return ERR_TIMEOUT;
}
}
/*********************************************************************************************************
* 函数名:  SAMConfiguration
* 函数功能:设置PN532的内部参数
* 输入参数:
mode:
      0x01:normal mode
      0x02:virtual mode
      0x03:wired mode
      0x04:dual mode
timeout:
      0x00:不使用timeout
      0x01-0xFF:超时值
irq:
      0x00:不使用P70_IRQ
      0x01:使用P70_IRQ
* 输出参数:
成功:ERR_NO
        失败:ERR_RECVACK,ERR_RECVDATA
* 输入输出参数:
        pRfBuf:输入,用于存放输入参数的缓存,从外部传入,用于解决在函数内部定义过大的数组问题
                输出,存放从PN532接收的结果
**********************************************************************************************************/
unsigned char SAMConfiguration(unsigned char *pRfBuf, unsigned char mode, unsigned char timeout, unsigned char irq)
{
    unsigned char temp;
    unsigned char s;
    pRfBuf[0] = 0x00; //前导码
    pRfBuf[1] = 0x00; //包开始标志2个字节
    pRfBuf[2] = 0xFF;
    pRfBuf[3] = 3 + 1 + 1;//len + 1字节的PD0 + 1字节的TFI
    pRfBuf[4] = 0x100-pRfBuf[3];
    pRfBuf[5] = 0xD4; //方向标示
    temp = pRfBuf[5];
    pRfBuf[6] = 0x14; //命令码
    temp += pRfBuf[6];
    pRfBuf[7] = mode;
    temp += pRfBuf[7];
    pRfBuf[8] = timeout;
    temp += pRfBuf[8];
    pRfBuf[9] = irq;
    temp += pRfBuf[9];
   
    pRfBuf[10] = 0x100 - temp; //DCS
    pRfBuf[11] = 0x00;
   
    //底层发送函数
    s = PN532SendData(pRfBuf,12);
    if (s!=ERR_NO)
    {
        return ERR_SENDDATA;
    }
    s = PN532RecvAck(pRfBuf);
    if (s!=ERR_NO)
    {
        return ERR_RECVACK;
    }
    s = PN532RecvData(pRfBuf);
    if (s!=ERR_NO)
    {
        return ERR_RECVDATA;
    }
   
    return ERR_NO;
}
/****************************************************************************************
* 函数名:  InListPassiveTarget
* 函数功能:PN532检测卡
* 输入参数:
maxTag:
            PN532最大初始化卡的个数,PN532一次只能同时处理2张卡         
brty:
            0x00 : 106 kbps type A (ISO/IEC14443 Type A),
            0x01 : 212 kbps (FeliCa polling),
            0x02 : 424 kbps (FeliCa polling),
            0x03 : 106 kbps type B (ISO/IEC14443-3B),
            0x04 : 106 kbps Innovision Jewel tag.
        pData:
* 输出参数:
成功:ERR_NO
        失败:ERR_RECVACK,ERR_RECVDATA
* 输入输出参数:
        pRfBuf:输入,用于存放输入参数的缓存,从外部传入,用于解决在函数内部定义过大的数组问题
                输出,存放从PN532接收的结果
*****************************************************************************************/
unsigned char InListPassiveTarget(unsigned char *pRfBuf, unsigned char maxTag, unsigned char brty,
                                  unsigned char *pData, unsigned char len)
{
    unsigned char i,temp;
    unsigned char s;
    pRfBuf[0] = 0x00; //前导码
    pRfBuf[1] = 0x00; //包开始标志2个字节
    pRfBuf[2] = 0xFF;
    pRfBuf[3] = len + 1 + 1 + 1 + 1;//len + 1字节的maxTag + 1字节的brty + 1字节的PD0 + 1字节的TFI
    pRfBuf[4] = 0x100-pRfBuf[3];
    pRfBuf[5] = 0xD4; //方向标示
    temp = pRfBuf[5];
    pRfBuf[6] = 0x4A; //命令码
    temp += pRfBuf[6];
    pRfBuf[7] = maxTag;
    temp += pRfBuf[7];
    pRfBuf[8] = brty;
    temp += pRfBuf[8];
   
    for (i=0; i<len; i++)
    {
        pRfBuf[9+i] = pData;
        temp  += pData;
    }
   
    pRfBuf[9+i] = 0x100 - temp; //DCS
    pRfBuf[9+i+1] = 0x00;
   
    //底层发送函数   
    s = PN532SendData(pRfBuf,9+i+1+1);
    if (s!=ERR_NO)
    {
        return ERR_SENDDATA;
    }
    s = PN532RecvAck(pRfBuf);
    if (s!=ERR_NO)
    {
        return ERR_RECVACK;
    }
    s = PN532RecvData(pRfBuf);
    if (s!=ERR_NO)
    {
        return ERR_RECVDATA;
    }
   
    return ERR_NO;
}
        
void main()
{
unsigned char i,s;
C51InitIo();
C51InitUart();
     
WDT_CONTR = 0x3F;//使能看门狗、清看门狗标志、空闲模式计数、分频系数(scale:bit2-bit0),溢出时间=(12*scale*32768)/Fosc
   
EA = 1;   //cpu中断总允许
p25 = 0;
C51Delay1us(60000);
C51Delay1us(60000);
C51Delay1us(60000);
C51Delay1us(60000);
C51Delay1us(60000);
p25 = 1;
gTimeOutFlag = 0;
gUart1RecvFlag = 0;
//--------------唤醒PN532----------------
C51Uart1SendByte(0x55);
C51Uart1SendByte(0x55);
C51Uart1SendByte(0x00);
C51Uart1SendByte(0x00);
C51Uart1SendByte(0x00);
SAMConfiguration(gPn532Data,1,0,1);
for (i=0; i<gPn532Data[3]+7; i++)
{
  C51Uart2SendByte(gPn532Data);
}
//---------------------------------------
while(1)
{
  WDT_CONTR = 0x3F;
  
  s = InListPassiveTarget(gPn532Data,1,0,0,0);
  if (ERR_NO==s)
  {
   for (i=0; i<gPn532Data[3]+7; i++)
   {
    C51Uart2SendByte(gPn532Data);
   }
   p25 = 0;
   C51Delay1us(60000);
   C51Delay1us(60000);
   C51Delay1us(60000);
   C51Delay1us(60000);
   C51Delay1us(60000);
   p25 = 1;
  }
}
}
//串口中断服务程序
void Uart1IsrHandler(void) interrupt 4
{
if (RI)
{
  RI = 0;  
  gPn532RxLen--;
  if (gPn532RxLen)
  {
   *gpPn532RxBuf = SBUF;
   
   gi++;
   if (gi==4)
   {
    if (0x00==*gpPn532RxBuf)//由于ACK帧与普通帧有一定的区别,所以要区别对待
    {
     gPn532RxLen = *gpPn532RxBuf + 2;  //接收ACK
    }
    else
    {
     gPn532RxLen = *gpPn532RxBuf + 3;  //包长度 + 1字节的包长度校验 + 1字节的数据校验 + 1字节的后导码
    }
   }
   
   gpPn532RxBuf++;
  }
  else
  {
   *gpPn532RxBuf = SBUF;
   gUart1RecvFlag = 1;
  }  
}
if (TI)
{         
  TI = 0;
}
}
void Timer0IsrHandler(void) interrupt 1
{
TH0 = 0x4C;
TL0 = 0x00;
if (--gTimeMult)
  return;
gTimeOutFlag = 1;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:47286 发表于 2017-7-5 11:21 | 只看该作者
干嘛翻译啊 12C5A比89C先进很多啊 你干嘛非用旧东西 抛开其它功能不说至少12c是1t的 89c是12t的 相同工作频率下速度快些

你只需要了解一下12c的1t寄存器和管脚配置就行了 其它和89c一样的 真心觉得没必要改

要翻译也最好你自己来 一方面可以增加自己的知识 另一方面 这种翻译还不如重新写一个呢 先要看懂人家的思路 再修改 麻烦
回复

使用道具 举报

板凳
ID:99130 发表于 2017-7-5 13:12 | 只看该作者
没必要翻译 基本可以通用的 60S2比C52更高级,更好用
回复

使用道具 举报

地板
ID:105206 发表于 2017-7-5 14:13 | 只看该作者
有几点要改,STC12是1T单片机,就是每1个时钟加1;是51的12倍。
1:时钟要改,延时函数要改。
2:定时器要改,波特率要改。
3:头文件要改。
回复

使用道具 举报

5#
ID:213173 发表于 2017-7-5 14:14 | 只看该作者
看了你这程序,完全可以用于STC89C52,因为没有用到STC89C52没有的特殊寄存器,只是两款单片机的速度不同,但定时器0和定时器1的设置都使用12T,所以不会影响定时时间和波特率。其实STC89C52也可以提速到6T。
回复

使用道具 举报

6#
ID:217180 发表于 2017-7-6 12:51 | 只看该作者
谢谢各位指点
回复

使用道具 举报

7#
ID:214223 发表于 2017-7-6 18:40 | 只看该作者
完全没必要啊!
回复

使用道具 举报

8#
ID:137736 发表于 2017-7-6 23:34 | 只看该作者
看STC手册,主要对比二者速度,牵涉到延时。特殊寄存器,牵涉到功能。先改掉包含的头文件。从头至尾阅读程序。
回复

使用道具 举报

9#
ID:159139 发表于 2017-7-7 13:26 来自手机 | 只看该作者
你就用12做了,如果改89C52,主要改延时部分。
回复

使用道具 举报

10#
ID:217985 发表于 2017-7-7 20:10 | 只看该作者
没有必要翻译啊
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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