標(biāo)題:
STC15W404AS單片機(jī)定時(shí)器0 定時(shí)器2通訊 加AD轉(zhuǎn)換死機(jī)
[打印本頁]
作者:
czhaii
時(shí)間:
2021-3-19 08:11
標(biāo)題:
STC15W404AS單片機(jī)定時(shí)器0 定時(shí)器2通訊 加AD轉(zhuǎn)換死機(jī)
我用定時(shí)器0控制兩個(gè)電機(jī)PWM占空比調(diào)速,
P1.0 P1.1作AD轉(zhuǎn)換,
兩個(gè)按鍵刷新讀AD值,再通過定時(shí)器2做波特率發(fā)生器
串口發(fā)送數(shù)據(jù)到觸摸屏,每次按刷新AD值,發(fā)送數(shù)據(jù)就死機(jī)了。
前幾天以為定時(shí)器0,定時(shí)器2同時(shí)開啟的沖突,搞了幾天。
非常疲憊。
定時(shí)器0,定時(shí)器2,串口單獨(dú)使用從來沒有問題,
為啥一合成就出問題了呢?
ADvalue_x=ADC_P10()/10; //刷新AD值
// printf("n1.val=%d\xff\xff\xff",ADvalue_x); //把這條注釋可以循環(huán)
#include "reg52.h"
#include <intrins.h>
#include <string.h>
#include "stdio.h"
#include <stdlib.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define uint unsigned int
#define uchar unsigned char
sfr P1ASF=0x9D; //P1口第2功能控制寄存器
uint ADvalue_x,ADvalue_y; //存放AD轉(zhuǎn)換返回的結(jié)果
#define ADC_SPEEDLL 0x00 //540個(gè)時(shí)鐘
sbit INTPUT3=P1^4; //X軸速度刷新
sbit INTPUT4=P1^5; //Y軸速度刷新
sbit INTPUT1=P5^4; //X軸啟動(dòng)
sbit INTPUT2=P5^5; //Y軸啟動(dòng)
sbit OUT1=P3^2;
sbit OUT2=P3^3;
sbit P_WM1=P3^6; //
sbit P_WM2=P3^7; //
bit timeflag; /****/
uchar kcounter,kstatus; //按鍵計(jì)數(shù)標(biāo)志 按鍵狀態(tài)標(biāo)志
uint vala,valb,aa; /**/
#define FOSC 11059200L
#define T1MS (65536-FOSC/1000) //1T模式
#define BAUD 9600 //串口波特率
#define uint unsigned int
#define uchar unsigned char
uint vala,val,aa; /**/
bit MOTORX_RUN; //X軸啟動(dòng)標(biāo)志
bit MOTORY_RUN; //Y軸啟動(dòng)標(biāo)志
bit MotorX_LowFlag; //電機(jī)X軸低電平計(jì)數(shù)標(biāo)志
bit MotorY_LowFlag; //電機(jī)Y軸低電平計(jì)數(shù)標(biāo)志
uint MotorX_LowCounter; //電機(jī)X軸低電平計(jì)數(shù)器
uint MotorX_HighCounter; //電機(jī)X軸高電平計(jì)數(shù)器
uint MotorY_LowCounter; //電機(jī)X軸低電平計(jì)數(shù)器
uint MotorY_HighCounter; //電機(jī)X軸高電平計(jì)數(shù)器
/*---------------延時(shí)子程序----------------*/
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<2000;j++)
;
}
/*---------------延時(shí)子程序----------------*/
void delay (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<10;j++)
;
}
/*************關(guān)所有輸出*******************************/
void reset_io()
{
P_WM1=1;
P_WM2=1;
INTPUT1=1; //
INTPUT2=1; //
P1M0=0X00;
P1M1=0X00;
P2M0=0X00;
P2M1=0X00;
P3M0=0X00;
P3M1=0X00;
P5M0=0X00;
P5M1=0X00;
}
/****************按鍵計(jì)數(shù)器狀態(tài)寄存器歸零*************/
void RstKey()
{
kcounter=0; //按鍵計(jì)數(shù)器歸零
kstatus=0; //狀態(tài)寄存器歸零
}
/*****************按鍵低電平檢測(cè)函數(shù)*****************/
void LowVoltKey(void) //按鍵計(jì)數(shù)器狀態(tài)標(biāo)志加一
{
kcounter++;
kstatus++;
delay(5); //延時(shí)
}
/*****************按鍵高電平檢測(cè)函數(shù)*****************/
void HighVoltKey(void) //按鍵計(jì)數(shù)器加一 狀態(tài)標(biāo)志歸零
{
kcounter++; //按鍵計(jì)數(shù)器加一
kstatus=0; //按鍵狀態(tài)標(biāo)志歸零
delay(5); //延時(shí)
}
/*****************************************/
unsigned int ADC_P10() //
{
uint i;
uchar status=0; //AD轉(zhuǎn)換結(jié)束標(biāo)志
uint AD_Dat=0; //10位AD轉(zhuǎn)換值
ADC_CONTR|=0X80; //打開ADC轉(zhuǎn)換電源,第一次使用時(shí)要打開內(nèi)部電源
for(i=0;i<10000;i++) //等待電源穩(wěn)定1ms
P1ASF|=0X00; //0000 0000
ADC_CONTR=0XE0; //1110 0000 通道P1.0
for(i=0;i<1000;i++) //如果多通道測(cè)量,更換通道后延時(shí)200us
ADC_CONTR|=0X08; //啟動(dòng)AD轉(zhuǎn)換 0000 1000ADC_START
while(status==0) //等待AD轉(zhuǎn)換結(jié)束
{
status=ADC_CONTR&0X10; //判斷ADC_FLAG是否等于1,
}
ADC_CONTR&=0XE7; //將ADC_FLAG清零
AD_Dat=(ADC_RES<<2)|(ADC_RESL&0X03); //
return AD_Dat; //
}
/*****************************************/
unsigned int ADC_P11() //
{
uint i;
uchar status=0; //AD轉(zhuǎn)換結(jié)束標(biāo)志
uint AD_Dat=0; //10位AD轉(zhuǎn)換值
ADC_CONTR|=0X80; //打開ADC轉(zhuǎn)換電源,第一次使用時(shí)要打開內(nèi)部電源
for(i=0;i<10000;i++) //等待電源穩(wěn)定1ms
P1ASF|=0X02; //0000 0010
ADC_CONTR=0XE1; //1110 0001 BIT 7電源 6 5速度90個(gè)時(shí)鐘 001 P1.1
for(i=0;i<1000;i++) //如果多通道測(cè)量,更換通道后延時(shí)200us
ADC_CONTR|=0X08; //啟動(dòng)AD轉(zhuǎn)換
while(status==0) //等待AD轉(zhuǎn)換結(jié)束
{
status=ADC_CONTR&0X10; //判斷ADC_FLAG是否等于1,
}
ADC_CONTR&=0XE7; //將ADC_FLAG清零
AD_Dat=(ADC_RES<<2)|(ADC_RESL&0X03); //
return AD_Dat; //
}
/*********************************/
void tm0_isr() interrupt 1
{
val++;
if(val>10)
{
val=0;
OUT1=~OUT1;
}
//X軸電機(jī)高低電平切換
if(MOTORX_RUN==1) //X軸電機(jī)開啟標(biāo)志
{
P_WM1=0; //開X軸輸出
if(MotorX_LowFlag==1) //低電平計(jì)數(shù)標(biāo)志等于1
{
MotorX_LowCounter++;
if(MotorX_LowCounter>=ADvalue_x)//
{
MotorX_LowFlag=0; //低電平計(jì)數(shù)標(biāo)志等于0高電平開始計(jì)數(shù)
MotorX_HighCounter=102-ADvalue_x;//賦高電平占空比值
}
}
else
{
P_WM1=1; //關(guān)X軸輸出
MotorX_HighCounter++;
if(MotorX_HighCounter>=ADvalue_x)//
{
MotorX_LowFlag=1; //低電平計(jì)數(shù)標(biāo)志等于1低電平開始計(jì)數(shù)
MotorX_LowCounter=ADvalue_x; //低電平計(jì)數(shù)器
}
}
}
//Y軸電機(jī)高低電平切換
if(MOTORY_RUN==1) //X軸電機(jī)開啟標(biāo)志
{
P_WM2=0; //開Y軸輸出
if(MotorY_LowFlag==1) //低電平計(jì)數(shù)標(biāo)志等于1
{
MotorY_LowCounter++;
if(MotorY_LowCounter>=ADvalue_y)//
{
MotorY_LowFlag=0; //低電平計(jì)數(shù)標(biāo)志等于0高電平開始計(jì)數(shù)
MotorY_HighCounter=102-ADvalue_y;//賦高電平占空比值
}
}
else
{
P_WM2=1; //關(guān)Y軸輸出
MotorY_HighCounter++;
if(MotorY_HighCounter>=ADvalue_y)//
{
MotorY_LowFlag=1; //低電平計(jì)數(shù)標(biāo)志等于1低電平開始計(jì)數(shù)
MotorY_LowCounter=ADvalue_y; //
}
}
}
}
/*------------定時(shí)器2中斷---------------------*/
void t2int() interrupt 12 //中斷入口
{
vala++;
if(vala>100)
{
vala=0;
OUT2=~OUT2; //將測(cè)試口取反
}
}
/*------------初始化串口---------------------*/
void InitUart()
{
T2L=(65536-(FOSC/4/BAUD)); //設(shè)置波特率重裝值
T2H=(65536-(FOSC/4/BAUD))>>8;
AUXR=0x14; //T2為1T模式, 并啟動(dòng)定時(shí)器2
IE2=0x01; //使能串口2中斷
}
/*********************************/
void main()
{
reset_io();
AUXR |= 0x04; //定時(shí)器2為1T模式
vala=0;
valb=0;
aa=0;
InitUart(); //初始化串口
TMOD=0x00; //設(shè)置定時(shí)器為模式0(16位自動(dòng)重裝載)
TL0=T1MS; //初始化計(jì)時(shí)值
TH0=T1MS>>8;
TR0=1; //定時(shí)器0開始計(jì)時(shí)
ET0=1; //使能定時(shí)器0中斷
EA=1;
delay1(100);
while (1)
{
delay1(10);
/***************低電平X軸啟動(dòng)*************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT1) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT1) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
MOTORX_RUN=1; //X軸啟動(dòng)啟動(dòng)標(biāo)志
MotorX_LowCounter=ADvalue_x;
MotorX_LowFlag=1; //定時(shí)器啟動(dòng)先發(fā)低電平 標(biāo)志置1,內(nèi)部循環(huán)切換
}
/***************高電平X軸停止*************/
RstKey(); //按鍵復(fù)位
if(MOTORX_RUN==1)
{
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(~!INTPUT1) //按鍵高電平
{
LowVoltKey();
}
else if(!INTPUT1) //按鍵低電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
MOTORX_RUN=0; //X軸啟動(dòng)啟動(dòng)標(biāo)志
}
}
/***************Y軸啟動(dòng)************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT2) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT2) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
MOTORY_RUN=1;
MotorY_LowCounter=ADvalue_y; //
MotorY_LowFlag=1; //定時(shí)器啟動(dòng)先發(fā)低電平 標(biāo)志置1,內(nèi)部循環(huán)切換
}
/***************高電平Y(jié)軸停止*************/
RstKey();
if(MOTORY_RUN==1)
{ //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(~!INTPUT2) //按鍵高電平
{
LowVoltKey();
}
else if(!INTPUT2) //按鍵低電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
MOTORY_RUN=0; //Y軸啟動(dòng)啟動(dòng)標(biāo)志
}
}
/***************更新X軸電機(jī)速度***********************/
RstKey();
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT3) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT3) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
ADvalue_x=ADC_P10()/10; //
// printf("n1.val=%d\xff\xff\xff",ADvalue_x); //
}
/***************更新Y軸電機(jī)速度***********************/
RstKey();
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT4) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT4) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
ADvalue_y=ADC_P11()/10; //
// printf("n1.val=%d\xff\xff\xff",ADvalue_y); //
}
/**************************************/
}
}
作者:
人人學(xué)會(huì)單片機(jī)
時(shí)間:
2021-3-19 10:07
建議你使用框架式編程思路,注意,不是模塊化編程。意思差不多,本質(zhì)有差異
作者:
wulin
時(shí)間:
2021-3-19 11:40
可能死在AD轉(zhuǎn)換的while(status==0)這里了。P1ASF=0X00;是設(shè)置測(cè)內(nèi)部基準(zhǔn)電壓,使用P1.0 P1.1作模擬輸入應(yīng)該是P1ASF=0x03;。
作者:
czhaii
時(shí)間:
2021-3-20 01:59
/***測(cè)試定時(shí)器0,2AD程序 ***/
/****L244 CODE1896 2021 3 20**********/
#include <REG52.H>
#include <intrins.h>
#include <string.h>
#include "stdio.h"
#include <stdlib.h>
#define uint unsigned int
#define uchar unsigned char
typedef unsigned char BYTE;
typedef unsigned int WORD;
sbit OUT0=P3^2; //
sbit OUT1=P3^3; //
sbit OUT2=P3^6; //
sbit OUT3=P3^7; //
sbit INTPUT1=P1^4;
sbit INTPUT2=P1^5;
sbit INTPUT3=P5^4;
sbit INTPUT4=P5^5;
uint aa=0; /****RUN FLAG****/
uint a[10]; //定義數(shù)組a
uchar i; //串口接收計(jì)數(shù)器
uchar k; //信號(hào)輸入高電平計(jì)數(shù)器
sfr P1ASF=0x9D; //P1口第2功能控制寄存器
uint ADvalue_x,ADvalue_y; //存放AD轉(zhuǎn)換返回的結(jié)果
#define ADC_SPEEDLL 0x00 //540個(gè)時(shí)鐘
bit Receive_Flag;
uchar kcounter,kstatus; //按鍵計(jì)數(shù)標(biāo)志 按鍵狀態(tài)標(biāo)志
/*------------------------------------------*/
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<1000;j++);
}
/********************************************/
void resrt_io()
{
P1M0=0X00;
P1M1=0X00;
P3M0=0X00;
P3M1=0X00;
P5M0=0X00;
P5M1=0X00;
OUT0=1;
OUT1=1;
OUT2=1;
OUT3=1;
}
/*****************************************/
unsigned int ADC_P10() //
{
uint i;
uchar status=0; //AD轉(zhuǎn)換結(jié)束標(biāo)志
uint AD_Dat=0; //10位AD轉(zhuǎn)換值
ADC_CONTR|=0X80; //打開ADC轉(zhuǎn)換電源,第一次使用時(shí)要打開內(nèi)部電源
for(i=0;i<10000;i++) //等待電源穩(wěn)定1ms
P1ASF|=0X00; //0000 0000
ADC_CONTR=0XE0; //1110 0000 通道P1.0
for(i=0;i<1000;i++) //如果多通道測(cè)量,更換通道后延時(shí)200us
ADC_CONTR|=0X08; //啟動(dòng)AD轉(zhuǎn)換 0000 1000ADC_START
while(status==0) //等待AD轉(zhuǎn)換結(jié)束
{
status=ADC_CONTR&0X10; //判斷ADC_FLAG是否等于1,
}
ADC_CONTR&=0XE7; //將ADC_FLAG清零
AD_Dat=(ADC_RES<<2)|(ADC_RESL&0X03); //
return AD_Dat; //
}
/*****************************************/
unsigned int ADC_P11() //
{
uint i;
uchar status=0; //AD轉(zhuǎn)換結(jié)束標(biāo)志
uint AD_Dat=0; //10位AD轉(zhuǎn)換值
ADC_CONTR|=0X80; //打開ADC轉(zhuǎn)換電源,第一次使用時(shí)要打開內(nèi)部電源
for(i=0;i<10000;i++) //等待電源穩(wěn)定1ms
P1ASF|=0X01; //0000 0010
ADC_CONTR=0XE1; //1110 0001 BIT 7電源 6 5速度90個(gè)時(shí)鐘 001 P1.1
for(i=0;i<1000;i++) //如果多通道測(cè)量,更換通道后延時(shí)200us
ADC_CONTR|=0X08; //啟動(dòng)AD轉(zhuǎn)換
while(status==0) //等待AD轉(zhuǎn)換結(jié)束
{
status=ADC_CONTR&0X10; //判斷ADC_FLAG是否等于1,
}
ADC_CONTR&=0XE7; //將ADC_FLAG清零
AD_Dat=(ADC_RES<<2)|(ADC_RESL&0X03); //
return AD_Dat; //
}
/****************按鍵計(jì)數(shù)器狀態(tài)寄存器歸零*************/
void RstKey()
{
kcounter=0; //按鍵計(jì)數(shù)器歸零
kstatus=0; //狀態(tài)寄存器歸零
}
/*****************按鍵低電平檢測(cè)函數(shù)*****************/
void LowVoltKey(void) //按鍵計(jì)數(shù)器狀態(tài)標(biāo)志加一
{
kcounter++;
kstatus++;
delay(5); //延時(shí)
}
/*****************按鍵高電平檢測(cè)函數(shù)*****************/
void HighVoltKey(void) //按鍵計(jì)數(shù)器加一 狀態(tài)標(biāo)志歸零
{
kcounter++; //按鍵計(jì)數(shù)器加一
kstatus=0; //按鍵狀態(tài)標(biāo)志歸零
delay(5); //延時(shí)
}
/*------------初始化串口---------------------*/
void InitUart()
{
SCON=0X50; //8位數(shù)據(jù),可變波特率
AUXR|=0x01; //串口1選擇定時(shí)器2為波特率發(fā)生器
AUXR|=0X04; //定時(shí)器2時(shí)鐘為Fosc,即1T
T2L=0XE0; //設(shè)置定時(shí)器處置 110592》9600
T2H=0XFE; //設(shè)置定時(shí)器處置 110592》9600
AUXR|=0X10; //啟動(dòng)定時(shí)器2
TI=1;
ES=1; //
EA=1;
}
/**************串口中斷*************************/
void Uart() interrupt 4 using 1
{
if(RI)
{
if(SBUF==0XFA||SBUF==0XFF) //觸摸屏結(jié)束碼
{
Receive_Flag=1; //接收數(shù)據(jù)標(biāo)志置一
RI=0; //
i=0; //數(shù)組計(jì)數(shù)器歸零
}
else
{
a[i]=SBUF; //數(shù)組下標(biāo)位置的數(shù)據(jù)等于SBUF
RI=0; //
i++;
}
}
}
/**************定時(shí)中斷*************************/
void timer0() interrupt 1
{
TH0=0X53;
TL0=0X32;
aa++;
if(aa>=300)
{
OUT1=~OUT1;
aa=0;
}
}
/*************************************************/
void main( ) /*主程序開始*/
{
resrt_io();
AUXR=0X80; //STC系列的1T 設(shè)置
TMOD=0X01;
TH0=0X53;
TL0=0X32;
ET0=1;
TR0=1;
P_SW1=0x00; //RXD/P3.0, TXD/P3.1
Receive_Flag=0;
InitUart(); //初始化串口
printf("0XFF,0XFF,0XFF");
i=0; //數(shù)據(jù)接收計(jì)數(shù)器等于0
while(1) //INTPUT1
{
/***************AD1*************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT1) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT1) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
ADvalue_x=ADC_P10()/10; //
printf("n1.val=%d\xff\xff\xff",ADvalue_x); //
}
/***************AD2*************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT2) //按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT2) //按鍵高電平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{ /*循環(huán)檢測(cè) */
ADvalue_y=ADC_P11()/10; //
printf("n1.val=%d\xff\xff\xff",ADvalue_y); //
}
//***************電機(jī)A檢測(cè)*************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT3) //模退 按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT3) //模退 按鍵高電平
{
HighVoltKey(); //高電平檢測(cè)
}
}
if(kstatus>=3) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{
}
/***************電機(jī)B檢測(cè)*************/
RstKey(); //按鍵復(fù)位
for(;kcounter<5;) //按鍵循環(huán)5次
{
if(!INTPUT4) //模退 按鍵低電平
{
LowVoltKey();
}
else if(~!INTPUT4) //模退 按鍵高電平
{
HighVoltKey(); //高電平檢測(cè)
}
}
if(kstatus>=3) /*按鍵狀態(tài)標(biāo)志大于等于3為有效值*/
{
}
}
} //L244 CODE1896 2021 3 20
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1