【聲明】此程序僅用于學習與參考!
*********************************************************************/
#include "STC8A8K64D4.h"
#include "RTX51TNY.h"
#include "uart.h"
#include "PCC.h"
#include <intrins.h>
#define uchar unsigned char//宏定義無符號字符型
#define uint unsigned int //宏定義無符號整型
/*******************************************************************************
* 函 數 名 : System初始化
* 函數功能 : 任務0
* 作用 : 初始化函數和創建任務,使用完后記住刪除任務0
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void System_Init(void)
{
P0M1 = 0X00;//必須設置雙向io口
P0M0 = 0X00;
P1M1 = 0X00;//必須設置雙向io口
P1M0 = 0X00;
P2M1 = 0X00;
P2M0 = 0X00;
P3M1 = 0X00;
P3M0 = 0X00;
P4M1 = 0X00;
P4M0 = 0X00;
P5M1 = 0X00;
P5M0 = 0X00;
IT1 = 1; //使能INT1下降沿中斷
EX1 = 1; //使能INT1中斷
Init_UART();//串口轉移
ConfigUART();//串口1配置
Config2UART();//串口2配置
ConfigPCC();//配置脈沖捕獲
}
/*******************************************************************************
* 函 數 名 : task_create
* 函數功能 : 任務0
* 作用 : 初始化函數和創建任務,使用完后記住刪除任務0
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void task_create(void) _task_ 0
{
//系統初始化
System_Init();
//創建任務1、2
os_create_task(1);//串口監控
os_create_task(2);//串口1 2
os_create_task(3);//脈沖計數
os_delete_task(0);//刪除任務0
while(1)
{
;
}
}
#include "STC8A8K64D4.h"
#include "uart.h"
#include "PCC.h"
#include "RTX51TNY.h"
bit flagFrame=0,flagTxd=0,flagFrame2=0,flagTxd2=0;
unsigned char cntRxd = 0; //接收字節計數器
unsigned char xdata bufRxd[20];
unsigned char cnt2Rxd = 0; //接收字節計數器
unsigned char xdata buf2Rxd[20];
/********************************************************************
配置串口1
*********************************************************************/
void ConfigUART(void)
{
RS485_DIR = 0;
SCON = 0x50; //8位可變波特率
T2L = (65536 - (FOSC/4/BAUD)); //設置波特率重裝值
T2H = (65536 - (FOSC/4/BAUD))>>8;
AUXR = 0x14; //T2為1T模式, 并啟動定時器2
AUXR |= 0x01; //選擇定時器2為串口1的波特率發生器
ES = 1;
}
/*******************************************************************
* 串口轉移到P3.6 P3.7
********************************************************************/
void Init_UART(void)
{
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=1 S1_S1=0
ACC |= S1_S0; //(P3.6/RxD_2, P3.7/TxD_2)
P_SW1 = ACC;
}
/********************************************************************
配置串口2
*********************************************************************/
void Config2UART(void)
{
S2CON = 0x50; //8位可變波特率
T2L = (65536 - (FOSC/4/BAUD)); //設置波特率重裝值
T2H = (65536 - (FOSC/4/BAUD))>>8;
AUXR = 0x14; //T2為1T模式, 并啟動定時器2
AUXR |= 0x01; //選擇定時器2為串口1的波特率發生器
IE2 = 0x01;
}
/********************************************************************
串口1發送
*********************************************************************/
void UartWrite(unsigned char *buf, unsigned char len){//串口數據寫入,即串口發送函數,buf-待發送數據的指針,len-指定的發送長度
RS485_DIR = 1;
while (len--){ //循環發送所有字節
flagTxd = 0; //清零發送標志
SBUF = *buf; //發送一個字節數據
buf++;
while (!flagTxd); //等待該字節發送完成
}
RS485_DIR = 0;
}
/********************************************************************
串口2發送
*********************************************************************/
void Uart2Write(unsigned char *buf2, unsigned char len2){//串口數據寫入,即串口發送函數,buf-待發送數據的指針,len-指定的發送長度
while (len2--){ //循環發送所有字節
flagTxd2 = 0; //清零發送標志
S2BUF = *buf2; //發送一個字節數據
buf2++;
while (!flagTxd2); //等待該字節發送完成
}
}
/********************************************************************
串口1發送字符串
*********************************************************************/
//void Send_Uart2_string(unsigned char *p)//串口2發送字符串
//{
// unsigned char i=0,len_s=0;
// for(i=0;*(p+i)!='\0';i++);//得出字符串長度
// len_s=i;
// Uart2Write(p,len_s);
//}
/********************************************************************
串口監控
*********************************************************************/
void UartRxMonitor(unsigned char ms){//串口接收監控,由空閑時間判定幀結束,需在定時中斷中調用,ms-定時間隔
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0){ //接收計數器大于零時,監控總線空閑時間
if (cntbkp != cntRxd){ //接收計數器改變,即剛接收到數據時,清零空閑計時
cntbkp = cntRxd;
idletmr = 0;
}else{ //接收計數器未改變,即總線空閑時,累積空閑時間
if (idletmr < 20){ //空閑計時小于30ms時,持續累加
idletmr += ms;
if (idletmr >= 20){ //空閑時間達到30ms時,即判定為一幀接收完畢
flagFrame = 1; //設置幀接收完成標志
}
}
}
}else
if(cnt2Rxd > 0){
if (cntbkp != cnt2Rxd){
cntbkp = cnt2Rxd;
idletmr = 0;
}else{
if (idletmr < 20){
idletmr += ms;
if (idletmr >= 20){
flagFrame2 = 1;
}
}
}
}
else{
cntbkp = 0;
}
}
/********************************************************************
串口1接收
*********************************************************************/
void UartDriver(){//串口1接收
unsigned char xdata buf[30];
unsigned char len=0,lenx=0,bz=0,i=0;
unsigned int addr_s=0;
if(flagFrame==1)
{
flagFrame=0; //定時器0檢測接收的數據
len = cntRxd; //讀取接收的字節數量
lenx = cntRxd; //讀取接收的字節數量
cntRxd = 0; //接收計數器清零
//-----------調試-------------//
if(len==5)
{
if(bufRxd[0]==0xAA && bufRxd[1]==0x00 && bufRxd[2]==0x00 && bufRxd[3]==0x00 && bufRxd[4]==0xBB)
{
buf[0] = 0xAA;
buf[1] = num_mc/10000;
buf[2] = num_mc%10000/1000;//功能位
buf[3] = num_mc%1000/100;//收到
buf[4] = num_mc%100/10;//收到
buf[5] = num_mc%10;//收到
buf[6] = 0xff;
buf[7] = length/10000;
buf[8] = length%10000/1000;//功能位
buf[9] = length%1000/100;//收到
buf[10] = length%100/10;//收到
buf[11] = length%10;//收到
buf[12] = 0xBB;
len = 13;
UartWrite(buf, len); //發送
}
}
for(bz=lenx;bz>0;bz--){bufRxd[bz] = 0;} //把串口接收的數據緩存清零
lenx=0;len=0;
}
}
/********************************************************************
串口2接收
*********************************************************************/
void Uart2Driver(){//串口1接收
unsigned char xdata buf[20];
unsigned char len=0,lenx=0,bz=0,i=0;
if(flagFrame2==1)
{
flagFrame2=0; //定時器0檢測接收的數據
len = cnt2Rxd; //讀取接收的字節數量
lenx = cnt2Rxd; //讀取接收的字節數量
cnt2Rxd = 0; //接收計數器清零
//-----------調試-------------//
if(len==5)
{
if(buf2Rxd[0]==0xAA && buf2Rxd[1]==0x00 && buf2Rxd[2]==0x00 && buf2Rxd[3]==0x00 && buf2Rxd[4]==0xBB)
{
buf[0] = 0xAA;
buf[1] = length/1000;//功能位
buf[2] = length%1000/100;//收到
buf[3] = length%100/10;//收到
buf[4] = length%10;//收到
buf[5] = 0xff;
buf[6] = num_mc/1000;//功能位
buf[7] = num_mc%1000/100;//收到
buf[8] = num_mc%100/10;//收到
buf[9] = num_mc%10;//收到
buf[10] = 0xBB;
len = 11;
Uart2Write(buf, len); //發送
}
}
for(bz=lenx;bz>0;bz--){buf2Rxd[bz] = 0;} //把串口接收的數據緩存清零
}
}
/*******************************************************************************
* 函 數 名 : task_create
* 函數功能 : 任務1
* 作用 : 串口監控
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void task_UartRxMonitor (void) _task_ 1
{
while(1)
{
os_wait2(K_IVL,1);
UartRxMonitor(1);
os_send_signal(2);
}
}
/*******************************************************************************
* 函 數 名 : task_create
* 函數功能 : 任務2
* 作用 : 串口1接收
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void task_uart (void) _task_ 2
{
unsigned char sig=0;
unsigned int time=0;
while(1)
{
sig=os_wait1(K_SIG);
if(sig==SIG_EVENT)
{
UartDriver();
Uart2Driver();
}
}
}
|