[15單片機] STC15F104W開發入門及模擬串口程序


STC15F104W開發入門及模擬串口程序

Saturday, 31. March 2018 09:42AM - beautifulzzzz

前言

最近找到一款51內核的SOP8封裝的8腳單片機STC15F10x與大家分享!

1、基本介紹

下面是其一個典型應用——紅外收發器實現:

是不是覺得麻雀雖小,五臟俱全呀,再看一下其架構圖:


下面是其部分型號的外設列表和采購價格圖(需要特別注意的是下面幾款都是不帶串口、CCP、PCA、PWM、AD的!因此,如果你想要用串口,就需要采用模擬的方法實現了。不過,好在宏晶官網提供了DEMO。):


2、DEMO&燒寫

STC15和之前燒寫STC51單片機一樣,需要用STC-ISP,通過USB轉TTL(RX接芯片的P31,TX接芯片的P30),選擇好芯片等信息,點擊下載,之后上電...

從官網下載最新的STC-ISP工具:stc-isp-15xx-v6.86L,務必要下載完全版!!!

在該工具的后面的范例程序中可以找到各種DEMO的C語言和匯編雙版本.

3、編程

STC-TOOL.pdf的第13章 編譯器(匯編器)/ISP編程器(燒錄)/仿真器說明中,介紹了用keil可以開發。由於STC15單片機型號較新,keil中目標單片機還沒有,可以用Intel 80/87C58作為目標單片機。

此外,可以在STC官網下載打包好的驅動和DEMO:STC15系列庫函數與例程測試版V1.0,2014-5-29

4、STC15F104W半雙工串口DEMO

/*************  功能說明    **************
使用STC15系列的Timer2做的模擬串口. P3.0接收, P3.1發送, 半雙工.
假定測試芯片的工作頻率為11059200HZ. 時鍾為5.5296MHZ ~ 35MHZ. 
波特率高,則時鍾也要選高, 優先使用 22.1184MHZ, 11.0592MHZ.
測試方法: 上位機發送數據, MCU收到數據后原樣返回.
串口固定設置: 1位起始位, 8位數據位, 1位停止位,  波特率在范圍如下.
1200 ~ 115200 bps @ 33.1776MHZ
 600 ~ 115200 bps @ 22.1184MHZ
 600 ~  76800 bps @ 18.4320MHZ
 300 ~  57600 bps @ 11.0592MHZ
 150 ~  19200 bps @  5.5296MHZ

******************************************/

#include    <reg52.h>

#define MAIN_Fosc       11059200UL  //定義主時鍾
#define UART3_Baudrate  9600UL    //定義波特率
#define RX_Lenth        32          //接收長度

#define UART3_BitTime   (MAIN_Fosc / UART3_Baudrate)

typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;

sfr IE2  = 0xAF;
sfr AUXR = 0x8E;
sfr INT_CLKO = 0x8F;
sfr T2H  = 0xD6;
sfr T2L  = 0xD7;

sfr P1M1 = 0x91;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull
sfr P1M0 = 0x92;    //                  =10--->pure input,  11--->open drain
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

u8  Tx3_read;           //發送讀指針
u8  Rx3_write;          //接收寫指針
u8  idata   buf3[RX_Lenth]; //接收緩沖

u16 RxTimeOut;
bit B_RxOk;     //接收結束標志


//===================== 模擬串口相關===========================
sbit P_RX3 = P3^0;  //定義模擬串口接收IO
sbit P_TX3 = P3^1;  //定義模擬串口發送IO

u8  Tx3_DAT;        // 發送移位變量, 用戶不可見
u8  Rx3_DAT;        // 接收移位變量, 用戶不可見
u8  Tx3_BitCnt;     // 發送數據的位計數器, 用戶不可見
u8  Rx3_BitCnt;     // 接收數據的位計數器, 用戶不可見
u8  Rx3_BUF;        // 接收到的字節, 用戶讀取
u8  Tx3_BUF;        // 要發送的字節, 用戶寫入
bit Rx3_Ring;       // 正在接收標志, 低層程序使用, 用戶程序不可見
bit Tx3_Ting;       // 正在發送標志, 用戶置1請求發送, 底層發送完成清0
bit RX3_End;        // 接收到一個字節, 用戶查詢 並清0
//=============================================================

void    UART_Init(void);

void main(void){
    
    P0M0 = P0M1 = P1M0 = P1M1 = P2M0 = P2M1 = P3M0 = P3M1 = 0x00;
	P4M0 = P4M1 = P5M0 = P5M1 = P6M0 = P6M1 = P7M0 = P7M1 = 0x00;

    UART_Init();    //PCA初始化
    EA = 1;
    
    while (1){       //user's function
        if (RX3_End){        // 檢測是否收到一個字節
            RX3_End = 0;    // 清除標志
            buf3[Rx3_write] = Rx3_BUF;  // 寫入緩沖
            if(++Rx3_write >= RX_Lenth) Rx3_write = 0;  // 指向下一個位置,  溢出檢測
            RxTimeOut = 1000;   //裝載超時時間
        }
        if(RxTimeOut != 0){      // 超時時間是否非0?
            if(--RxTimeOut == 0){    // (超時時間  - 1) == 0?
                B_RxOk = 1;
                AUXR &=  ~(1<<4);   //Timer2 停止運行
                INT_CLKO &= ~(1 << 6);  //禁止INT4中斷
                T2H = (65536 - UART3_BitTime) / 256;    //數據位
                T2L = (65536 - UART3_BitTime) % 256;    //數據位
                AUXR |=  (1<<4);    //Timer2 開始運行
            }
        }
        
        if(B_RxOk){      // 檢測是否接收OK?
            if (!Tx3_Ting){      // 檢測是否發送空閑
                if (Tx3_read != Rx3_write){  // 檢測是否收到過字符
                    Tx3_BUF = buf3[Tx3_read];   // 從緩沖讀一個字符發送
                    Tx3_Ting = 1;               // 設置發送標志
                    if(++Tx3_read >= RX_Lenth)  Tx3_read = 0;   // 指向下一個位置,  溢出檢測
                }else{
                    B_RxOk = 0;
                    AUXR &=  ~(1<<4);       //Timer2 停止運行
                    INT_CLKO |=  (1 << 6);  //允許INT4中斷
                }
            }
        }
    }
}

// 描述: UART初始化程序.
void UART_Init(void){
    Tx3_read  = 0;
    Rx3_write = 0;
    Tx3_Ting  = 0;
    Rx3_Ring  = 0;
    RX3_End   = 0;
    Tx3_BitCnt = 0;
    RxTimeOut = 0;
    B_RxOk = 0;

    AUXR &=  ~(1<<4);       // Timer2 停止運行
    T2H = (65536 - UART3_BitTime) / 256;    // 數據位
    T2L = (65536 - UART3_BitTime) % 256;    // 數據位
    INT_CLKO |=  (1 << 6);  // 允許INT4中斷
    IE2  |=  (1<<2);        // 允許Timer2中斷
    AUXR |=  (1<<2);        // 1T
}

// 描述: Timer2中斷處理程序.
void timer2_int (void) interrupt 12{
    if(Rx3_Ring){        //已收到起始位
    	if (--Rx3_BitCnt == 0){      //接收完一幀數據
            Rx3_Ring = 0;           //停止接收
            Rx3_BUF = Rx3_DAT;      //存儲數據到緩沖區
            RX3_End = 1;
            AUXR &=  ~(1<<4);   //Timer2 停止運行
            INT_CLKO |=  (1 << 6);  //允許INT4中斷
        }else{
            Rx3_DAT >>= 1;                  //把接收的單b數據 暫存到 RxShiftReg(接收緩沖)
            if(P_RX3) Rx3_DAT |= 0x80;      //shift RX data to RX buffer
        }
    }

    if(Tx3_Ting){                    // 不發送, 退出
        if(Tx3_BitCnt == 0){         //發送計數器為0 表明單字節發送還沒開始
        
            P_TX3 = 0;              //發送開始位
            Tx3_DAT = Tx3_BUF;      //把緩沖的數據放到發送的buff
            Tx3_BitCnt = 9;         //發送數據位數 (8數據位+1停止位)
        }else{                        //發送計數器為非0 正在發送數據
            if (--Tx3_BitCnt == 0){  //發送計數器減為0 表明單字節發送結束
                P_TX3 = 1;          //送停止位數據
                Tx3_Ting = 0;       //發送停止
            }else{
                Tx3_DAT >>= 1;      //把最低位送到 CY(益處標志位)
                P_TX3 = CY;         //發送一個bit數據
            }
        }
    }
}


/********************* INT4中斷函數 *************************/
void Ext_INT4 (void) interrupt 16{
    AUXR &=  ~(1<<4);   //Timer2 停止運行
    T2H = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) / 256;  //起始位 + 半個數據位
    T2L = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) % 256;  //起始位 + 半個數據位
    AUXR |=  (1<<4);    //Timer2 開始運行
    Rx3_Ring = 1;       //標志已收到起始位
    Rx3_BitCnt = 9;     //初始化接收的數據位數(8個數據位+1個停止位)
    
    INT_CLKO &= ~(1 << 6);  //禁止INT4中斷
    T2H = (65536 - UART3_BitTime) / 256;    //數據位
    T2L = (65536 - UART3_BitTime) % 256;    //數據位
}


鏈接

@beautifulzzzz
智能硬件、物聯網,熱愛技術,關注產品
博客:http://blog.beautifulzzzz.com
園友交流群:414948975


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM