#include "uart.h"
static u8 U1_rOver_Cnt = 0;
idata Usart_Read_STR U1_rSTR;
/***************************************************************************
* 描 述 : 串口1初始化函数
* 入 参 : 无
* 返回值 : 无
备注:波特率9600bps 晶振24MHz
**************************************************************************/
void Uart1_Init(uint32 Baud)
{
P3M1 &= 0xFE; P3M0 &= 0xFE; //设置P3.0为准双向口
P3M1 &= 0xFD; P3M0 |= 0x02; //设置P3.1为推挽输出
P_SW1 |= 0x00; //串口1引脚切换到 P30.P31
SCON = 0x50; //串口1工作模式为0,8位数据模式
AUXR &= 0xFE; //串口1选择定时器1作为波特率发生器
TMOD |= 0x00;
TL1 = (65536 - MAIN_Fosc / Baud / 4); //定时器2装初值
TH1 = (65536 - MAIN_Fosc / Baud / 4) >> 8;
TR1 = 1; //启动定时器1
AUXR |= 0x40; //定时器1,1T模式
ES = 1; //使能串口1中断
}
/***************************************************************************
* 描 述 : 串口1发送数据函数
* 入 参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void UART1_Send_byte(uint8 dat)
{
U1_rSTR.sBusy_Flag=1;
SBUF = dat; //写数据到UART数据寄存器
while(U1_rSTR.sBusy_Flag); //等待发送完成
}
/**************************************************************************************
* 描 述 : 串口1发送指定长度字符串
* 入 参 : 无
* 返回值 : 无
**************************************************************************************/
void Uart1_Send_xStr(uint8 *string,uint16 x)
{
while(x--)
{
UART1_Send_byte(*string++);
}
}
/**************************************************************************************
* 描 述 : 串口1发送字符串
* 入 参 : 无
* 返回值 : 无
**************************************************************************************/
void Uart1_Send_Str(uint8 *string)
{
while(*string != 0)
{
UART1_Send_byte(*string++);
}
}
/**************************************************************************************
* 描 述 : 串口1测试程序
* 入 参 : 无
* 返回值 : 无
**************************************************************************************/
void UART1_Tx_Puts(void)
{
if(U1_rSTR.RxBusy_Flag) //有新数据通过串口被接收到
{
RS485_Send_Str(U1_rSTR.rBuf);
U1_rSTR.RxBusy_Flag=FALSE; //清除接收标识符
CleanBufer(U1_rSTR.rBuf,U1_rSTR.rCnt);
USART1_RX_PROCESS_OK;
}
}
/***************************************************************************
* 描 述 : 串口1中断服务函数
* 入 参 : 无
* 返回值 : 无
**************************************************************************/
void Uart1() interrupt 4
{
unsigned char dat =0;
if (RI) //串行接收到停止位的中间时刻时,该位置1
{
RI = 0; //清除RI位 (该位必须软件清零)
dat=SBUF;
U1_rSTR.RxBusy_Flag=TRUE; //接收到数据,接收标识符有效
U1_rOver_Cnt = 5; //10毫秒未收到数据,认为数据接收完毕。
U1_rSTR.rOver = FALSE;
if(U1_rSTR.rCnt < UART_RBUF_LEN)
{
U1_rSTR.rBuf[U1_rSTR.rCnt] = SBUF;
U1_rSTR.rCnt++;
}
}
if (TI) //在停止位开始发送时,该位置1
{
TI = 0; //清除TI位(该位必须软件清零)
U1_rSTR.sBusy_Flag = 0; //清忙标志
}
}
/*----------------------------
* 判断串口1接收完成
* 放入定时器中断中
----------------------------*/
void Check_U1_rOver(void)
{
if(U1_rOver_Cnt != 0)
{
U1_rOver_Cnt--;
if(U1_rOver_Cnt == 0)
{
U1_rSTR.rOver = TRUE;
}
}
}
/*********************************Uart1 END FILE ********************************************/
/*----------------------------
* 判断串口1接收完成
* 放入定时器中断中
----------------------------*/
void Check_U2_rOver(void)
{
if(U2_rOver_Cnt != 0)
{
U2_rOver_Cnt--;
if(U2_rOver_Cnt == 0)
{
U2_rSTR.rOver = TRUE;
}
}
}
/*********************************************************
*** 函数名称:CleanBufer
*** 功能描述:清缓存
*** 参数: *ptr 缓存指针 ,size清除大小
*** 返回值:无
*** 创建者:
*** 最后更新:
*** 说明:
**********************************************************/
void CleanBufer(uint8 *ptr,uint16 size)
{
uint8 i = 0;
for(i=0; i<size; i++)
{
ptr[i] = 0;
}
}
/*********************************END FILE********************************************/
#ifndef __UART_H_
#define __UART_H_
#define u8 unsigned char
#define UART_RBUF_LEN 50
#define USART1_RX_PROCESS_OK U1_rSTR.rCnt = 0;\
U1_rSTR.rOver = FALSE;
#include "config.h" //通用配置头文件
typedef struct
{
uint8 RxBusy_Flag;
uint8 sBusy_Flag; //串口发送忙碌标志
uint8 rBuf[UART_RBUF_LEN]; //串口接收buff
uint16 rCnt; //串口接收长度
uint8 rOver; //接收完成标志
}
Usart_Read_STR;
extern idata Usart_Read_STR U1_rSTR;
extern void Uart1_Init(uint32 Baud);
extern void UART1_Tx_Puts(void);
extern void UART1_Send_byte(uint8 dat);
extern void Uart1_Send_Str(uint8 *string);
extern void Uart1_Send_xStr(uint8 *string,uint16 x);
extern void Check_U1_rOver(void);
#endif
/**********************************************************
不建议更改此文档,相关函数功能请查看相关头文件定义
**********************************************************/
#include "Timer.h"
uint T0_n =0; //定时器0计数
void PIT_init_ms(int n,int time)
{
if(n==0)
{
AUXR &= 0x7f; // T0, 12T 模式
TMOD |= 0x00; //定时器0工作方式0
TH0 = (65535-(int)(time*(Main_Fosc_KHZ/12)))/256;
TL0 = (65535-(int)(time*(Main_Fosc_KHZ/12)))%256;
ET0 = 1;
TR0 = 1;
}
if(n==1)
{
AUXR &= 0xbf; // T1, 12T 模式
TMOD |= 0x00; //定时器1工作方式0
TH1 = (65535-(int)(time*(Main_Fosc_KHZ/12)))/256;
TL1 = (65535-(int)(time*(Main_Fosc_KHZ/12)))%256;
ET1 = 1;
TR1 = 1;
}
if(n==2)
{
AUXR &= 0xfb; // T2, 12T 模式
T2H = (65535-(int)(time*(Main_Fosc_KHZ/12)))/256;
T2L = (65535-(int)(time*(Main_Fosc_KHZ/12)))%256;
IE2 |= ET2; //使能定时器中断
AUXR |= 0x10; //启动定时器2
}
if(n==3)
{
T4T3M &= 0xf8; // T3, 12T 模式
T3H = (65535-(int)(time*(Main_Fosc_KHZ/12)))/256;
T3L = (65535-(int)(time*(Main_Fosc_KHZ/12)))%256;
IE2 |= ET3; //使能定时器3中断
T4T3M |= 0x08; //启动定时器3
}
if(n==4)
{
T4T3M &= 0x8f; // T4, 12T 模式
T4H = (65535-(int)(time*(Main_Fosc_KHZ/12)))/256;
T4L = (65535-(int)(time*(Main_Fosc_KHZ/12)))%256;
IE2 |= ET4; //使能定时器4中断
T4T3M |= 0x80; //启动定时器4
}
EA=1; //允许所有中断
}
void PIT_init_us(int n,int time)
{
if(n==0)
{
AUXR |= 0x80; // T0, 1T 模式
TMOD |= 0x00; //定时器0工作方式1
TH0 = (65535-(int)(time*(Main_Fosc_KHZ/1000)))/256;
TL0 = (65535-(int)(time*(Main_Fosc_KHZ/1000)))%256;
ET0 = 1;
TR0 = 1;
}
if(n==1)
{
AUXR |= 0x40; // T1, 1T 模式
TMOD |= 0x00; //定时器1工作方式1
TH1 = (65535-(int)(time*(Main_Fosc_KHZ/1000)))/256;
TL1 = (65535-(int)(time*(Main_Fosc_KHZ/1000)))%256;
ET1 = 1;
TR1 = 1;
}
if(n==2)
{
AUXR |= 0x04; // T2, 1T 模式
T2H = (65535-(int)(time*(Main_Fosc_KHZ/1000)))/256;
T2L = (65535-(int)(time*(Main_Fosc_KHZ/1000)))%256;
IE2 |= ET2; //使能定时器中断
AUXR |= 0x10; //启动定时器2
}
if(n==3)
{
T4T3M &= 0xf8; // T3, 1T 模式
T4T3M |= 0x02; // T3, 1T 模式
T3H = (65535-(int)(time*(Main_Fosc_KHZ/1000)))/256;
T3L = (65535-(int)(time*(Main_Fosc_KHZ/1000)))%256;
IE2 |= ET3; //使能定时器3中断
T4T3M |= 0x08; //启动定时器3
}
if(n==4)
{
T4T3M &= 0x8f; // T4, 1T 模式
T4T3M |= 0x20; // T4, 1T 模式
T4H = (65535-(int)(time*(Main_Fosc_KHZ/1000)))/256;
T4L = (65535-(int)(time*(Main_Fosc_KHZ/1000)))%256;
IE2 |= ET4; //使能定时器4中断
T4T3M |= 0x80; //启动定时器4
}
EA=1; //允许所有中断
}
void TM0_isr(void)
{
if(T0_n<50000) T0_n++; //生成循环自加变量 0-50000
else T0_n=0;
if(T0_n%DELAY_1S == 0) //1s一次
{
}
Check_U1_rOver();//串口1计时接收完成
}
void TM0_I() interrupt 1 using 3 //--定时器0中断--//
{
TM0_isr();
}
#ifndef _TIMER_H_
#define _TIMER_H_
#include "config.h"
#define DELAY_20MS 10
#define DELAY_50MS 25
#define DELAY_100MS 50
#define DELAY_500MS 250
#define DELAY_200MS 100
#define DELAY_1500MS 750
#define DELAY_1S 500
#define DELAY_3S 1500
#define DELAY_30S 15000
void SysTimer_Init(void);
bool_t Timer_RefTime(u16 *timepoint,u16 timelength);
u16 Get_RefCount(void);
extern void Timer0Init(void);
extern void PIT_init_ms(int n,int time); //PIT模块ms初始化函数,默认使用定时器工作方式1,12T工作方式
extern u16 boot_cnt;
extern u16 systimer_cnt;
/*
取值:n:要使用的定时器模块 例:0 为 定时器0
1 为 定时器1
2 为 定时器2
3 为 定时器3
4 为 定时器4
取值:time:要定时中断的时长 取值范围: 1-32ms(24MHZ)
*/
extern void PIT_init_us(int n,int time); //PIT模块us初始化函数,默认使用定时器工作方式1,1T工作方式
/*
取值:n:要使用的定时器模块 例:0 为 定时器0
1 为 定时器1
2 为 定时器2
3 为 定时器3
4 为 定时器4
取值:time:要定时中断的时长 取值范围: 1-2730us(24MHZ)
*/
#endif
#include "config.h" //通用配置头文件
/*********************************************************
*** 函数名称:Usart1App_DownloadProgram
*** 功能描述:热启动下载程序
*** 参数:
*** 返回值:无
*** 创建者:
*** 最后更新:
*** 说明:
**********************************************************/
void Usart1App_DownloadProgram(void)
{
unsigned char i =0 ,sta =0;
for(i =0;i<10;i++){
if(U1_rSTR.rBuf[0] != U1_rSTR.rBuf[i]){
return 0;
}
}
IAP_CONTR = 0x60;
return 1;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
STC8A8K64D4 内部晶振24MHz 复位脚不做IO
*******************************************************************************/
void main(void)
{
Uart1_Init(9600);
PIT_init_ms(0,2); //初始化定时器0,2ms计时
while(1)
{
if(U1_rSTR.rOver==TRUE)//串口1有数据接收
{
Usart1App_DownloadProgram();
memset(userApp.RxBufer,0,U1_rSTR.rCnt);
CleanBufer(U1_rSTR.rBuf,U1_rSTR.rCnt);
USART1_RX_PROCESS_OK;
}
}
}