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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 18679|回復: 2
收起左側

51單片機串口Uart1 Uart2收發程序帶校驗

[復制鏈接]
ID:26188 發表于 2015-2-18 01:27 | 顯示全部樓層 |閱讀模式
//包含文件定義
//#include "reg51.h"
//#include <stc.h>
#include "intrins.h"
#include "string.h"
//串口相關常量定義
#define  FOSC              22118400L   //系統頻率11059200L 22118400L
#define  Uart1_MaxString   32          //串口1最大接收緩沖區字符數量(0-31)共32個字符
#define  Uart2_MaxString   32          //串口2最大接收緩沖區字符數量(0-31)共32個字符
//串口相關變量定義
char           Uart1_Data[Uart1_MaxString];   //串口1接收字串
unsigned char  Uart1_String_P;                //串口1接收字串位置指針
bit            Uart1_busy;                    //串口1正在發送標記,1,正在發送,0,發送完成
unsigned char  Uart1_ParitySet;               //串口1奇偶校驗方式 0不校驗 1奇校驗 2偶校驗 3始終1 4始終0
bit            Uart1_Parity;                  //串口1接收到的奇偶校驗狀態 1,0
bit            Uart1_Parity_out;              //串口1驗證接收到的奇偶校驗狀態 1,驗證,0驗證錯誤
char           Uart2_Data[Uart1_MaxString];   //串口2接收字串
unsigned char  Uart2_String_P;                //串口2接收字串位置指針
bit            Uart2_busy;                    //串口2正在發送標記,1,正在發送,0,發送完成
unsigned char  Uart2_ParitySet;               //串口2奇偶校驗方式 0不校驗 1奇校驗 2偶校驗 3始終1 4始終0
bit            Uart2_Parity;                  //串口2接收到的奇偶校驗狀態 1,0
bit            Uart2_Parity_out;              //串口2驗證接收到的奇偶校驗狀態 1,驗證,0驗證錯誤
//Uart1包含函數申明
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx); //串口1波特率和時基源設置函數
void Uart1_SendData(unsigned char Uart1_dat);                  //串口1單字符發送函數
void Uart1_SendString(char *s);                          //串口1字符串發送函數
//void Uart1_Isr() interrupt 4 using 1;                    //串口1中斷服務函數
void Uart2_Setup(unsigned long Uart2_Baud);              //串口2波特率
void Uart2_SendData(unsigned char Uart2_dat);                  //串口2單字符發送函數
void Uart2_SendString(char *s);                          //串口2字符串發送函數
//void Uart1_Isr() interrupt 4 using 1;                    //串口2中斷服務函數
/*串口編程示范============================================================================
Uart1_String_P=0;                //串口1接收字串下標歸0
Uart1_ParitySet=1;               //串口1使用9位可變波特率方式,校驗方式為奇校驗
Uart1_Setup(9600,0);             //串口1波特率為9600bps,時基源選擇定時器1
Uart1_SendString("hello word");  //串口1發送數據,英文字母 hello word
Uart2_String_P=0;                //串口2接收字串下標歸0
Uart2_ParitySet=1;               //串口2使用9位可變波特率方式,校驗方式為奇校驗
Uart2_Setup(9600);               //串口2波特率為9600bps
Uart2_SendString("hello word");  //串口2發送數據,英文字母 hello word
=======================================================================================*/
/*********************************************************
** 函數名稱: void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
** 功能描述: 初始化串口函數
** 輸   入: unsigned long Uart1_Baud,bit Uart1_Tx
** 輸   出: 無
** 全局變量: PCON,SCON,TMOD,AUXR,TCON,TH1,
** 調用模塊:
** 備    注:時鐘為22118400Hz
            參數1:波特率設置,300;600;1200;2400;4800;9600;19200
            參數2:計數器選擇,0,定時器1;1,獨立波特率
**********************************************************/
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
{
unsigned int Uart1_Brt;
//時基源設置-------------------------------------------------
if(Uart1_Tx)
    {
AUXR |= 0x01;  //串口1選擇獨立波特率發生器
}
else
    {
AUXR &= 0xFE;  //串口1選擇定時器1做波特率發生器
}
//校驗方式設置-------------------------------------------------
switch (Uart1_ParitySet)
    {//判斷校驗方式
    case 1:
        {//9位串口, 奇校驗 Uart1_ParitySet=1;   //校驗位初值狀態標記置1
        SCON=0xD8;           //9位波特率可變,允許接收,TB8待發第9位初始置1
        break;
        }
    case 2:
        {//9位串口, 偶校驗 Uart1_ParitySet=2;   //校驗位初值狀態標記置2
        SCON=0xD4;           //9位波特率可變,允許接收,RB8待收第9位初始置1
        break;
        }
    case 3:
        {//9位串口, 掩碼校驗 校驗值始終為 1 Uart1_ParitySet=3;   //校驗位初值狀態標記置3
        SCON|=0xD8;         //9位波特率可變,允許接收,TB8待發第9位初始置1
        break;
        }
    case 4:
        {//9位串口, 空校驗 校驗值始終為 0 Uart1_ParitySet=4;   //校驗位初值狀態標記置4
        SCON=0xD4;          //9位波特率可變,允許接收,RB8待收第9位初始置1
        break;
        }
    default:
        {//8位串口, 無校驗 Uart1_ParitySet=0;   //校驗位初值狀態標記置0
        SCON&=0x5F;         //清除第5位,第7位
        SCON|=0x50;         //8位波特率可變,允許接收
        break;
        }
    }
//波特率設置并開始運行串口-------------------------------------------------
//時鐘為22118400Hz
Uart1_Brt=FOSC/32/Uart1_Baud;
if(Uart1_Brt>255)
    {//如果重裝值>255,使用12T模式12分頻
    if(Uart1_Tx)
        {//如果使用獨立波特率發生器
        //PCON |= 0x80;                                 //串口1波特率加倍
        //PCON &= 0x7f;                                 //串口1波特率不加倍
        AUXR &= 0xFB;                                 //獨立波特率使用12T模式
        //AUXR |= 0x04;                                 //獨立波特率使用1T模式
        BRT = 256-Uart1_Brt/12;                       //獨立波特率發生器初值設置
        AUXR|= 0x10;                                  //獨立波特率發生器開始計數
        }
    else
        {//如果使用定時器1做波特率發生器
        TMOD&=0xCF;                                 //清除定時器1設置狀態,定時器0不修改
        TMOD|=0x20;                                 //定時器1使用8位自動重裝模式
        //PCON |= 0x80;                               //串口1波特率加倍
        //PCON &= 0x7f;                               //串口1波特率不加倍
        AUXR &= 0xBF;                               //定時器1使用12T模式
        //AUXR|=0x40;                                 //定時器1使用1T模式
        TH1  = TL1 = 256-Uart1_Brt/12;              //設置自動裝入的值
        ET1  = 0;                                   //關閉定時器1中斷
        TR1  = 1;                                   //TCON|=0x40;定時器1開始計數,TCON&=0xBF;關閉計數
        }
    }
else
    {//如果重裝值<255,使用1T模式1分頻
    if(Uart1_Tx)
        {//如果使用獨立波特率發生器
        //PCON |= 0x80;                                 //串口1波特率加倍
        //PCON &= 0x7f;                                 //串口1波特率不加倍
        //AUXR &= 0xFB;                                 //獨立波特率使用12T模式
        AUXR |= 0x04;                                 //獨立波特率使用1T模式
        BRT  = 256-Uart1_Brt;                         //獨立波特率發生器初值設置
        AUXR|= 0x10;                                  //獨立波特率發生器開始計數
        }
    else
        {//如果使用定時器1做波特率發生器
        TMOD&=0xCF;                                 //清除定時器1設置狀態,定時器0不修改
        TMOD|=0x20;                                 //定時器1使用8位自動重裝模式
        //PCON |= 0x80;                               //串口1波特率加倍
        //PCON &= 0x7f;                               //串口1波特率不加倍
        //AUXR &= 0xBF;                               //定時器1使用12T模式
        AUXR|=0x40;                                 //定時器1使用1T模式
        TH1  = TL1 = 256-Uart1_Brt;                 //設置自動裝入的值
        ET1  = 0;                                   //關閉定時器1中斷
        TR1  = 1;                                   //TCON|=0x40;定時器1開始計數,TCON&=0xBF;關閉計數
        }
    }
    ES        = 1;                                  //打開串口中斷
    EA        = 1;                                  //打開總中斷
}
/*********************************************************
** 函數名稱: void Uart2_Setup(unsigned long Uart2_Baud)
** 功能描述: 初始化串口函數
** 輸   入: unsigned long Uart1_Baud
** 輸   出: 無
** 全局變量:
** 調用模塊:
** 備    注:時鐘為22118400Hz
            參數1:波特率設置,300;600;1200;2400;4800;9600;19200
**********************************************************/
void Uart2_Setup(unsigned long Uart2_Baud)
{
unsigned int Uart2_Brt;
//校驗方式設置-------------------------------------------------
switch (Uart2_ParitySet)
    {//判斷校驗方式
    case 1:
        {//9位串口, 奇校驗 Uart1_ParitySet=1;   //校驗位初值狀態標記置1
        S2CON=0xD8;           //9位波特率可變,允許接收,TB8待發第9位初始置1
        break;
        }
    case 2:
        {//9位串口, 偶校驗 Uart1_ParitySet=2;   //校驗位初值狀態標記置2
        S2CON=0xD4;           //9位波特率可變,允許接收,RB8待收第9位初始置1
        break;
        }
    case 3:
        {//9位串口, 掩碼校驗 校驗值始終為 1 Uart1_ParitySet=3;   //校驗位初值狀態標記置3
        S2CON|=0xD8;         //9位波特率可變,允許接收,TB8待發第9位初始置1
        break;
        }
    case 4:
        {//9位串口, 空校驗 校驗值始終為 0 Uart1_ParitySet=4;   //校驗位初值狀態標記置4
        S2CON=0xD4;          //9位波特率可變,允許接收,RB8待收第9位初始置1
        break;
        }
    default:
        {//8位串口, 無校驗 Uart1_ParitySet=0;   //校驗位初值狀態標記置0
        S2CON&=0x5F;         //清除第5位,第7位
        S2CON|=0x50;         //8位波特率可變,允許接收
        break;
        }
    }
//波特率設置并開始運行串口-------------------------------------------------
//時鐘為22118400Hz
Uart2_Brt=FOSC/32/Uart2_Baud;
if(Uart2_Brt>255)
    {//如果重裝值>255,使用12T模式12分頻
        //PCON |= 0x80;                                 //串口1波特率加倍
        //PCON &= 0x7f;                                 //串口1波特率不加倍
        AUXR &= 0xFB;                                 //獨立波特率使用12T模式
        //AUXR |= 0x04;                                 //獨立波特率使用1T模式
        BRT = 256-Uart2_Brt/12;                       //獨立波特率發生器初值設置
    }
else
    {//如果重裝值<255,使用1T模式1分頻
        //PCON |= 0x80;                                 //串口1波特率加倍
        //PCON &= 0x7f;                                 //串口1波特率不加倍
        //AUXR &= 0xFB;                                 //獨立波特率使用12T模式
        AUXR |= 0x04;                                 //獨立波特率使用1T模式
        BRT  = 256-Uart2_Brt;                         //獨立波特率發生器初值設置
    }
    AUXR|= 0x10;                                  //獨立波特率發生器開始計數
IE2|=0x01;                                    ////打開串口2中斷
    EA   = 1;                                     //打開總中斷
}
//=======================================================================================
/**********************************************************
串口1中斷服務函數
**********************************************************/
void Uart1_Isr() interrupt 4 using 1
{// UART 中斷服務函數
EA=0; //關總中斷
if (RI)
{//如果 UART 接收產生中斷
    RI = 0;                                           //清除 UART 接收中斷標記
    ACC= SBUF;                                        //接收緩沖區數據寫入累加器A
    Uart1_Parity = P;                                 //保存校驗值到Uart1_Parity
    Uart1_Parity_out=0;                               //清除允許寫入標記,為下面判斷準備
    switch(Uart1_ParitySet)
    {//根據校驗要求判斷
        case 1:
        {//要求奇校驗
        Uart1_Parity_out=Uart1_Parity^RB8;    //如果檢驗結果和接收結果不符合則成立,允許寫入
        break;
        }
        case 2:
        {//要求偶校驗
        Uart1_Parity_out=~(Uart1_Parity^RB8); //如果檢驗結果和接收結果符合則成立,允許寫入
        break;
        }
        case 3:
        {//要求常1校驗
        Uart1_Parity_out=RB8;                 //如果接收結果為1則成立,允許寫入
        break;
        }
        case 4:
        {//要求常0校驗
        Uart1_Parity_out=~RB8;                //如果接收結果為0則成立,允許寫入
        break;
        }
        default:
        {//要求無校驗
        Uart1_Parity_out=1;                  //如果無校驗,允許寫入
        break;
        }
    }
    if(Uart1_Parity_out)
    {//如果允許寫入
        Uart1_Data[Uart1_String_P]= SBUF;              //接收緩沖區數據順序寫入串口接收字串
        Uart1_String_P++;                              //串口接收字串指針累加
        //↓如果串口接收字串指針在大于最大接收緩沖區字符數量,串口接收字串指針歸零
        if(Uart1_String_P >= Uart1_MaxString)
        {//如果接受字串指針越界
            Uart1_String_P=0;                          //接受字串指針歸零
        }
    }
}
if (TI)
{//如果 UART 發送產生中斷
    TI   = 0;                  //清除 UART 發送中斷標記
    Uart1_busy = 0;            //發送完成,清除正在發送標記
}
EA=1;                          //開總中斷
}
//=======================================================================================
/**********************************************************
串口2中斷服務函數
**********************************************************/
void Uart2_Isr() interrupt 8 using 1
{// UART 中斷服務函數
EA=0; //關總中斷
if (S2CON&0x01)
{//如果 UART 接收產生中斷
    S2CON &= 0xFE;                                     //清除 UART 接收中斷標記
    ACC= S2BUF;                                        //接收緩沖區數據寫入累加器A
    Uart2_Parity = P;                                  //保存校驗值到Uart1_Parity
    Uart2_Parity_out=0;                                //清除允許寫入標記,為下面判斷準備
    switch(Uart2_ParitySet)
    {//根據校驗要求判斷
        case 1:
        {//要求奇校驗
        Uart2_Parity_out=Uart2_Parity^(S2CON&0x04);    //如果檢驗結果和接收結果不符合則成立,允許寫入 (S2CON&0x04)==S2RB8
        break;
        }
        case 2:
        {//要求偶校驗
        Uart2_Parity_out=~(Uart2_Parity^(S2CON&0x04)); //如果檢驗結果和接收結果符合則成立,允許寫入
        break;
        }
        case 3:
        {//要求常1校驗
        Uart2_Parity_out=(S2CON&0x04);                 //如果接收結果為1則成立,允許寫入
        break;
        }
        case 4:
        {//要求常0校驗
        Uart2_Parity_out=~(S2CON&0x04);                //如果接收結果為0則成立,允許寫入
        break;
        }
        default:
        {//要求無校驗
        Uart2_Parity_out=1;                  //如果無校驗,允許寫入
        break;
        }
    }
    if(Uart2_Parity_out)
    {//如果允許寫入
        Uart2_Data[Uart2_String_P]= S2BUF;              //接收緩沖區數據順序寫入串口接收字串
        Uart2_String_P++;                              //串口接收字串指針累加
        //↓如果串口接收字串指針在大于最大接收緩沖區字符數量,串口接收字串指針歸零
        if(Uart2_String_P >= Uart2_MaxString)
        {//如果接受字串指針越界
            Uart2_String_P=0;                          //接受字串指針歸零
        }
    }
}
if (S2CON&0x02)
{//如果 UART 發送產生中斷
    S2CON &= 0xFD;                  //清除 UART 發送中斷標記
    Uart2_busy = 0;            //發送完成,清除正在發送標記
}
EA=1;                          //開總中斷
}

//=======================================================================================
/**********************************************************
** 函數名稱: void Uart1_SendData(unsigned char Uart1_dat)
** 功能描述: UART1 單個字符發送函數
** 輸   入: unsigned char Uart1_dat
** 輸   出: 無
** 全局變量:
** 調用模塊:
** 備    注:參數1:待發送的單個字符
**********************************************************/
void Uart1_SendData(unsigned char Uart1_dat)
{//UART 發送字節函數
    while (Uart1_busy);       //循環等待正在發送標記被清空
    ACC = Uart1_dat;                //被發送數據送累加器A,準備求奇偶校驗位 P
    TB8 = P;                  //寫奇偶校驗標記
    switch(Uart1_ParitySet)
    {//根據校驗要求判斷
        case 1:
        {//要求奇校驗
            TB8=~TB8;        //翻轉TB8的值
            break;
        }
        /*偶校驗,TB8不變
        case 2:
        {//要求偶校驗
            TB8=TB8;            //TB8不變
            break;
        }
        */
        case 3:
        {//要求常1校驗
            TB8=1;            //TB8恒等于1
            break;
        }
        case 4:
        {//要求常0校驗
            TB8=0;            //TB8恒等于0
            break;
        }
        default:
        {//要求無校驗
        break;
        }
    }
    Uart1_busy = 1;          //正在發送標記置 1
    SBUF = ACC;              //累加器 A 中的數據送發送緩沖區發送
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart2_SendData(unsigned char Uart2_dat)
** 功能描述: UART2 單個字符發送函數
** 輸   入: unsigned char Uart2_dat
** 輸   出: 無
** 全局變量:
** 調用模塊:
** 備    注:參數1:待發送的單個字符
**********************************************************/
void Uart2_SendData(unsigned char Uart2_dat)
{//UART 發送字節函數
    while (Uart2_busy);       //循環等待正在發送標記被清空
    ACC = Uart2_dat;                //被發送數據送累加器A,準備求奇偶校驗位 P
    TB8 = P;                  //寫奇偶校驗標記
    switch(Uart2_ParitySet)
    {//根據校驗要求判斷
        case 1:
        {//要求奇校驗
            S2CON^=0x08;        //翻轉S2TB8的值
            break;
        }
        /*偶校驗,S2TB8不變
        case 2:
        {//要求偶校驗
            S2TB8=1;            //S2TB8不變
            break;
        }
        */
        case 3:
        {//要求常1校驗
            S2CON|=0x08;            //S2TB8恒等于1
            break;
        }
        case 4:
        {//要求常0校驗
            S2CON&=0xF7;            //TB8恒等于0
            break;
        }
        default:
        {//要求無校驗
        break;
        }
    }
    Uart2_busy = 1;          //正在發送標記置 1
    S2BUF = ACC;              //累加器 A 中的數據送發送緩沖區發送
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart1_SendString(char *s)
** 功能描述: UART1 按字符串發送函數
** 輸   入: char *s
** 輸   出: 無
** 全局變量:
** 調用模塊:
** 備    注:參數1:待發送的字符串
**********************************************************/
void Uart1_SendString(char *s)
{//UART 按字符串發送
    while (*s)
    {
        Uart1_SendData(*s++);   //將待發字符串依次使用SendData函數按字節發送
    }
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart2_SendString(char *s)
** 功能描述: UART2 按字符串發送函數
** 輸   入: char *s
** 輸   出: 無
** 全局變量:
** 調用模塊:
** 備    注:參數1:待發送的字符串
**********************************************************/
void Uart2_SendString(char *s)
{//UART 按字符串發送
    while (*s)
    {
        Uart2_SendData(*s++);   //將待發字符串依次使用SendData函數按字節發送
    }
}
//=======================================================================================
/*常用串口設置開關===============================副錄===================================
AUXR |= 0x01;  //串口1選擇獨立波特率發生器
AUXR &= 0xFE;  //串口1選擇定時器1做波特率發生器
AUXR |= 0x40;  //定時器1使用1T模式
AUXR &= 0xBF;  //定時器1使用12T模式
AUXR |= 0x04;  //獨立波特率使用1T模式
AUXR &= 0xFB;  //獨立波特率使用12T模式
AUXR |= 0x10;  //打開獨立波特率發生器
AUXR &= 0xEF;  //關閉獨立波特率發生器
PCON |= 0x80;  //串口1波特率加倍
PCON &= 0x7f;  //串口1波特率不加倍
AUXR |= 0x08;   //串口2波特率加倍
AUXR &= 0xf7;   //串口2波特率不加倍
=======================================================================================*/



回復

使用道具 舉報

ID:367948 發表于 2018-8-3 11:42 | 顯示全部樓層
學習了
回復

使用道具 舉報

ID:975054 發表于 2021-11-14 01:05 | 顯示全部樓層
內容完整豐富
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕免费在线 | 日韩中文字幕一区 | 搞黄网站在线观看 | 久久国产成人 | 国产一区欧美一区 | av香蕉| 久久综合一区二区三区 | 国产小u女发育末成年 | 精品www| 日韩三级电影在线看 | 国产精品久久久久久久午夜 | 欧美一级做性受免费大片免费 | 韩国av影院 | 巨大黑人极品videos精品 | 伊人二区 | www.xxxx欧美| 天天操 夜夜操 | 91精品国产91久久久久游泳池 | 成人av电影免费在线观看 | 久久久久无码国产精品一区 | 国产一区二区三区免费观看视频 | 免费国产一区二区 | 国产欧美精品一区二区 | 国产精品福利在线观看 | 999久久久 | 国产成人网 | 一区二区三区在线免费观看 | 日韩色在线 | 日韩在线欧美 | 亚洲视频一区在线观看 | 国产精品一区二区视频 | 欧美日韩精品一区 | 成人a免费 | av av在线| 亚洲狠狠爱一区二区三区 | 日韩在线视频免费观看 | 国产视频一二三区 | 精品久久99| 国产不卡在线 | 91精品国产综合久久精品 | 国产免费拔擦拔擦8x高清 |