找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10427|回復(fù): 8
收起左側(cè)

51單片機(jī)普通IO口模擬串口源程序

  [復(fù)制鏈接]
ID:140725 發(fā)表于 2016-10-18 14:55 | 顯示全部樓層 |閱讀模式
完整代碼下載:
Xserial.zip (1.37 KB, 下載次數(shù): 167)


大家放心用,但是你們程序要好好看看,容易中斷沖突,現(xiàn)在我們也在解決中,接收和發(fā)送字符串的程序有需要的郵箱給你們發(fā)送過去

東西是好東西,我們遇到了中斷問題,有點(diǎn)麻煩,數(shù)據(jù)采集上來后用模擬串口掛到485總線,向一個控制單片機(jī)發(fā)送數(shù)據(jù),用12864顯示,但是控制單片機(jī)的串口通信的中斷和模擬串口中斷沖突,上位機(jī)和下位機(jī)沒有辦法通信,今天下午實(shí)在沒有辦法了,又做了一塊單片機(jī)最小系統(tǒng),讓采集板上的數(shù)據(jù)之間和這塊最小系統(tǒng)板進(jìn)行通信12864上顯示,現(xiàn)在還沒有想到好的解決辦法,等解決之后再告訴大家,還有就是接受字符串的時候,先進(jìn)行解包,再進(jìn)行標(biāo)識位檢測,這個程序發(fā)程序的方法是一個一個字符發(fā)送的,接收的時候要先放進(jìn)數(shù)組里面,要是有需要的可以單獨(dú)聯(lián)系我,希望大家共同進(jìn)步。

這兩天項(xiàng)目結(jié)項(xiàng),一直比較忙,沒來得及回復(fù)大家,這個程序非常有用嗎,畢竟大部分的單片機(jī)串口都是一個到兩個,有時候功能擴(kuò)展的時候,不可避免的要使用串口,當(dāng)你發(fā)現(xiàn)串口不夠用的時候,你可以使用這個程序,我把接收函數(shù)給大家參考一下

   while(1)
  {
    if(StartBitOn())
    {
          Msg[i_L]=PGetChar();
          if(Msg[i_L]!='a')
          {
            i_L++;
          }
          else
          {  
                i_L=0;
                chinese_disp(0,2,"溫度");//這個是12864液晶顯示函數(shù)大家不用管
          }
         }
        }

說實(shí)話,這東西用起來雖然挺好,但是能不用就不要用,現(xiàn)在單片機(jī)大都是雙串口的,一般都夠用,我們做的東西,用52單片機(jī)模擬串口通信,模擬modbus通信,三個定時器全開,中斷全用,時序容易出錯,所以建議大家不要過多依賴模擬的東西,能花點(diǎn)錢買個好點(diǎn)片子,減少開發(fā)周期,上策。


預(yù)覽:
  1. #include "reg52.h"
  2. #include "intrins.h"  
  3. #include "math.h"     
  4. #include "stdio.h"
  5. sbit BT_SND =P1^5;
  6. sbit BT_REC =P1^6;
  7. sbit LED =P1^7;
  8. bit  LED_flage=1;
  9. //IO 口模擬232通訊程序
  10. //使用兩種方式的C程序 占用定時器0
  11. #define MODE_QUICK
  12. #define F_TM F0
  13. #define TIMER0_ENABLE  TL0=TH0; TR0=1;
  14. #define TIMER0_DISABLE TR0=0;
  15. sbit ACC0=   ACC^0;
  16. sbit ACC1=   ACC^1;
  17. sbit ACC2=   ACC^2;
  18. sbit ACC3=   ACC^3;
  19. sbit ACC4=   ACC^4;
  20. sbit ACC5=   ACC^5;
  21. sbit ACC6=   ACC^6;
  22. sbit ACC7=   ACC^7;

  23. void IntTimer0() interrupt 1
  24. {
  25.   F_TM=1;
  26. }
  27. //發(fā)送一個字符
  28. void PSendChar(unsigned char inch)
  29. {
  30. #ifdef MODE_QUICK
  31.     ACC=inch;
  32.     F_TM=0;
  33.     BT_SND=0; //start bit
  34.     TIMER0_ENABLE; //啟動
  35.     while(!F_TM);
  36.     BT_SND=ACC0; //先送出低位
  37.     F_TM=0;
  38.     while(!F_TM);
  39.     BT_SND=ACC1;
  40.     F_TM=0;
  41.     while(!F_TM);
  42.     BT_SND=ACC2;
  43.     F_TM=0;
  44.     while(!F_TM);
  45.     BT_SND=ACC3;
  46.     F_TM=0;
  47.     while(!F_TM);
  48.     BT_SND=ACC4;
  49.     F_TM=0;
  50.     while(!F_TM);
  51.     BT_SND=ACC5;
  52.     F_TM=0;
  53.     while(!F_TM);
  54.     BT_SND=ACC6;
  55.     F_TM=0;
  56.     while(!F_TM);
  57.     BT_SND=ACC7;
  58.     F_TM=0;
  59.     while(!F_TM);
  60.     BT_SND=1;
  61.     F_TM=0;
  62.     while(!F_TM);
  63.     TIMER0_DISABLE; //停止timer
  64.     #else
  65.     unsigned char ii;
  66.      ii=0;
  67.      F_TM=0;
  68.      BT_SND=0; //start bit
  69.      TIMER0_ENABLE; //啟動
  70.      while(!F_TM);
  71.      while(ii<8)
  72.         {
  73.           if(inch&1)
  74.          {
  75.           BT_SND=1;
  76.          }
  77.          else
  78.          {
  79.           BT_SND=0;
  80.          }
  81.           F_TM=0;
  82.         while(!F_TM);
  83.           ii++;
  84.          inch>>=1;
  85.     }
  86.          BT_SND=1;
  87.          F_TM=0;
  88.          while(!F_TM);
  89.     #endif
  90.     TIMER0_DISABLE; //停止timer
  91. }
  92. //接收一個字符
  93. unsigned char PGetChar()
  94. {
  95.         #ifdef MODE_QUICK
  96.         TIMER0_ENABLE;
  97.         F_TM=0;
  98.         while(!F_TM); //等過起始位
  99.         ACC0=BT_REC;
  100.         TL0=TH0;
  101.         F_TM=0;
  102.         while(!F_TM);
  103.         ACC1=BT_REC;
  104.         F_TM=0;
  105.         while(!F_TM);
  106.         ACC2=BT_REC;
  107.         F_TM=0;
  108.         while(!F_TM);
  109.         ACC3=BT_REC;
  110.         F_TM=0;
  111.         while(!F_TM);
  112.         ACC4=BT_REC;
  113.         F_TM=0;
  114.         while(!F_TM);
  115.         ACC5=BT_REC;        
  116.         F_TM=0;
  117.         while(!F_TM);
  118.         ACC6=BT_REC;        
  119.         F_TM=0;
  120.         while(!F_TM);
  121.         ACC7=BT_REC;
  122.         F_TM=0;
  123.         while(!F_TM)
  124.     {
  125.                 if(BT_REC)
  126.                 {
  127.                   break;
  128.                 }
  129.     }
  130.         TIMER0_DISABLE; //停止timer
  131.         return ACC;
  132.         #else
  133.         unsigned char rch,ii;
  134.         TIMER0_ENABLE;
  135.         F_TM=0;
  136.         ii=0;
  137.         rch=0;
  138.         while(!F_TM); //等過起始位
  139.         while(ii<8)
  140.     {
  141.             rch>>=1;
  142.                 if(BT_REC)
  143.                 {
  144.                 rch|=0x80;
  145.                 }                                       
  146.                 ii++;
  147.                 F_TM=0;
  148.                 while(!F_TM);        
  149.     }
  150.         F_TM=0;
  151.          while(!F_TM)
  152.     {
  153.                 if(BT_REC)
  154.                 {
  155.                    break;
  156.                 }
  157.     }
  158.         TIMER0_DISABLE; //停止timer
  159.         return rch;
  160.         #endif
  161. }
  162. //檢查是不是有起始位
  163. bit StartBitOn()
  164. {
  165.   return (BT_REC==0);
  166. }
  167. //定時器1初始化
  168. void Time1_Init(void)
  169. {
  170.    TMOD=0x22; //定時器1為工作模式2(8位自動重裝),0為模式2(8位自動重裝)
  171.    PCON=00;
  172.    TR0=0; //在發(fā)送或接收才開始使用
  173.    TF0=0;
  174.    TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 執(zhí)行的timer//104.167*11.0592/12= 96
  175.    TL0=TH0;
  176.    ET0=1;
  177.    EA=1;
  178. }
  179. //發(fā)送字符串
  180. void Send_Char(char *byte)
  181. {
  182.    int i=0;
  183.    for(i=0;*(byte+i)!='\0';i++)
  184.    {
  185.       PSendChar(*(byte+i));
  186.    }
  187. }
  188. //void delay(int x)
  189. //{
  190. //        int a,b;
  191. //        for(a=x;a>0;a--)
  192. //                for(b=10;b>0;b--);
  193. //}
  194. //void main()
  195. //{
  196. //   unsigned char gch;
  197. //   Time1_Init();
  198. //   LED=0;
  199. //  // Send_Char("S00.0C00.0%E00.0C00.0%L00000lx");
  200. //   while(1)
  201. //  {         
  202. //      
  203. //          PSendChar('1');
  204. //          delay(1000);
  205. ////      if(StartBitOn())
  206. ////          {
  207. ////            gch=PGetChar();
  208. ////            if(gch=='1')
  209. ////                {
  210. ////                  LED=LED_flage;  
  211. ////                  delay(1000);
  212. ////                  LED_flage=~LED_flage;
  213. ////                }
  214. ////               
  215. ////          }        
  216. //           
  217. //  }           
  218. //
  219. //}
復(fù)制代碼



相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:164411 發(fā)表于 2017-4-24 14:53 | 顯示全部樓層
你好能發(fā)給大家 接收字符串的嗎?
回復(fù)

使用道具 舉報(bào)

ID:164411 發(fā)表于 2017-4-24 15:06 | 顯示全部樓層
我可以模擬得了串口接收到數(shù)據(jù),但是總接收不到字符串
回復(fù)

使用道具 舉報(bào)

ID:128463 發(fā)表于 2017-5-1 12:16 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

ID:593300 發(fā)表于 2019-7-31 20:52 來自觸屏版 | 顯示全部樓層
謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:596409 發(fā)表于 2019-8-20 17:42 | 顯示全部樓層
這個程序試過,為什么發(fā)送的時候連續(xù)的字符會丟失中間的,如果加一個空格就都可以收到
回復(fù)

使用道具 舉報(bào)

ID:301055 發(fā)表于 2019-8-20 23:41 | 顯示全部樓層
十分感謝  開源萬歲
回復(fù)

使用道具 舉報(bào)

ID:339215 發(fā)表于 2022-3-23 17:46 | 顯示全部樓層
parmhan 發(fā)表于 2019-8-20 17:42
這個程序試過,為什么發(fā)送的時候連續(xù)的字符會丟失中間的,如果加一個空格就都可以收到

做個緩存,然后從緩存發(fā)出去不會
回復(fù)

使用道具 舉報(bào)

ID:847934 發(fā)表于 2022-4-3 12:37 | 顯示全部樓層
小屁 發(fā)表于 2022-3-23 17:46
做個緩存,然后從緩存發(fā)出去不會

請問做緩存應(yīng)該怎么做呢?
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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