久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1412|回復: 9
打印 上一主題 下一主題
收起左側

單片機任意I/O口模擬串口的程序,有一句代碼不明白

  [復制鏈接]
跳轉到指定樓層
樓主
ID:384954 發表于 2023-12-23 23:24 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
請高人幫忙指點,小弟勝感激
/****************《51單片機輕松入門-基于STC15W4K系列》配套例程 *************
/*  任意I/O口模擬串口,22.1184MHZ, 內部R/C時鐘,9600bps  */

#include "STC15W4K.H"            // 包含 "STC15W4K.H"寄存器定義頭文件  
#define RECEIVE_MAX_BYTES  1     // 最大接收字節數

unsigned char RecvBuf[16];       // 接收數據緩沖區
unsigned char RecvCount=0;       // 接收數據計數器

sbit T_TXD=P3^2;                 // 發送數據的引腳
sbit R_RXD=P3^3;                 // 接收數據的引腳
bit RXD_OK;                         // 數據接收完成標志,1(接收正確),0(接收錯誤)
//******************************************/
void delay104uS()
{
  unsigned char i,j,k;
  for(i=1;i>0;i--)         // 注意后面沒分號
  for(j=3;j>0;j--)         // 注意后面沒分號
  for(k=189;k>0;k--);      // 注意后面有分號  
}
void delay52uS()               // 起始位結束后52uS采樣數據
{
  unsigned char i,j,k;
  for(i=1;i>0;i--)         // 注意后面沒分號
  for(j=3;j>0;j--)         // 注意后面沒分號
  for(k=93;k>0;k--);       // 注意后面有分號  
}
void SendByte(unsigned char Dat)
{
       unsignedchar i=8;      // 發送8 位數據
       T_TXD=0;                        // 發送起始位
       delay104uS();
       while(i--)
       {
              if(Dat&1)T_TXD=1;
              elseT_TXD=0;
              delay104uS();
              Dat>>=1;
       }
       T_TXD=1;                        // 發送停止位
       delay104uS();           // 延時   
}

unsigned char RecvByte()
{
       unsignedchar i;      
       unsignedchar Dat=0;            // 接收到的數據
       RXD_OK=0;                              // 字節數據接收正常標志,0——錯誤,1——正常
       delay52uS();                   // 數據位中心位置讀數據   
       if(R_RXD==0)                     // 確認起始位正常
       {   
              delay104uS();               // 起始位寬度            
              for(i=0;i<8;i++)
              {
                     if(R_RXD)     Dat|=(1<<i);  /這一句不懂,求高人講解。
                     delay104uS();
              }   
              if(R_RXD==1)                // 確認停止位正常
              {
                     RXD_OK=1;
              }
       }  
       returnDat;
}

//功能:串口打印字符串
//*****************************************/
void PrintfStr(char * pstr)
{
       while(*pstr)   
       {
              SendByte(*pstr++);
       }
}

//功能:函數主體
//******************************************/
void main(void)
{  
       unsignedchar i;     
       PrintfStr("模擬串口:STC15\r\n");
       while(1)                  
       {
              if(R_RXD==0)      // 死循環不斷檢測R_RXD是否有起始位出現
              {
                     RecvBuf[RecvCount]=RecvByte();
                     if(RXD_OK==1)                                     // 一個字節接收正常
                     {  
                            RecvCount++;
                            if(RecvCount>=RECEIVE_MAX_BYTES)
                            {
                                   RecvCount=0;
                                   for(i=0;i<RECEIVE_MAX_BYTES;i++)
                                   {
                                          SendByte(RecvBuf[ i]+1);        // 接收到得數據+1后發回
                                   }
                            }
                     }            
              }
       }
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:366877 發表于 2023-12-24 01:19 | 只看該作者
這里要實現的是把串行收到的數一位一位地接收下來轉成并行的8位數,這里只考慮收到是1的情況,沒考慮收到0的情況,應該是少了一句程序。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:213173 發表于 2023-12-24 07:30 | 只看該作者
Dat變量初始為0,用2進制表示:00000000 8位都是0
當for循環,if(R_RXD)判斷R_RXD為真,也就是1,
Dat|=(1<<i); 等同Dat=Dat|(1<<i),結果一樣寫法不同,
這段代碼就是把由低到高收到的1按位插入Dat。
例如:
Dat初始=0000 0000
收到字節1010 0101
逐次按位相或后Dat=1010 0101=0xa5
回復

使用道具 舉報

地板
ID:384109 發表于 2023-12-24 08:32 | 只看該作者
功能如樓上所說,不過DAT初始化為0,所以不考慮接收0的情況
回復

使用道具 舉報

5#
ID:1105954 發表于 2023-12-24 09:52 | 只看該作者
表示接收的數據或等于1右移i位
回復

使用道具 舉報

6#
ID:1105893 發表于 2023-12-24 10:49 | 只看該作者
這段代碼是使用單片機STC15W4K模擬串口通信的程序。它通過模擬IO口實現了串口的發送和接收功能。  代碼中定義了一個接收數據緩沖區RecvBuf和一個接收數據計數器RecvCount。接收到的數據存儲在RecvBuf數組中,并根據接收計數器進行處理。  在主函數main中,先發送一條初始化信息"模擬串口:STC15\r\n",然后進入死循環不斷檢測R_RXD引腳是否有起始位出現。如果檢測到起始位,則調用RecvByte函數接收一字節數據,并判斷接收是否正常。  如果接收正常,將接收到的數據存儲在RecvBuf數組中,并遞增接收計數器RecvCount。當接收計數器達到最大接收字節數RECEIVE_MAX_BYTES時,將接收到的數據加1后通過SendByte函數發送回去。  整個程序的功能是模擬串口通信,接收到的數據加1后再發送回去。  需要注意的是,這段代碼只是單片機的程序,無法在此環境中直接運行。如果需要運行,請將代碼下載到STC15W4K單片機開發板上,并根據硬件連接情況進行相應的配置。
回復

使用道具 舉報

7#
ID:517951 發表于 2023-12-24 11:16 | 只看該作者
如果R_RXD=1, 就把Dat=Dat第0 到7 bit(根據i的循環置0-7)置1.
回復

使用道具 舉報

8#
ID:384954 發表于 2023-12-24 19:00 | 只看該作者
wulin 發表于 2023-12-24 07:30
Dat變量初始為0,用2進制表示:00000000 8位都是0
當for循環,if(R_RXD)判斷R_RXD為真,也就是1,
Dat|=( ...

非常感謝這位老師的回復!
只是我感覺這句代碼有問題,如果改動一下就對了,也好理解。
if(R_RXD)
Dat |=(i<<1);
回復

使用道具 舉報

9#
ID:584814 發表于 2023-12-25 08:16 | 只看該作者
1017038201 發表于 2023-12-24 19:00
非常感謝這位老師的回復!
只是我感覺這句代碼有問題,如果改動一下就對了,也好理解。
if(R_RXD)

沒有任何改動哈,回車和縮進對機器可有可無只是方便人類閱讀罷了。
將多行放在一行是可行的,只要多行能正常運行放在同一行也一樣行。
回復

使用道具 舉報

10#
ID:192020 發表于 2023-12-28 13:55 | 只看該作者
1017038201 發表于 2023-12-24 19:00
非常感謝這位老師的回復!
只是我感覺這句代碼有問題,如果改動一下就對了,也好理解。
if(R_RXD)

不知道是你復制錯了還是故意改的,Dat |=(i<<1);不能這樣改,邏輯上錯了,還得原本的Dat |=(1<<i);
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线视频第一页 | av网站在线免费观看 | 亚洲一区日韩 | 欧美一区二区三区的 | 久久精品久久久 | 色综合99 | 91欧美| 欧美性tv| 亚洲精品日韩在线观看 | 国产高清精品一区二区三区 | 成人免费区一区二区三区 | 欧美极品在线 | 99成人| 欧美综合一区二区三区 | 一本一道久久a久久精品蜜桃 | 国产精品爱久久久久久久 | 日韩一区二区三区在线观看视频 | 午夜免费观看 | 午夜国产在线 | 麻豆精品一区二区三区在线观看 | 国产成在线观看免费视频 | 精品毛片| 国内自拍偷拍视频 | 国产精品久久久久久久久久久免费看 | 亚洲美女一区二区三区 | 免费视频一区二区 | 99在线免费视频 | 久久久成人免费视频 | 午夜免费视频 | 久久久不卡网国产精品一区 | 嫩草网| 在线一级片 | 日韩在线一区二区三区 | 精品久久久久久久久久 | 国产免费一区二区三区 | 国产精品视频一区二区三 | 婷婷99 | 久久狠狠| 91中文字幕在线观看 | 日日干夜夜操 | 亚洲欧美日韩一区二区 |