新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機+315M無線射頻模塊接受程序

        51單片機+315M無線射頻模塊接受程序

        作者: 時間:2016-11-30 來源:網絡 收藏

        sbit W_IN = P2^1;
        sbit W_OUT = P2^0;

        unsigned char w_data;//接收時用于存儲兩次上升沿之間的時長,發送時存儲前半周
        unsigned char send_busy = 0;//存儲發送時后半周
        unsigned char recv_timer = 0;
        bit w_stat, last_w_stat;

        unsigned char jiffies=0;
        void clock_timer(void) interrupt 1 using 1{
        if (send_busy){
        if(w_data){
        w_data--;
        w_stat = 0;
        }else{
        send_busy--;
        w_stat = 1;
        }
        W_OUT = w_stat;
        }else{
        w_stat = W_IN;
        if (w_stat != last_w_stat){
        last_w_stat = w_stat;
        if (w_stat){
        w_data = recv_timer;
        recv_timer = 0;
        }
        }
        if (~recv_timer)//if(recv_busy != 0xff)
        recv_timer++;
        }
        jiffies++;
        }

        void clock_init(void){
        jiffies = 0;
        TMOD=0x02;
        TH0=TL0=0x0ce;//12M,50us
        //TH0=TL0=0x7a;//16M
        //TH0=TL0=0x75;//16.59M
        //TH0=TL0=0x72;//17M
        //TH0=TL0=0x37;//24M
        //TH0=TL0=0x47;//22.1844M, 100us
        //TH0=TL0=0xa3;//22.1844M, 50us
        EA=1;
        ET0=1;

        TR0=1;
        }
        void init_serialcomm(void)
        {
        SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
        TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
        PCON |= 0x80; //SMOD=1;
        TH1 = 0x0e6; //Baud:2400 fosc=11.0592MHz :f4
        TL1 = 0x0e6;
        //IE |= 0x90; //Enable Serial Interrupt
        TR1 = 1; // timer 1 run
        RI=0;
        TI=1;
        }

        void serial_out(unsigned char d){
        while(!TI);
        TI=0;
        SBUF=(d);
        }

        void send_string_com(unsigned char *str,int strlen)//串口程序
        { unsigned char sum;

        unsigned char k=0;
        //serial_out(02);
        do
        { //sum^=*(str+k);
        serial_out(*(str + k));
        //serial_out(a);
        k++;
        } while(k < strlen);
        //serial_out(sum);
        //serial_out(e);
        }

        //等待指定長度的串行數據到達,超時值為每兩個字節之間的間隔時間而非等待整個串的時間.
        //超時單位為time_out * 100uS
        bit wait_serial(unsigned char *p, unsigned char len, unsigned char time_out){
        unsigned int time=jiffies;
        unsigned char n=0;
        do{
        if (RI){
        p[n++]=SBUF;
        RI=0;
        if(n==len)
        return 0;
        time=jiffies;
        }
        }while(jiffies-time < time_out);
        return 1;
        }

        sys_init(){
        clock_init();
        init_serialcomm();
        }


        //=============================================================
        //發送程序 開始
        //=============================================================

        #define PULS_0_WIDTH 8//低電平脈寬
        #define PULS_1_WIDTH 16//高電平脈寬
        #define PULS_HEAD_WIDTH 8//前導信號脈寬
        #define PULS_START_WIDTH 24//引導信號脈寬
        #define PULS_STOP_WIDTH 8//結束碼脈寬

        #define PULS_HEAD_COUNTS 16//前導信號長度


        unsigned char send_buf[16];
        #define send_byts send_buf[0]//剩余字節數,發送完后為0
        unsigned char sending_byte;//當前正在發送的字節
        unsigned char send_byte_p;//已發送字節數(含正在發送的字節)
        unsigned char send_bit_p;//當前正在發送的字節已發送位數(含正在發送的位)

        #define SEND_PROGRESSING 0x41
        #define SEND_FAILED 0x21
        #define SEND_SUCCESS 0x31
        unsigned char send_stat = 0;//發送程序當前狀態,為0時正常
        unsigned char head_counts;//前導信號計數器(包括引導信號)

        void start_send(){
        send_byte_p = 0;
        send_bit_p = 0;
        send_stat = SEND_PROGRESSING;
        head_counts = 16;
        }

        #define START_SEND(byts) send_buf[0]=byts;send_byts=byts;start_send()

        //發送前應清除send_byte_p,send_bit_p,send_stat,并設置send_byts
        //發送過程中可根據send_byts的值得到剩余字節數,根據send_byte_p的值得到已發送字節數.注意,將正在發送的字節當作已發送完畢.
        //發送過程中可根據send_stat的值得到發送狀態.
        //發送完成后,send_byts和send_bit_p的值都為0.
        #define SEND_PULS(x) w_data=send_busy=(x>>1)
        void send(){
        //下面兩行在wirless()中已經執行過了,所以無需寫上
        //if (send_stat != SEND_PROGRESSING)
        //return;

        if (!send_busy){
        if(send_byts || send_bit_p){
        if (head_counts){
        head_counts--;
        if(head_counts)
        SEND_PULS(PULS_HEAD_WIDTH);
        else
        SEND_PULS(PULS_START_WIDTH);
        }else{
        if (send_bit_p == 0){
        sending_byte = send_buf[send_byte_p];
        send_byte_p++;
        send_byts--;
        send_bit_p = 8;
        }

        if(sending_byte & 0x80){
        SEND_PULS(PULS_1_WIDTH);
        }else{
        SEND_PULS(PULS_0_WIDTH);
        }

        sending_byte <<= 1;
        send_bit_p--;
        }
        }else{
        SEND_PULS(PULS_STOP_WIDTH);
        send_stat = SEND_SUCCESS;
        }
        }
        return;
        }
        //=============================================================
        //發送程序 結束
        //=============================================================

        //=============================================================
        //接收程序 開始
        //=============================================================

        unsigned char recv_buf[16];
        #define recv_byts recv_buf[0]//應收到字節數,由每個包的第一個字節指定
        unsigned char recving_byte;//當前正在接收的字節
        unsigned char recv_byte_p;//已收到字節數(不含正在接收的字節)
        unsigned char recv_bit_p;//當前正在接收的字節等待接收位數(不含正在接收的位)

        #define RECV_FAILED 0x31
        #define RECV_SUCCESS 0x41

        unsigned char recv_stat = 0; //接收程序當前狀態,為0時正常
        unsigned char recv_step = 0;//引導脈沖標志,為0時等待引導,為1時等待數據

        #define TEST_PULS(puls_in, puls_type) (puls_in > puls_type - PULS_0_WIDTH / 2 && puls_in < puls_type + PULS_0_WIDTH / 2)

        #define HEAD_NEED_RECIVED 8
        void recv(){
        unsigned puls_width;

        if ((recv_stat == RECV_SUCCESS) || !w_data)
        return;

        puls_width = w_data;
        w_data = 0;

        #if 0//輸出脈寬
        serial_out(puls_width);
        //printhex(puls_width);
        #endif

        if (recv_step < HEAD_NEED_RECIVED){
        if(TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
        recv_step++;
        }else{
        recv_step = 0;
        }
        }else if (recv_step == HEAD_NEED_RECIVED){
        if(TEST_PULS(puls_width, PULS_START_WIDTH)){
        serial_out(0xbb);
        recv_byte_p = 0;
        recv_bit_p = 8;
        recv_stat = 0;
        recv_step++;
        }else{
        if(!TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
        recv_step = 0;
        }
        }
        }else{
        //serial_out(puls_width);
        recving_byte <<= 1;
        if(TEST_PULS(puls_width, PULS_0_WIDTH)){
        recving_byte &= 0xfe;
        }else if(TEST_PULS(puls_width, PULS_1_WIDTH)){
        recving_byte |= 1;
        }else{
        serial_out(puls_width);
        recv_step = 0;
        serial_out(0xaa);
        return;
        }
        recv_bit_p--;
        if(recv_bit_p == 0){//接收完一字節
        recv_bit_p = 8;
        //serial_out(recving_byte);//輸出接收到的字符
        recv_buf[recv_byte_p] = recving_byte;
        recv_byte_p++;
        if(recv_byte_p == recv_byts){
        recv_step = 0;
        recv_stat = RECV_SUCCESS;
        }
        }
        }
        }

        //=============================================================
        //接收程序 結束
        //=============================================================

        #define SEND_DELAY_TIME 20//防碰撞延遲(單位:毫秒)
        unsigned char send_delay = SEND_DELAY_TIME;
        #define VALID_PULS_COUNT 10
        unsigned char valid_puls_counts = VALID_PULS_COUNT;

        //碰撞檢測在該函數中實現.由于無線模塊本身的限制,碰撞檢測為非完全檢測,只能在發送前
        //檢測是否有其它單元在使用信道,在發送過程中受到的碰撞干擾是無法檢測到的.經測試,效果還行
        void wirless(){
        if (send_stat == SEND_PROGRESSING && send_delay == 0){
        send();
        if (send_stat == SEND_SUCCESS)
        send_delay = SEND_DELAY_TIME;
        }else{
        recv();
        if (recv_step > HEAD_NEED_RECIVED)//如果檢測到當前有其它單元正在發送,繼續等待
        send_delay = SEND_DELAY_TIME;
        else{
        if(TEST_PULS(w_data, PULS_0_WIDTH)//如果檢測到當前有其它單元正在發送,繼續等待
        || TEST_PULS(w_data, PULS_1_WIDTH)
        //|| TEST_PULS(w_data, PULS_HEAD_WIDTH)
        || TEST_PULS(w_data, PULS_START_WIDTH)
        //|| TEST_PULS(w_data, PULS_STOP_WIDTH)
        ){
        if (valid_puls_counts)
        valid_puls_counts--;
        else
        send_delay = SEND_DELAY_TIME;
        }else{
        valid_puls_counts = VALID_PULS_COUNT;
        }
        }
        }
        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 合山市| 武冈市| 鹿邑县| 伊金霍洛旗| 肃宁县| 北碚区| 江都市| 东莞市| 泊头市| 上栗县| 郎溪县| 修武县| 遂宁市| 宁明县| 周至县| 吉隆县| 贡觉县| 荥经县| 曲麻莱县| 科技| 秦安县| 南郑县| 莲花县| 盐山县| 玉溪市| 龙泉市| 安新县| 长宁县| 阳高县| 渭南市| 远安县| 兰坪| 瑞安市| 麻栗坡县| 长宁区| 海丰县| 尼木县| 白银市| 常山县| 泉州市| 奉节县|