找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1108|回复: 9
收起左侧

关于RFID程序移植问题,从12T到1T单片机

[复制链接]
ID:887186 发表于 2022-4-12 20:02 | 显示全部楼层 |阅读模式
50黑币
从商家那买来的RFID模块,用52和他的历程可以驱动
想要移植到自己的STC8H1K28上,按理来说,改变串口的初始化就可以实现
但不知道为什么总是不行。恳请各位指点
①商家代码C52单片机的
#include "reg52.h"

sbit LED1 = P2^0;
sbit LED2 = P2^1;

typedef unsigned int u16;        //对系统默认数据类型进行重定义
typedef unsigned char u8;

u8 rxdatabuf[32];
u8 rxdatacnt;


/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能                 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出             : 无
*******************************************************************************/
void uart_init(u8 baud)
{
        TMOD|=0X20;        //设置计数器工作方式2
        SCON=0X50;        //设置为工作方式1
        PCON=0X80;        //波特率加倍
        TH1=baud;        //计数器初始值设置
        TL1=baud;
        ES=1;                //打开接收中断
        EA=1;                //打开总中断
        TR1=1;                //打开计数器               
}

//void sendchar(u8 ch)
//{
//  ES=0;
//  TI=0;
//        SBUF = ch;
//        while(!TI);                //等待发送数据完成
//        TI=0;                        //清除发送完成标志位
//        ES=1;
//}
/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能                 : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出             : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
        while(ten_us--);        
}

unsigned char CheckSum(unsigned char *ptr,unsigned char len)
{
        unsigned char i;
        unsigned char checksum;
        checksum = 0;
        for(i=0;i<(len-1);i++)
        {
                   checksum ^= ptr[ i];
        }
        if(ptr[len-1] == (~checksum))
                return         0x01;
        else
                return         0x00;
}

void clean_rxdatabuf(void)
{
        u8 i = 0;
         rxdatacnt = 0;
        for(i=0;i<32;i++)
        {
                 rxdatabuf[ i] = 0;
        }
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{        
        u8 i;
        u8 cardid[4];
        rxdatacnt = 0;
        uart_init(0xFA);//波特率为9600
        LED1 = 1;
        LED2 = 0;
        delay_10us(5000);
        LED1 = 0;
        LED2 = 1;
        while(1)
        {        
                if(rxdatacnt > 0) //判断串口是否收到数据
                {        
                        LED2 = 0;        //接收到数据闪LED2
                        delay_10us(2000);//等待串口接收完毕
                        LED2 = 1;
                        if(rxdatacnt >= 12) //判断是否收到一帧数据,自动读卡号读卡器送的数据包长度为12字节
                        {
                                        //rxdatabuf数组中接收到的数据格式应该如下
                                        //rxdatabuf[0]包类型,0x04表示自动读卡返回的数据包
                                        //rxdatabuf[1]包长度,自动读卡号返回的数据包长度为12字节
                                        //rxdatabuf[2]命令,0x02表示自动读卡号,0x03表示自动读数据块,0x04表示自动读卡号+数据块
                                        //rxdatabuf[3]读卡器地址,默认0x20
                                        //rxdatabuf[4]固定值0x00
                                        //rxdatabuf[5],rxdatabuf[6]这两个字节保存的是卡类型,比如04 00表示 M1 S50卡,02 00 表示M1 S70卡
                                         //rxdatabuf[7],rxdatabuf[8],rxdatabuf[9],rxdatabuf[10]这个4个字节存储的是卡号
                                        //rxdatabuf[11]数据包校验值,计算方式参考手册的校验和计算方方法或者参考本例子代码CheckSum();
                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] == 12)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判断是否为读卡器返回的数据包
                                 {
                                                 if(CheckSum(rxdatabuf,12))         //判断检验是否正确,正确返回0x01,错误返回0x00
                                                {
                                                                //获取卡号
                                                                 for(i=0;i<4;i++)
                                                                {
                                                                         cardid[ i] = rxdatabuf[7 + i]; //将rxdatabuf数组中的4字节卡号复制到数组cardid[]中
                                                                }
                                                                LED1 = 1;                //熄灭LED
                                                                delay_10us(50000);
                                                                LED1 = 0;                //点亮LED
                                                }
                                 }
                        }
                        clean_rxdatabuf();
                }                                
        }               
}

void uart() interrupt 4 //串口通信中断函数
{
        RI = 0;                        //清除接收中断标志位
        rxdatabuf[rxdatacnt] = SBUF;         //存储接收到的数据
        rxdatacnt++;
        if(rxdatacnt >= 32)                //RxDataBuf数组最大存放32字节数据,防止数组溢出
        {
                rxdatacnt = 0;
        }                                       
}

②我移植的代码
#include "STC8.h"
#include "intrins.h"
#define FOSC        11059200UL
#define BRT         (256 - FOSC / 9600 / 32)
sbit LED1 = P2^0;
sbit LED2 = P2^1;
typedef unsigned int u16;        //对系统默认数据类型进行重定义
typedef unsigned char u8;

u8 i;
u8 cardid[4];
bit busy;
u8 rxdatacnt;
char rptr;
char rxdatabuf[32];

void delay_10us(u16 ten_us)
{
        while(ten_us--);        
}
unsigned char CheckSum(unsigned char *ptr,unsigned char len)
{
        unsigned char i;
        unsigned char checksum;
        checksum = 0;
        for(i=0;i<(len-1);i++)
        {
                   checksum ^= ptr[ i];
        }
        if(ptr[len-1] == (~checksum))
                return         0x01;
        else
                return         0x00;
}
void clean_rxdatabuf(void)
{
        u8 i = 0;
         rxdatacnt = 0;
        for(i=0;i<32;i++)
        {
                 rxdatabuf[ i] = 0;
        }
}



void UartIsr() interrupt 4
{
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
    if (RI)
    {
      rxdatabuf[rxdatacnt++] =SBUF;
                        if( rxdatacnt >=13){
                                       RI = 0;}
                        
  if(rxdatacnt >= 32)                //RxDataBuf数组最大存放32字节数据,防止数组溢出
        {
                rxdatacnt = 0;
        }                                       
    }
}

void UartInit()
{
    SCON = 0x50;
    TMOD = 0x20;
    TL1 = BRT;
    TH1 = BRT;
    TR1 = 1;
    AUXR = 0x40;
    rxdatacnt = 0x00;
    rptr = 0x00;
    busy = 0;
}


void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    UartInit();
    ES = 1;
    EA = 1;
        LED1 = 0;

    while (1)
    {
     if(rxdatacnt > 0) //判断串口是否收到数据
                {        
                        LED1 = 1;
                        delay_10us(1000);
                        if (rxdatacnt >= 12) //判断是否收到一帧数据,自动读卡号读卡器送的数据包长度为12字节
                        {
                                                 LED2 = 0;        
                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] ==0X0C)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判断是否为读卡器返回的数据包
                                 {
                                         LED2 = 1;        
                                                 if(CheckSum(rxdatabuf,12))         //判断检验是否正确,正确返回0x01,错误返回0x00
                                                {
                                                                //获取卡号
                                                                 for(i=0;i<4;i++)
                                                                {
                                                                         cardid[ i] = rxdatabuf[7 + i]; //将rxdatabuf数组中的4字节卡号复制到数组cardid[]中
                                                                }
                                
                        
                                                }
                                 }
                        }
                        clean_rxdatabuf();
                }                                
    }
}

最后通过LED灯的状态发现他卡在LED2=0;
不知道为什么,是数据不对还是?
我试过把接收到的数据传到串口助手上看,数据时而是对的,时而都是000000

最佳答案

查看完整内容

两者速度不同,端口模式寄存器、定时器工作模式寄存器也有所不同,主要修改这三项即可。
回复

使用道具 举报

ID:213173 发表于 2022-4-12 20:02 | 显示全部楼层
一夜暴富 发表于 2022-4-13 09:43
我串口中断的设置是直接照着例程写下来的。
不知道应该怎么修改比较好

两者速度不同,端口模式寄存器、定时器工作模式寄存器也有所不同,主要修改这三项即可。
  1. //#include "reg52.h"
  2. #include "STC8.h"

  3. sbit LED1 = P2^0;
  4. sbit LED2 = P2^1;

  5. typedef unsigned int u16;        //对系统默认数据类型进行重定义
  6. typedef unsigned char u8;

  7. u8 rxdatabuf[32];
  8. u8 rxdatacnt;

  9. /*******************************************************************************
  10. * 函 数 名       : uart_init
  11. * 函数功能       : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
  12. * 输    入       : baud:波特率对应的TH、TL装载值
  13. * 输    出             : 无
  14. *******************************************************************************/
  15. /*
  16. void uart_init(u8 baud)
  17. {
  18. TMOD|=0X20;        //设置计数器工作方式2
  19. SCON=0X50;        //设置为工作方式1
  20. PCON=0X80;        //波特率加倍
  21. TH1=baud;        //计数器初始值设置
  22. TL1=baud;
  23. ES=1;                //打开接收中断
  24. EA=1;                //打开总中断
  25. TR1=1;                //打开计数器               
  26. }*/
  27. void uart_init(void)                //9600bps@11.0592MHz
  28. {
  29.         SCON = 0x50;                //8位数据,可变波特率
  30.         AUXR |= 0x40;                //定时器时钟1T模式
  31.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  32.         TMOD &= 0x0F;                //设置定时器模式
  33.         TL1 = 0xE0;                //设置定时初始值
  34.         TH1 = 0xFE;                //设置定时初始值
  35.         ET1 = 0;                //禁止定时器%d中断
  36.         ES=1;        //打开接收中断
  37.         EA=1;         //打开总中断
  38.         TR1 = 1;                //定时器1开始计时
  39. }

  40. //void sendchar(u8 ch)
  41. //{
  42. //  ES=0;
  43. //  TI=0;
  44. //        SBUF = ch;
  45. //        while(!TI);                //等待发送数据完成
  46. //        TI=0;                        //清除发送完成标志位
  47. //        ES=1;
  48. //}
  49. /*******************************************************************************
  50. * 函 数 名       : delay_10us
  51. * 函数功能       : 延时函数,ten_us=1时,大约延时10us
  52. * 输    入       : ten_us
  53. * 输    出             : 无
  54. *******************************************************************************/
  55. /*
  56. void delay_10us(u16 ten_us)
  57. {
  58.         while(ten_us--);        
  59. }
  60. */
  61. void delay_10us(u16 ten_us)
  62. {
  63.         u16 i;
  64.         while(ten_us--)      
  65.         {
  66.                 for(i=10;i>0;i--);
  67.         }
  68. }

  69. unsigned char CheckSum(unsigned char *ptr,unsigned char len)
  70. {
  71.         unsigned char i;
  72.         unsigned char checksum;
  73.         checksum = 0;
  74.         for(i=0;i<(len-1);i++)
  75.         {
  76.                 checksum ^= ptr[ i];
  77.         }
  78.         if(ptr[len-1] == (~checksum))
  79.                 return         0x01;
  80.         else
  81.                 return         0x00;
  82. }

  83. void clean_rxdatabuf(void)
  84. {
  85.         u8 i = 0;
  86.         rxdatacnt = 0;
  87.         for(i=0;i<32;i++)
  88.         {
  89.                 rxdatabuf[ i] = 0;
  90.         }
  91. }
  92. /*******************************************************************************
  93. * 函 数 名       : main
  94. * 函数功能                 : 主函数
  95. * 输    入       : 无
  96. * 输    出             : 无
  97. *******************************************************************************/
  98. void main()
  99. {        
  100.         u8 i;
  101.         u8 cardid[4];
  102.         P0M0 = 0x00;
  103.         P0M1 = 0x00;
  104.         P1M0 = 0x00;
  105.         P1M1 = 0x00;
  106.         P2M0 = 0x00;
  107.         P2M1 = 0x00;
  108.         P3M0 = 0x00;
  109.         P3M1 = 0x00;
  110.         P4M0 = 0x00;
  111.         P4M1 = 0x00;
  112.         P5M0 = 0x00;
  113.         P5M1 = 0x00;
  114.         rxdatacnt = 0;
  115.         //uart_init(0xFA);//波特率为9600
  116.         uart_init();//波特率为9600
  117.         LED1 = 1;
  118.         LED2 = 0;
  119.         delay_10us(5000);
  120.         LED1 = 0;
  121.         LED2 = 1;
  122.         while(1)
  123.         {        
  124.                 if(rxdatacnt > 0) //判断串口是否收到数据
  125.                 {        
  126.                         LED2 = 0;        //接收到数据闪LED2
  127.                         delay_10us(2000);//等待串口接收完毕
  128.                         LED2 = 1;
  129.                         if(rxdatacnt >= 12) //判断是否收到一帧数据,自动读卡号读卡器送的数据包长度为12字节
  130.                         {
  131.                                 //rxdatabuf数组中接收到的数据格式应该如下
  132.                                 //rxdatabuf[0]包类型,0x04表示自动读卡返回的数据包
  133.                                 //rxdatabuf[1]包长度,自动读卡号返回的数据包长度为12字节
  134.                                 //rxdatabuf[2]命令,0x02表示自动读卡号,0x03表示自动读数据块,0x04表示自动读卡号+数据块
  135.                                 //rxdatabuf[3]读卡器地址,默认0x20
  136.                                 //rxdatabuf[4]固定值0x00
  137.                                 //rxdatabuf[5],rxdatabuf[6]这两个字节保存的是卡类型,比如04 00表示 M1 S50卡,02 00 表示M1 S70卡
  138.                                 //rxdatabuf[7],rxdatabuf[8],rxdatabuf[9],rxdatabuf[10]这个4个字节存储的是卡号
  139.                                 //rxdatabuf[11]数据包校验值,计算方式参考手册的校验和计算方方法或者参考本例子代码CheckSum();
  140.                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] == 12)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判断是否为读卡器返回的数据包
  141.                                 {
  142.                                         if(CheckSum(rxdatabuf,12))         //判断检验是否正确,正确返回0x01,错误返回0x00
  143.                                         {
  144.                                                 //获取卡号
  145.                                                 for(i=0;i<4;i++)
  146.                                                 {
  147.                                                         cardid[ i] = rxdatabuf[7 + i]; //将rxdatabuf数组中的4字节卡号复制到数组cardid[]中
  148.                                                 }
  149.                                                 LED1 = 1;                //熄灭LED
  150.                                                 delay_10us(50000);
  151.                                                 LED1 = 0;                //点亮LED
  152.                                         }
  153.                                 }
  154.                         }
  155.                         clean_rxdatabuf();
  156.                 }                                
  157.         }               
  158. }

  159. void uart() interrupt 4 //串口通信中断函数
  160. {
  161.         RI = 0;                        //清除接收中断标志位
  162.         rxdatabuf[rxdatacnt] = SBUF;         //存储接收到的数据
  163.         rxdatacnt++;
  164.         if(rxdatacnt >= 32)                //RxDataBuf数组最大存放32字节数据,防止数组溢出
  165.         {
  166.                 rxdatacnt = 0;
  167.         }
  168. }
复制代码
回复

使用道具 举报

ID:584814 发表于 2022-4-13 08:49 | 显示全部楼层
无非是速度不同,可能有中断设置不一样。
看器件手册,重点是中断设置和延时调整。
回复

使用道具 举报

ID:887186 发表于 2022-4-13 09:43 | 显示全部楼层
man1234567 发表于 2022-4-13 08:49
无非是速度不同,可能有中断设置不一样。
看器件手册,重点是中断设置和延时调整。

我串口中断的设置是直接照着例程写下来的。
不知道应该怎么修改比较好
回复

使用道具 举报

ID:887186 发表于 2022-4-13 09:57 | 显示全部楼层
发现只能接收到头字符0X04
但是按理来说他应该接受完数据放进数组里的。。
是我的代码哪里写的不对吗
希望各位能帮忙看看
回复

使用道具 举报

ID:887186 发表于 2022-4-13 10:13 | 显示全部楼层
好像搞定了各位,
不知道为什么他C52里串口中断加if判定没关系,不影响字节接受
但是STC8在串口中断加了if判断就只接收到帧头
非常之神奇
回复

使用道具 举报

ID:161164 发表于 2022-4-13 10:40 | 显示全部楼层
新代码中的delay_10us(1000);耗时大约是1.3ms
9600bps = 1200Byte/s
即每一byte耗时0.833ms
12Byte需要10ms
所以把delay_10us(1000);改为delay_10us(10000);试试看

但不建议再用阻塞式延时
一来不准确
二来浪费单片机资源
回复

使用道具 举报

ID:887186 发表于 2022-4-13 14:14 | 显示全部楼层
lkc8210 发表于 2022-4-13 10:40
新代码中的delay_10us(1000);耗时大约是1.3ms
9600bps = 1200Byte/s
即每一byte耗时0.833ms

明白了,感谢,顺便想再请教一下用什么方法比较合适。
然后我发现好像事因为我在接收中断里加了if判定导致数据只接受一个字节
或许这有什么讲究?
回复

使用道具 举报

ID:887186 发表于 2022-4-13 14:15 | 显示全部楼层
wulin 发表于 2022-4-13 10:45
两者速度不同,端口模式寄存器、定时器工作模式寄存器也有所不同,主要修改这三项即可。

感谢!我稍后试试您的代码
回复

使用道具 举报

ID:123289 发表于 2022-4-14 08:55 | 显示全部楼层
什么时间你的程序中看不到DELAY()函数,你的水平就不是初级阶段了。
都是教书先生害的人。不告诉学生DELAY()的危害有多大。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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