T3定时器工作2个时间后不启动问题?
本帖最后由 石晓伟 于 2023-7-3 22:29 编辑尊敬的STC单片机技术支持人员:
你好!
我们在使用STC8H3K32S2单片机,遇到T3定时器工作2个时间后不启动问题?
我的软件设置UART1使用T1定时器产生9600波特率进行发送数据,UART2使用T2定时器产生115200波特率接收/发送4G/wifi模组的数据(T0定时器设置300us时间,用于串口接收一帧数据监控),工作2小时发现T0\T3定时器无法工作,导致uart2不能接收数据和发送数据(uart2发送给4G模组数据是每5s上报一次数据);麻烦STC单片机工程师支持一下是什么原因?
#include "reg51.h"
#define FOSC 11059200L //System frequency 机器周期T=12/FOSC≈1us
#define BAUD 9600 //UART baudrate
#define BAUD2 115200 //UART baudrate
#define BRT(65536 - FOSC / BAUD / 4)
#define BRT2(65536 - FOSC / BAUD2 / 4)
#define buf_size20
#define true 1
#define false 0
typedef int bool;
sfr WDT_CONTR=0xC1;
sfr IP2H=0xB6;
sfr IP2 =0xB5;
sfr IPH =0xB7;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr T4T3M = 0xd1;
sfr T4L = 0xd3;
sfr T4H = 0xd2;
sfr T3L = 0xd5;
sfr T3H = 0xd4;
sfr AUXR = 0x8e;
sfr T2H = 0xd6;
sfr T2L = 0xd7;
sfr S2CON = 0x9a;
sfr S2BUF = 0x9b;
sfr IE2 = 0xaf;
sfr P_SW1 = 0xa2;
sfr AUXINTIF =0xef;
#define T3IF 0x02
sbit A0=P1^2; //
sbit A1=P1^6; //
sbit A2=P1^7; //
sbit red1=P3^5;
sbit green1=P3^4;
sbit green2=P3^3;
sbit green3=P3^2;
sbit DW_mode=P5^4;
char b,wptr;
bool falg1,fk_falg,SB_falg,uart2_falg;
char falg,dangwei;
uchar dangwei_old,in_dangwei,A_old,jiajian;
uint wg,c,SB_Count=0;
uchar buff={0xAA,0X00,0X00},wg0,TM3Count=0,TM0Count=0;
char buffer={0},buffer2={0};
char rssi_falg=0;
idata char state="state:01";//9
idata char mode=",mode:00,"; //8
idata char rssi="rssi:01\r"; //7
data char snd={0};
unsigned charxCal_crc(unsigned char*ptr, unsigned charlen);
void Uart2_chuli();
void Uart2Send(uchar dat);
void Timer3_Init(void);
void Timer4_Init(void);
void rssi_Rd(void);
void Uart2SendStr(char *p);
void char_pinjie(char *p1,char *p2,char *p3);
void uart1_Init()
{
SCON = 0x50;
TMOD&=0x0f;
TMOD|=0x00;
TL1 = BRT;
TH1 = BRT >> 8;
P_SW1 = 0x40; //RXD_2/P3.6, TXD_2/P3.7
TR1=1; //启动T1定时器
ES=1;
TI = 0;
RI = 0;
}
void uart2_Init()
{
S2CON = 0x10;
T2L = BRT2;
T2H = BRT2 >> 8;
S2CON &= ~0x02;
S2CON &= ~0x01;
}
void Timer0_Init(void) //10微秒@11.0592MHz
{
//定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x91; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TF0 = 0; //清除TF0标志
// ET0=1; //T1定时器中断允许
// TR0 = 1;
}
void UartSend(uchar dat)
{
SBUF = dat;
while (!TI);
TI = 0;
}
void dangwei_UartSend()
{
T4T3M&=~0x08; //定时器3停止计时;
UartSend(buff);
UartSend(buff);
UartSend(buff);
UartSend(xCal_crc(buff,3));
T4T3M|=0x08;
}
void Init()
{
AUXR = 0xD4;
Timer0_Init();
Timer3_Init();
uart1_Init();
uart2_Init();
IP|=0x02;
IPH|=0x10;
IP2|=0x01;
IP2H|=0x01;
IE2 = 0x21;
//Open master interrupt switch
WDT_CONTR=0x37; //设置看门狗
P1M0 = 0x00; //初始化时设置P1.1端口为准双向,其他端口IO口为推挽输出
P1M1 = 0x00;
P3M0 = 0x00; //初始化时设置P3端口IO口为推挽输出
P3M1 = 0x00;
P5M0 = 0x10; //初始化时设置P3端口IO口为推挽输出
P5M1 = 0x00;
red1=0; //关机指示
green1=0; //低档位指示
green2=0; //中档位指示
green3=0; //高档位指示
delay_ms(4000);
green1=1; //低档位指示
green2=1; //中档位指示
green3=1; //高档位指示
EA = 1;
dangwei=0;
falg=1;
A_old=0x00;
b=1;
falg1=true;
//定时器0开始计时
}
void guanji() //关机
{
red1=0;
green1=1;
green2=1;
green3=1;
if(falg1==true)
{
if(b==1){b=0;falg1=false;buff=0x00;buff=0x04;}//else {buff=0x00;b=0;falg1=false;}
dangwei_UartSend();
}
}
void didang() //低档
{
red1=1;
green1=0;
green2=1;
green3=1;
if(falg1==true)
{
if(b==1){b=0;falg1=false;buff=0x11;buff=0x02;}//else{ buff=0x00;b=0;falg1=false;}
dangwei_UartSend();
}
}
void zhongdang() //中档
{
red1=1;
green1=0;
green2=0;
green3=1;
if(falg1==true)
{
if(b==1){b=0;falg1=false;buff=0x12;buff=0x01;}//else {buff=0x00;b=0;falg1=false;}
dangwei_UartSend();
}
}
void gaodang() //高档
{
red1=1;
green1=0;
green2=0;
green3=0;
if(falg1==true)
{
if(b==1){b=0;falg1=false;buff=0x13;buff=0x01;}//else{ buff=0x00;b=0;falg1=false;}
dangwei_UartSend();
}
}
unsigned charxCal_crc(unsigned char*ptr, unsigned charlen)
{
unsigned charcrc;
unsigned chari;
crc = 0;
while(len--)
{
crc ^= *ptr++;
for(i = 0; i < 8; i++)
{
if(crc & 0x01)
{
crc = (crc >> 1) ^ 0x8C;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
void key_can()
{
if(A0==0)
{
if(A0==0)
{
in_dangwei=0x01;
if(falg==1){
dangwei_old=in_dangwei;
falg=0;
}
if(A_old==0x02){jiajian=0x01;}
if(A_old==0x03){jiajian=0x00;}
A_old=0x01;
}
}
if(A1==0)
{
// delay_ms(5);
if(A1==0)
{
in_dangwei=0x02;
if(falg==1){dangwei_old=in_dangwei;
falg=0;
}
if(A_old==0x03){jiajian=0x01;}
if(A_old==0x01){jiajian=0x00;}
A_old=0x02;
}
}
if(A2==0)
{
// delay_ms(5);
if(A2==0)
{
in_dangwei=0x03;
if(falg==1) //开机读取一次
{
dangwei_old=in_dangwei;
falg=0;
}
if(A_old==0x01){jiajian=0x01;}//上一次为中档位时,本次为加档
if(A_old==0x02){jiajian=0x00;}//上一次为低档位时,本次为减档
A_old=0x03;
}
}
if(dangwei_old==in_dangwei){dangwei_old=in_dangwei;} //读取档位,进行一次判断
else{
if(jiajian==0x01){dangwei=dangwei+1;} //为加档
if(jiajian==0x00){dangwei=dangwei-1;} //为减档
if(dangwei>3){dangwei=0;} //超档位清零
if(dangwei<0){dangwei=3;} //超档位清零
b=1;
falg1=true;
dangwei_old=in_dangwei;
}
}
void main()
{
Init(); //串口初始化
while(1)
{
if(DW_mode==0){Uart2_chuli();mode='1';}else{key_can();mode='0';}
switch(dangwei)
{
case 0:guanji();state='0'; break;
case 1:didang();state='1'; break;
case 2:zhongdang();state='2';break;
case 3:gaodang();state='3';break;
}
if(fk_falg==true)
{
fk_falg=false;
Uart2SendStr(state);
}else
if(rssi_falg==1){rssi_falg=0;Uart2SendStr("abcAT+CSQ\r\n");}
else if(SB_falg==1)
{
SB_falg=0;
char_pinjie(state,mode,rssi); //拼接字符串+上报净化器状态字符串
if((rssi!='0')&&(rssi!='0'))
{
rssi='0';
rssi='0';
}
}
WDT_CONTR=0x37;
}
}
void char_pinjie(char *p1,char *p2,char *p3)//字符串拼接
{
strcat(snd,p1);
strcat(snd,p2);
strcat(snd,p3);
Uart2SendStr(snd);
memset(snd,0,buf_size);
}
void timer0() interrupt 1 //计时中断1工作方式1函数。
{
TF0=0;
TM0Count++;
if(TM0Count>20)
{
TM0Count=0;
wptr=0;
TR0=0;
T4T3M|=0x08;
// IE2&=~0x20;
// IE2|=0x20;
if((buffer=='+')&&(buffer=='Q')){rssi=buffer;rssi=buffer;}
else{
uart2_falg=true;
strcpy(buffer2,buffer);
SB_Count=0;
rssi_falg=0;
SB_falg=0;
}
memset(buffer,0,buf_size);
}
}
void Uart2Isr() interrupt 8
{
if (S2CON & 0x01)
{
S2CON &= ~0x01;
buffer=S2BUF;
TM0Count=0;
T4T3M&=0xF7;
TR0=1;
ET0=1;
if(wptr>=buf_size)
{
wptr=0;
memset(buffer,0,buf_size);
}
}
}
void TM3_Isr() interrupt 19
{
AUXINTIF&=~0x02;
TM3Count++;
if(TM3Count>=100) //10ms*100次=1s,1s*60个=60s
{
TM3Count=0;
SB_Count++; //10ms*100次=1s,1s*60个=60s
if(SB_Count==5){rssi_falg=1;}
if(SB_Count>=10){SB_Count=0;SB_falg=1;} //测试端口
}
}
void Uart2Send(char dat)
{
S2BUF = dat;
while (!(S2CON & 0x02));
S2CON &= ~0x02;
}
void Uart2SendStr(char *p)
{
T4T3M&=~0x08; //定时器3停止计时
while (*p)
{
Uart2Send(*p++);
}
T4T3M |= 0x08; //定时器3开始计时
}
void Uart2_chuli()
{
if(uart2_falg==true)
{
uart2_falg=false;
if(strcmp(buffer2,"A5A6080052")==0){dangwei=0;fk_falg=true; b=1; }
if(strcmp(buffer2,"A5A601014C")==0){dangwei=1;fk_falg=true; b=1; } //"A5A501"
if(strcmp(buffer2,"A5A601024D")==0){dangwei=2;fk_falg=true; b=1; }
if(strcmp(buffer2,"A5A601034E")==0){dangwei=3;fk_falg=true; b=1; }
memset(buffer2,0,buf_size);
falg1=true;
}
}
void Timer3_Init(void) //10毫秒@11.0592MHz
{
T4T3M &= 0xFD; //定时器时钟12T模式
T3L = 0x00; //设置定时初始值
T3H = 0xDC; //设置定时初始值
T4T3M |= 0x08; //定时器3开始计时
}
最好上传简化后(删除所有无关代码)能够复现问题的例程包,这样才好进行分析。 {:4_167:}{:4_167:}{:4_167:}{:4_167:}
即无原理图也无代码,你是想让大家算卦么?
那我们就强行算一下,你代码写的有BUG……
🤭🤭🤭,我 hsrzq 发表于 2023-6-27 23:42
即无原理图也无代码,你是想让大家算卦么?
那我们就强行算一下,你 ...
代码我现在贴上去了,现在帮我算一算{:lol:} 石晓伟 发表于 2023-7-4 15:07
代码我现在贴上去了,现在帮我算一算
问题已经解决了,增加了串口1的标志清零中断函数
页:
[1]