?? testcom.c
字號:
#include <CPU.H>
// 類型定義
#define BYTE unsigned char
#define UINT unsigned int
#define BOOL unsigned int
#define ULNG unsigned long
///////////////////
// 硬件引腳功能定義 //
///////////////////
sbit bCSX = P1^4; // p1.4(PLCC44-P6)為程序運行指示,低電平亮;
////////////
// 時鐘計數 //
////////////
BYTE ucMsCount; // 用于1ms計時(受GPS脈沖控制)
UINT uiMsNow; // 當前毫秒數(受GPS脈沖控制)
bit b250MsPassed; // 已經過了250毫秒, LED-RUN
bit bOneSecPassed; // 已經過了1秒
BYTE ucSecCount; // 用于1s計時(受GPS脈沖控制)
bit bOneMinPassed; // 每分鐘,重新初始化一次串口,以提高可靠性
// 中斷服務初始化
void vInterruptInitialize()
{
// =====================================================
// IE:中斷允許寄存器;復位后:IE = 0x00;1允許,0-禁止;
// =====================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// -----------------------------------------------------
// EA ET2 ES ET1 EX1 ET0 EX0
// -----------------------------------------------------
// EX0,EX1:外部中斷0、1的中斷允許位;
// ET0,ET1:定時器/計數器0、1(T/C0,T/C1)溢出中斷允許位;
// ES:串口中斷允許位;
// ET2:定時器/計數器2(T/C2)溢出中斷允許位;
// EA:CPU總的中斷允許;
// -----------------------------------------------------
// =================================================
// IP:中斷優先級寄存器;復位后:IP = 0x00;1→高,0→低;
// =================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// -------------------------------------------------
// PT2 PS PT1 PX1 PT0 PX0
// -------------------------------------------------
// PX0,PX1:外部中斷0、1中斷優先級控制位;
// PT0,PT1:定時器/計數器0、1中斷優先級控制位;
// PS:串口中斷優先級控制位;
// PT2:定時器/計數器2(T/C2)中斷優先級控制位;
// -------------------------------------------------
// ======================================================
// TCON:定時器/計數器控制寄存器;復位后:TCON = 0x00
// ======================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// --------------------------------------------------------
// TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
// --------------------------------------------------------
// TF1,TF0:定時器x溢出中斷標志,當定時器x溢出時由內部硬件至置位,
// 當CPU轉向中斷服務程序時,由內部硬件清除;
// TR1,TR0:定時器運行控制位,由軟件置位、清除來控制定時器開啟、關閉;
// IE1,IE0:外部觸發中斷請求標志;
// IT1,IT0:外部中斷觸發方式,1-下降沿觸發;0-低電平觸發;
// --------------------------------------------------------
EA = 0; // 中斷允許總控制
EX0 = 0; // 外部中斷0允許
EX1 = 0; // 外部中斷1允許
IT0 = 0; // 外部中斷0外下降沿有效
IT1 = 0; // 外部中斷1外下降沿有效
PS = 1; // 串口中斷優先級高
ES = 1; // 串口中斷使能
PX0 = 0; // 外部中斷0優先級低
PX1 = 0; // 外部中斷1優先級低
ET1 = 0; // 定時器1禁止中斷
// =================================================
// TMOD: 定時器工作方式控制寄存器,復位后TMOD = 0x00
// =================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// -------------------+---------------------------
// GATE C//T M1 M0 | GATE C//T M1 M0
// -------------------+---------------------------
// ------ 定時器1 -----+--- 定時器0 ---------------
// M1、M0:工作方式設置;
// 00-13位計數器;
// 01-16位計數器;
// 10-可自動再裝入的8位計數器(從THx中自動裝到TLx中);
// 11-把定時器分為兩個8為的計數器或關閉定時器1;
// C//T:1-計數器功能,0-定時器功能;
// GATE:選通控制;1-同時/INTx為高電平且TRx為1時選通定時器x;
// 0-每當TRx為1時就選通定時器x;
// -----------------------------------------------------
// 定時器/計數器0初始化
TMOD = (TMOD & 0xF0) | 0x2; // T0工作于:10-可自動再裝入的8位計數器(從THx中自動裝到TLx中);
// 22.1184MHz / 12分頻 = 計數頻率為1.8432MHz,100個us的設置
// (2^8 - TL) / (1.8432 * 10^6) = 10^(-4) ==> TL ≈ 72
TH0 = TL0 = 72;
ET0 = 1; // 定時器0允許中斷
TR0 = 1; // T0使能
EA = 1; // 中斷允許總控制
}
// 串口初始化
#define cnBaudRate 19200 // 19200bps、8、N、1
#define cnFosc 22118400 // 當前晶振: 22.1184MHz
bit bComSendBufEmpty; // 串口的發送緩沖區空的標志: 用于啟動TI
void vSerialInitialize()
{
// =====================================================================
// SCON:串口控制寄存器;復位后:SCON = 0x00;
// =====================================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// ---------------------------------------------------------------------
// SM0 SM1 SM2 REN TB8 RB8 TI RI
// ---------------------------------------------------------------------
// SM1.SM0串口工作方式控制:
// 00-同步移位寄存器fosc/12;移位寄存器工作方式;
// 01-異步收發,由定時器控制;8位數據位的UART工作方式;
// 10-異步收發,fosc/32或fosc/64;9位數據位的UART工作方式;
// 11-異步收發,由定時器控制;9位數據位的UART工作方式;
// 波特率:
// 00-同步fosc/12;
// 01.03-異步,
// 1. 16位定時器1的溢出中斷,2^SMOD * 定時器1的溢出率 / 32;例,要
// 取得110bps,定時器1的溢出率為32*110=3520,定時器1是加1定時器,
// 每12個振蕩周期加1,因此當fosc=12MHz時,定時器每隔284us中斷一次:
// fosc / (12 * 3520) = 12 * 10^6 / (12 * 2520) = 284us
// 考慮到溢出中斷后CPU響應中斷以及進行TH、TL的軟件重裝需要時間,
// 因此扣除8個us,則定時器1在裝入后定時276us發生一次中斷,可以計算
// 得到TH1=FEH、TL1=EBH。
// 常用波特率與其他參數的選取關系
// --------------------------------------------------------------
// 串口 波特率 fosc=6MHz fosc=12MHz fosc=11.0592Hz
// 工作方式 SMOD TMOD TH1 SMOD TMOD TH1 SMOD TMOD TH1
// --------------------------------------------------------------
// 方式0 1M x x x
// --------------------------------------------------------------
// 方式2 375k 1 x x
// 187.5k 1 x x 0 x x
// --------------------------------------------------------------
// 62.5k 1 20 FF
// 19.2k 1 20 FD
// 9.6k 0 20 FD
// 4.8k 1 20 F3 0 20 FA
// 方式1 2.4k 1 20 F3 0 20 F3 0 20 F4
// 或 1.2k 1 20 E6 0 20 E6 0 20 E8
// 方式3 600 1 20 CC 0 20 CC 0 20 D0
// 300 0 20 CC 0 20 98 0 20 A0
// 137.5 1 20 1D 0 20 1D 0 20 2E
// 110 0 20 72 0 10 FEEB 0 10 FEFF
// --------------------------------------------------------------
// 2. 自動重載方式的定時器2,TMOD=0010xxxx,則2^SMOD * fosc / (32 * 12 * (256 - TH1));
// 3. SMOD為PCON的最高位;
// 02-異步,fosc/32或fosc/64;
// SM2:多機通信控制為:1-收到第9位(RB8)為1,RI置1;0-接收到字符RI就置1;方式0時,SM2應為0;
// REN:串口接收允許位:1-允許;0-禁止;
// TB8:方式2和3時為發送的第9位數據,由軟件置位或清零;可以作為奇偶校驗位,或多機通信中表示地址或數據(1/0);
// RB8:方式2和3時為接收到的第9位數據,作為奇偶校驗位,或多機通信的地址或數據(1/0);方式1時,為接收到的停止位;
// TI:發送中斷標志:由硬件置位,必須由軟件清零;
// RI:接收中斷標志:由硬件置位,必須由軟件清零;
// -----------------------------------------------------------------------------------
// 波特率設置技術:波特率隨串口工作方式、晶振頻率、電源控制PCON的SMOD等有關,另外與定時器T1設置也有關
// 1. 方式0: 波特率 = fosc / 12;
// 2. 方式2: 波特率 = fosc / 64 (SMOD=0)、fosc / 32 (SMOD=1);
// 3. 方式1和3:
// 波特率 = T1溢出率 / n,n = 32或64,
// T1溢出率 = 計數速率 / (256 - X)
// T1為工作于方式2,即自動重裝載方式,X為TH1和TL1中裝入的初始計數值;
// 計數速率:定時器1的計數速率與定時器的工作方式選擇有關。當選擇T1為定時工作方式時,
// 計數速率 = fosc / 12,
// 由此可得,
// 波特率 = (2 ^ SMOD) / 32 * fosc / 12 /(256 - X)
// = (2 ^ SMOD) * fosc / (32 * 12 * (256 - X))
//
// X = 256 - (2 ^ SMOD) * fosc / (32 * 12 * 波特率)
// = 256 - (2 ^ SMOD) * fosc / (384 * 波特率)
//
// 例如:
// 假定波特率要求為9600bps,系統晶振為fosc=11.0592MHz,當SMOD=1時,TH1和TL1的初值:
//
// 波特率 = 2 * 11.0592 * (10^6) / (32 * 12 * (256 - X)),
// X = 256 - 2 * 11059200 / (384 * 9600)) = 250 = FAH,
//
// THTL = FAH,波特率 = 9599.836bps,誤差 = 0.00177%;
// -----------------------------------------------------------------------------------
// 數據位、奇偶校驗位和停止位的不同:
// (1B、8D、0P、1S)1位起始位、8位數據位、0位奇偶位、1位停止位;或者,
// (1B、7D、1P、1S)1位起始位、7位數據位、1位奇偶位、1位停止位;或者,
// (1B、7D、0P、2S)1位起始位、7位數據位、0位奇偶位、2位停止位;或者,
// (1B、8D、1P、1S)1位起始位、8位數據位、1位奇偶位、1位停止位;或者,
// (1B、8D、0P、2S)1位起始位、8位數據位、0位奇偶位、2位停止位;
//
// PSW.0是每一指令周期累加器A的奇偶標志,由硬件置位或清零;A中1的個數為偶數,則PSW.0為0;為奇數,
// PSW.0為1。因此,可以利用累加器A來完成不同方式下的通信需求。
//
// 設置采用:
// (1B、8D、0P、1S)、(1B、7D、1P、1S)和(1B、7D、2S)采用:
// 01-異步收發,由定時器控制;8位數據位的UART工作方式;SM2=0:接收到字符RI就置1;
// (1B、8D、1P、1S)和(1B、8D、2S)采用:
// 11-異步收發,由定時器控制;9位數據位的UART工作方式;SM2=0:接收到字符RI就置1;
//
// 數據發送:
// (1B、8D、0P、1S)1位起始位、8位數據位、0位奇偶位、1位停止位;
// 。發送該字節
//
// (1B、7D、1P、1S)1位起始位、7位數據位、1位奇偶位、1位停止位;
// 。將發送的字節屏蔽bit7后送入A,可以得到奇偶值P;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -