【声明】此程序仅用于学习与参考!
*********************************************************************/
#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();
}
}
}
|