找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2396|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

關(guān)于RFID程序移植問(wèn)題,從12T到1T單片機(jī)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:887186 發(fā)表于 2022-4-12 20:02 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
50黑幣
從商家那買來(lái)的RFID模塊,用52和他的歷程可以驅(qū)動(dòng)
想要移植到自己的STC8H1K28上,按理來(lái)說(shuō),改變串口的初始化就可以實(shí)現(xiàn)
但不知道為什么總是不行。懇請(qǐng)各位指點(diǎn)
①商家代碼C52單片機(jī)的
#include "reg52.h"

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

typedef unsigned int u16;        //對(duì)系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;

u8 rxdatabuf[32];
u8 rxdatacnt;


/*******************************************************************************
* 函 數(shù) 名       : uart_init
* 函數(shù)功能                 : 串口通信中斷配置函數(shù),通過(guò)設(shè)置TH和TL即可確定定時(shí)時(shí)間
* 輸    入       : baud:波特率對(duì)應(yīng)的TH、TL裝載值
* 輸    出             : 無(wú)
*******************************************************************************/
void uart_init(u8 baud)
{
        TMOD|=0X20;        //設(shè)置計(jì)數(shù)器工作方式2
        SCON=0X50;        //設(shè)置為工作方式1
        PCON=0X80;        //波特率加倍
        TH1=baud;        //計(jì)數(shù)器初始值設(shè)置
        TL1=baud;
        ES=1;                //打開接收中斷
        EA=1;                //打開總中斷
        TR1=1;                //打開計(jì)數(shù)器               
}

//void sendchar(u8 ch)
//{
//  ES=0;
//  TI=0;
//        SBUF = ch;
//        while(!TI);                //等待發(fā)送數(shù)據(jù)完成
//        TI=0;                        //清除發(fā)送完成標(biāo)志位
//        ES=1;
//}
/*******************************************************************************
* 函 數(shù) 名       : delay_10us
* 函數(shù)功能                 : 延時(shí)函數(shù),ten_us=1時(shí),大約延時(shí)10us
* 輸    入       : ten_us
* 輸    出             : 無(wú)
*******************************************************************************/
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;
        }
}
/*******************************************************************************
* 函 數(shù) 名       : main
* 函數(shù)功能                 : 主函數(shù)
* 輸    入       : 無(wú)
* 輸    出             : 無(wú)
*******************************************************************************/
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) //判斷串口是否收到數(shù)據(jù)
                {        
                        LED2 = 0;        //接收到數(shù)據(jù)閃LED2
                        delay_10us(2000);//等待串口接收完畢
                        LED2 = 1;
                        if(rxdatacnt >= 12) //判斷是否收到一幀數(shù)據(jù),自動(dòng)讀卡號(hào)讀卡器送的數(shù)據(jù)包長(zhǎng)度為12字節(jié)
                        {
                                        //rxdatabuf數(shù)組中接收到的數(shù)據(jù)格式應(yīng)該如下
                                        //rxdatabuf[0]包類型,0x04表示自動(dòng)讀卡返回的數(shù)據(jù)包
                                        //rxdatabuf[1]包長(zhǎng)度,自動(dòng)讀卡號(hào)返回的數(shù)據(jù)包長(zhǎng)度為12字節(jié)
                                        //rxdatabuf[2]命令,0x02表示自動(dòng)讀卡號(hào),0x03表示自動(dòng)讀數(shù)據(jù)塊,0x04表示自動(dòng)讀卡號(hào)+數(shù)據(jù)塊
                                        //rxdatabuf[3]讀卡器地址,默認(rèn)0x20
                                        //rxdatabuf[4]固定值0x00
                                        //rxdatabuf[5],rxdatabuf[6]這兩個(gè)字節(jié)保存的是卡類型,比如04 00表示 M1 S50卡,02 00 表示M1 S70卡
                                         //rxdatabuf[7],rxdatabuf[8],rxdatabuf[9],rxdatabuf[10]這個(gè)4個(gè)字節(jié)存儲(chǔ)的是卡號(hào)
                                        //rxdatabuf[11]數(shù)據(jù)包校驗(yàn)值,計(jì)算方式參考手冊(cè)的校驗(yàn)和計(jì)算方方法或者參考本例子代碼CheckSum();
                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] == 12)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判斷是否為讀卡器返回的數(shù)據(jù)包
                                 {
                                                 if(CheckSum(rxdatabuf,12))         //判斷檢驗(yàn)是否正確,正確返回0x01,錯(cuò)誤返回0x00
                                                {
                                                                //獲取卡號(hào)
                                                                 for(i=0;i<4;i++)
                                                                {
                                                                         cardid[ i] = rxdatabuf[7 + i]; //將rxdatabuf數(shù)組中的4字節(jié)卡號(hào)復(fù)制到數(shù)組cardid[]中
                                                                }
                                                                LED1 = 1;                //熄滅LED
                                                                delay_10us(50000);
                                                                LED1 = 0;                //點(diǎn)亮LED
                                                }
                                 }
                        }
                        clean_rxdatabuf();
                }                                
        }               
}

void uart() interrupt 4 //串口通信中斷函數(shù)
{
        RI = 0;                        //清除接收中斷標(biāo)志位
        rxdatabuf[rxdatacnt] = SBUF;         //存儲(chǔ)接收到的數(shù)據(jù)
        rxdatacnt++;
        if(rxdatacnt >= 32)                //RxDataBuf數(shù)組最大存放32字節(jié)數(shù)據(jù),防止數(shù)組溢出
        {
                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;        //對(duì)系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
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數(shù)組最大存放32字節(jié)數(shù)據(jù),防止數(shù)組溢出
        {
                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) //判斷串口是否收到數(shù)據(jù)
                {        
                        LED1 = 1;
                        delay_10us(1000);
                        if (rxdatacnt >= 12) //判斷是否收到一幀數(shù)據(jù),自動(dòng)讀卡號(hào)讀卡器送的數(shù)據(jù)包長(zhǎng)度為12字節(jié)
                        {
                                                 LED2 = 0;        
                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] ==0X0C)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判斷是否為讀卡器返回的數(shù)據(jù)包
                                 {
                                         LED2 = 1;        
                                                 if(CheckSum(rxdatabuf,12))         //判斷檢驗(yàn)是否正確,正確返回0x01,錯(cuò)誤返回0x00
                                                {
                                                                //獲取卡號(hào)
                                                                 for(i=0;i<4;i++)
                                                                {
                                                                         cardid[ i] = rxdatabuf[7 + i]; //將rxdatabuf數(shù)組中的4字節(jié)卡號(hào)復(fù)制到數(shù)組cardid[]中
                                                                }
                                
                        
                                                }
                                 }
                        }
                        clean_rxdatabuf();
                }                                
    }
}

最后通過(guò)LED燈的狀態(tài)發(fā)現(xiàn)他卡在LED2=0;
不知道為什么,是數(shù)據(jù)不對(duì)還是?
我試過(guò)把接收到的數(shù)據(jù)傳到串口助手上看,數(shù)據(jù)時(shí)而是對(duì)的,時(shí)而都是000000

最佳答案

查看完整內(nèi)容

兩者速度不同,端口模式寄存器、定時(shí)器工作模式寄存器也有所不同,主要修改這三項(xiàng)即可。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:213173 發(fā)表于 2022-4-12 20:02 | 只看該作者
一夜暴富 發(fā)表于 2022-4-13 09:43
我串口中斷的設(shè)置是直接照著例程寫下來(lái)的。
不知道應(yīng)該怎么修改比較好

兩者速度不同,端口模式寄存器、定時(shí)器工作模式寄存器也有所不同,主要修改這三項(xiàng)即可。
  1. //#include "reg52.h"
  2. #include "STC8.h"

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

  5. typedef unsigned int u16;        //對(duì)系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
  6. typedef unsigned char u8;

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

  9. /*******************************************************************************
  10. * 函 數(shù) 名       : uart_init
  11. * 函數(shù)功能       : 串口通信中斷配置函數(shù),通過(guò)設(shè)置TH和TL即可確定定時(shí)時(shí)間
  12. * 輸    入       : baud:波特率對(duì)應(yīng)的TH、TL裝載值
  13. * 輸    出             : 無(wú)
  14. *******************************************************************************/
  15. /*
  16. void uart_init(u8 baud)
  17. {
  18. TMOD|=0X20;        //設(shè)置計(jì)數(shù)器工作方式2
  19. SCON=0X50;        //設(shè)置為工作方式1
  20. PCON=0X80;        //波特率加倍
  21. TH1=baud;        //計(jì)數(shù)器初始值設(shè)置
  22. TL1=baud;
  23. ES=1;                //打開接收中斷
  24. EA=1;                //打開總中斷
  25. TR1=1;                //打開計(jì)數(shù)器               
  26. }*/
  27. void uart_init(void)                //9600bps@11.0592MHz
  28. {
  29.         SCON = 0x50;                //8位數(shù)據(jù),可變波特率
  30.         AUXR |= 0x40;                //定時(shí)器時(shí)鐘1T模式
  31.         AUXR &= 0xFE;                //串口1選擇定時(shí)器1為波特率發(fā)生器
  32.         TMOD &= 0x0F;                //設(shè)置定時(shí)器模式
  33.         TL1 = 0xE0;                //設(shè)置定時(shí)初始值
  34.         TH1 = 0xFE;                //設(shè)置定時(shí)初始值
  35.         ET1 = 0;                //禁止定時(shí)器%d中斷
  36.         ES=1;        //打開接收中斷
  37.         EA=1;         //打開總中斷
  38.         TR1 = 1;                //定時(shí)器1開始計(jì)時(shí)
  39. }

  40. //void sendchar(u8 ch)
  41. //{
  42. //  ES=0;
  43. //  TI=0;
  44. //        SBUF = ch;
  45. //        while(!TI);                //等待發(fā)送數(shù)據(jù)完成
  46. //        TI=0;                        //清除發(fā)送完成標(biāo)志位
  47. //        ES=1;
  48. //}
  49. /*******************************************************************************
  50. * 函 數(shù) 名       : delay_10us
  51. * 函數(shù)功能       : 延時(shí)函數(shù),ten_us=1時(shí),大約延時(shí)10us
  52. * 輸    入       : ten_us
  53. * 輸    出             : 無(wú)
  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. * 函 數(shù) 名       : main
  94. * 函數(shù)功能                 : 主函數(shù)
  95. * 輸    入       : 無(wú)
  96. * 輸    出             : 無(wú)
  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) //判斷串口是否收到數(shù)據(jù)
  125.                 {        
  126.                         LED2 = 0;        //接收到數(shù)據(jù)閃LED2
  127.                         delay_10us(2000);//等待串口接收完畢
  128.                         LED2 = 1;
  129.                         if(rxdatacnt >= 12) //判斷是否收到一幀數(shù)據(jù),自動(dòng)讀卡號(hào)讀卡器送的數(shù)據(jù)包長(zhǎng)度為12字節(jié)
  130.                         {
  131.                                 //rxdatabuf數(shù)組中接收到的數(shù)據(jù)格式應(yīng)該如下
  132.                                 //rxdatabuf[0]包類型,0x04表示自動(dòng)讀卡返回的數(shù)據(jù)包
  133.                                 //rxdatabuf[1]包長(zhǎng)度,自動(dòng)讀卡號(hào)返回的數(shù)據(jù)包長(zhǎng)度為12字節(jié)
  134.                                 //rxdatabuf[2]命令,0x02表示自動(dòng)讀卡號(hào),0x03表示自動(dòng)讀數(shù)據(jù)塊,0x04表示自動(dòng)讀卡號(hào)+數(shù)據(jù)塊
  135.                                 //rxdatabuf[3]讀卡器地址,默認(rèn)0x20
  136.                                 //rxdatabuf[4]固定值0x00
  137.                                 //rxdatabuf[5],rxdatabuf[6]這兩個(gè)字節(jié)保存的是卡類型,比如04 00表示 M1 S50卡,02 00 表示M1 S70卡
  138.                                 //rxdatabuf[7],rxdatabuf[8],rxdatabuf[9],rxdatabuf[10]這個(gè)4個(gè)字節(jié)存儲(chǔ)的是卡號(hào)
  139.                                 //rxdatabuf[11]數(shù)據(jù)包校驗(yàn)值,計(jì)算方式參考手冊(cè)的校驗(yàn)和計(jì)算方方法或者參考本例子代碼CheckSum();
  140.                                 if((rxdatabuf[0] == 0x04)&&(rxdatabuf[1] == 12)&&(rxdatabuf[2] == 0x02)&&(rxdatabuf[3] == 0x20)&&(rxdatabuf[4] == 0x00))//判斷是否為讀卡器返回的數(shù)據(jù)包
  141.                                 {
  142.                                         if(CheckSum(rxdatabuf,12))         //判斷檢驗(yàn)是否正確,正確返回0x01,錯(cuò)誤返回0x00
  143.                                         {
  144.                                                 //獲取卡號(hào)
  145.                                                 for(i=0;i<4;i++)
  146.                                                 {
  147.                                                         cardid[ i] = rxdatabuf[7 + i]; //將rxdatabuf數(shù)組中的4字節(jié)卡號(hào)復(fù)制到數(shù)組cardid[]中
  148.                                                 }
  149.                                                 LED1 = 1;                //熄滅LED
  150.                                                 delay_10us(50000);
  151.                                                 LED1 = 0;                //點(diǎn)亮LED
  152.                                         }
  153.                                 }
  154.                         }
  155.                         clean_rxdatabuf();
  156.                 }                                
  157.         }               
  158. }

  159. void uart() interrupt 4 //串口通信中斷函數(shù)
  160. {
  161.         RI = 0;                        //清除接收中斷標(biāo)志位
  162.         rxdatabuf[rxdatacnt] = SBUF;         //存儲(chǔ)接收到的數(shù)據(jù)
  163.         rxdatacnt++;
  164.         if(rxdatacnt >= 32)                //RxDataBuf數(shù)組最大存放32字節(jié)數(shù)據(jù),防止數(shù)組溢出
  165.         {
  166.                 rxdatacnt = 0;
  167.         }
  168. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

板凳
ID:584814 發(fā)表于 2022-4-13 08:49 | 只看該作者
無(wú)非是速度不同,可能有中斷設(shè)置不一樣。
看器件手冊(cè),重點(diǎn)是中斷設(shè)置和延時(shí)調(diào)整。
回復(fù)

使用道具 舉報(bào)

地板
ID:887186 發(fā)表于 2022-4-13 09:43 | 只看該作者
man1234567 發(fā)表于 2022-4-13 08:49
無(wú)非是速度不同,可能有中斷設(shè)置不一樣。
看器件手冊(cè),重點(diǎn)是中斷設(shè)置和延時(shí)調(diào)整。

我串口中斷的設(shè)置是直接照著例程寫下來(lái)的。
不知道應(yīng)該怎么修改比較好
回復(fù)

使用道具 舉報(bào)

5#
ID:887186 發(fā)表于 2022-4-13 09:57 | 只看該作者
發(fā)現(xiàn)只能接收到頭字符0X04
但是按理來(lái)說(shuō)他應(yīng)該接受完數(shù)據(jù)放進(jìn)數(shù)組里的。。
是我的代碼哪里寫的不對(duì)嗎
希望各位能幫忙看看
回復(fù)

使用道具 舉報(bào)

6#
ID:887186 發(fā)表于 2022-4-13 10:13 | 只看該作者
好像搞定了各位,
不知道為什么他C52里串口中斷加if判定沒關(guān)系,不影響字節(jié)接受
但是STC8在串口中斷加了if判斷就只接收到幀頭
非常之神奇
回復(fù)

使用道具 舉報(bào)

7#
ID:161164 發(fā)表于 2022-4-13 10:40 | 只看該作者
新代碼中的delay_10us(1000);耗時(shí)大約是1.3ms
9600bps = 1200Byte/s
即每一byte耗時(shí)0.833ms
12Byte需要10ms
所以把delay_10us(1000);改為delay_10us(10000);試試看

但不建議再用阻塞式延時(shí)
一來(lái)不準(zhǔn)確
二來(lái)浪費(fèi)單片機(jī)資源
回復(fù)

使用道具 舉報(bào)

8#
ID:887186 發(fā)表于 2022-4-13 14:14 | 只看該作者
lkc8210 發(fā)表于 2022-4-13 10:40
新代碼中的delay_10us(1000);耗時(shí)大約是1.3ms
9600bps = 1200Byte/s
即每一byte耗時(shí)0.833ms

明白了,感謝,順便想再請(qǐng)教一下用什么方法比較合適。
然后我發(fā)現(xiàn)好像事因?yàn)槲以诮邮罩袛嗬锛恿薸f判定導(dǎo)致數(shù)據(jù)只接受一個(gè)字節(jié)
或許這有什么講究?
回復(fù)

使用道具 舉報(bào)

9#
ID:887186 發(fā)表于 2022-4-13 14:15 | 只看該作者
wulin 發(fā)表于 2022-4-13 10:45
兩者速度不同,端口模式寄存器、定時(shí)器工作模式寄存器也有所不同,主要修改這三項(xiàng)即可。

感謝!我稍后試試您的代碼
回復(fù)

使用道具 舉報(bào)

10#
ID:123289 發(fā)表于 2022-4-14 08:55 | 只看該作者
什么時(shí)間你的程序中看不到DELAY()函數(shù),你的水平就不是初級(jí)階段了。
都是教書先生害的人。不告訴學(xué)生DELAY()的危害有多大。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表