?? main.c
字號:
// Target : STC12C5A60S2
// Crystal: 11.0592Mhz
#include <reg52.h>
#include "fun.h"
//聲明
void init_devices(void);
void port_init(void)
{
//設(shè)置P3.2~P3.4為輸入,P3.5~P3.7為開漏輸出
P3M1 = 0xfc; //1111 1100
P3M0 = 0xe0; //1110 0000
//設(shè)置P2.0為開漏輸出
P2M1=0X01;
P2M0=0X01;
d_vote = 1; //關(guān)閉投票指示燈
//關(guān)閉d1 d2 d3 ,按鍵s1 s2 s3為高電平
P3 = 0xff;
//設(shè)置P1.4為推挽輸出,P1.0、P1.7為高阻輸入(AD轉(zhuǎn)換用)
P1M1 = 0x81; //1000 0001
P1M0 = 0x10; //0001 0000
m_power = 0; //打開無線模塊電源
}
//Watchdog initialize
//約568.8ms
void watchdog_init(void)
{
WDT_CONTR = 0x33;//啟動(dòng)定時(shí)器,11.0592MHz晶振下,溢出時(shí)間568.8ms
}
//外部中斷0
void INT0_interrupt() interrupt 0
{
//external interupt on INT0
//關(guān)外部中斷0、外部中斷1
IE &= 0xfa; //1111 1010
m_power = 0; //打開無線模塊電源
d_vote = 1; //關(guān)閉投票指示燈
P3 |= 0xe0; //關(guān)閉d1 d2 d3
d3 = 0; //點(diǎn)亮d3
msdelay(500);
WDR(); //喂狗
d2 = 0; //點(diǎn)亮d2
msdelay(500);
WDR();
d1 = 0; //點(diǎn)亮d1
msdelay(500);
WDR();
d_vote = 0; //點(diǎn)亮 d_vote
msdelay(500);
WDR();
init_devices();
m_power = 0; //打開無線模塊電源
d_vote = 1; //關(guān)閉投票指示燈
P3 |= 0xe0; //關(guān)閉d1 d2 d3
}
//外部中斷1
void INT1_interrupt() interrupt 2
{
//external interupt on INT1
//關(guān)外部中斷0、外部中斷1
IE &= 0xfa; //111 1010
m_power = 0; //打開無線模塊電源
//LED從下到上依次點(diǎn)亮
d_vote = 1; //關(guān)閉投票指示燈
P3 |= 0xe0; //關(guān)閉d1 d2 d3
d3 = 0; //點(diǎn)亮d3
msdelay(500);
WDR(); //喂狗
d2 = 0; //點(diǎn)亮d2
msdelay(500);
WDR();
d1 = 0; //點(diǎn)亮d1
msdelay(500);
WDR();
d_vote = 0; //點(diǎn)亮 d_vote
msdelay(500);
WDR();
init_devices();
m_power = 0; //打開無線模塊電源
d_vote = 1; //關(guān)閉投票指示燈
P3 |= 0xe0; //關(guān)閉d1 d2 d3
}
//TIMER0 initialize
// desired value: 16mSec
// actual value: 16mSec
void timer0_init()
{
AUXR &=0x7F; //T0x12 = 0,定時(shí)器0使用12分頻
TMOD |= 0X01;
TH0 = T0_16ms >> 8;
TL0 = T0_16ms,
ET0 = 1; //允許T0中斷
}
//定時(shí)器0中斷 ,16ms一次
void Timer0_interrupt() interrupt 1
{
//重裝初值
TH0 = T0_16ms >> 8; //TH0 = T0_16ms / 256 = 0xc6
TL0 = T0_16ms; //TL0 = T0_16ms % 256 = 0x66
cnt++;
if (cnt==me) //輪到自己發(fā)
{
if (addr!=0)//地址沒有問題,可以發(fā)送
{
TR0 = 0; //關(guān)定時(shí)器
REN = 0; //禁止接收數(shù)據(jù)
putchar(sent[0]);
putchar(sent[1]);
putchar(sent[2]);
REN = 1; //允許接收數(shù)據(jù)
}
else
{
TR0 = 0; //關(guān)定時(shí)器
REN = 1; //允許接收數(shù)據(jù)
}
}
}
//TIMER2 initialize
// desired value: 50mSec
// actual value: 50.000mSec (0.0%)
void timer1_init()
{
AUXR &=0xbF; //T1x12 = 0,定時(shí)器1使用12分頻
TMOD |= 0X10; //定時(shí)器1模式1,16bit
TH1 = T1_50ms >> 8;
TL1 = T1_50ms;
ET1 = 1; //允許T1中斷
}
//定時(shí)器1中斷 ,50ms一次
void Timer1_interrupt() interrupt 3
{
//重裝初值
TH1 = T1_50ms >> 8;
TL1 = T1_50ms;
time++; //按鍵計(jì)時(shí)
time_f++; //空閑計(jì)時(shí)
if (time==10) //按鍵之后500ms
{
//關(guān)按鍵燈
P3 |= 0xe0; //關(guān)d1 d2 d3
}
if (time==40)//按鍵之后2S
{
key1=0; //進(jìn)入工廠模式步驟清零
}
if (time_f==10) //500ms未接收到數(shù)據(jù)
{
recnum=0; //接收數(shù)據(jù)清零
}
if (time_f==1200) //1分鐘未接收到數(shù)據(jù) 沒有按鍵
{
sleep(); //休眠 power down
}
}
//UART0 initialize
// desired baud rate: 9600
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
//BRTR=1允許BRT BRTx12=1 S1BRS = 1使用BRT
AUXR |=0x15; //0001 0101
//方式1,8 N 1,允許接收
SCON = 0x50; //SM0 = 0,SM1=1,REN=1;
//11.0592MHz,9600
BRT = 256 - (fosc/32/9600); //BRT = 0xdc
ES = 1; //允許串口中斷
}
//串口中斷
void USART_interrupt() interrupt 4
{
//uart has received a character in SBUF
unsigned int i;
//如果是接收中斷
if (RI)
{
RI=0; //清接收中斷
time_f=0; //空閑時(shí)間計(jì)數(shù)器清零
disable(); //關(guān)閉定時(shí)器0、定時(shí)器1、ADC轉(zhuǎn)換
//防止緩沖區(qū)數(shù)組溢出錯(cuò)誤
if (recnum < 5)
{
rec[recnum]=SBUF;
recnum++; //接收計(jì)數(shù)指針+1
loop: //開始處理流程
if (recnum>2) //至少收了3個(gè)數(shù)據(jù)
{
if ((rec[0]&0x0c)==0x00 && ((rec[0]&0x80)==0x00)) //包頭正確 上位機(jī)下發(fā)的
{
//計(jì)算校驗(yàn)
checkXOR=rec[0] ^ rec[1];
if ((checkXOR==rec[2])) //校驗(yàn)正確
{
recieve(); //當(dāng)作協(xié)議處理
recnum=0; //接收清零
goto loop1; //跳走
}
else //校驗(yàn)不正確
{
//緩沖區(qū)整體前移
for (i=1;i<recnum;i++)
{
rec[i-1]=rec[i];
}
recnum--;
if (recnum<=0) //接收緩沖區(qū)沒有數(shù)據(jù)了
{
//計(jì)數(shù)器清零,開中斷返回
recnum=0;
goto loop1;
}
else //接收緩沖區(qū)還有數(shù)據(jù)
{
goto loop; //跳回去再檢查
}
}
}
else //不是包頭
{
//緩沖區(qū)整體前移
for (i=1;i<recnum;i++)
{
rec[i-1]=rec[i];
}
recnum--;
if (recnum<=0) //接收緩沖區(qū)沒有數(shù)據(jù)了
{
//計(jì)數(shù)器清零,開中斷返回
recnum=0;
goto loop1; //跳走
}
else //接收緩沖區(qū)還有數(shù)據(jù)
{
goto loop; //跳回去再檢查
}
}
}
else //<=2
{
//什么也不做,開中斷返回主程序,等待接收下一個(gè)數(shù)據(jù)
}
}
else //如果recnum >=5,緩沖區(qū)溢出
{
recnum = 0; //全部清空
// 開中斷返回主程序,等待接收下一個(gè)數(shù)據(jù)
}
loop1: //結(jié)束處理流程
enable(); //開中斷返回
}
//如果是發(fā)送中斷
if (TI)
{
TI = 0; //清除發(fā)送中斷
}
}
//ADC initialize
// Conversion time: 48uS
void adc_init(void)
{
P1ASF = 0x00; //P1.0用作AD轉(zhuǎn)換
//轉(zhuǎn)換結(jié)果清零
ADC_RES = 0;
ADC_RESL = 0;
//ADC_POWER=1,SPEED1=0,SPEED0=0,
//ADC_FLAG=0,ADC_START=0,CHS2/CHS1/CHS0=000
//11.0592MHz,540個(gè)時(shí)鐘周期轉(zhuǎn)換一次,速度約125KHz,時(shí)間約 48us
ADC_CONTR = 0X80;
//等待4周期
_nop_();
_nop_();
_nop_();
_nop_();
//ADRJ = 0,ADC_RES寄存器保存10位A/D轉(zhuǎn)換結(jié)果的高8位,ADC_RESL保存結(jié)果的低2位
AUXR1 &= 0xfb;
}
//AD轉(zhuǎn)換中斷
void ADC_interrupt() interrupt 5
{
ADC_CONTR &= 0Xef; //ADC_FLAG清零
//計(jì)算電壓值
ad_result10 = ADC_RES;
ad_result10 = ( ad_result10 << 2 ) | ADC_RESL;
f_adconverting = 0;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
char i=0;
//stop errant interrupts until set up
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
EA = 0; //disable all interrupts
port_init();
watchdog_init(); //設(shè)置且啟動(dòng)看門狗
timer0_init();
timer1_init();
uart0_init();
adc_init();
PCON &= 0xfd; //關(guān)閉power down模式,PD位置0
//all peripherals are now initialized
//按鍵清零
ty=0;
qq=0;
fd=0;
key0=0;
key1=0;
//時(shí)間、計(jì)數(shù)清零
time=0;
time_m=0;
time_f=0;
cnt=0;
//狀態(tài)清零
f_start=0;
f_sleep=0;
f_volt=0;
f_adconverting = 0;
readset();//讀取本機(jī)地址
me=addr;
WDR(); //喂狗
//剛上電,AD不準(zhǔn),多檢查一次
checkpower(); //檢查電源
WDR();
checkpower();
WDR();
if (vin<1.75) //如果需要充電
{
//燈全關(guān)
d_vote = 1;
P3 |= 0xe0;
for (i=0;i<5;i++)
{ //閃爍5次d_vote
d_vote=0; //亮d_vote
msdelay(500);
WDR();
d_vote=1; //滅d_vote
msdelay(500);
WDR(); //喂狗
}
}
}
void main(void)
{
int i;
init_devices();
//insert your functional code here...
EA = 1; //開總中斷
while(1)
{
//關(guān)INT0 INT1中斷
IE &= 0xfa; //111 1010
WDR();
if (recnum>5) //任意時(shí)刻接收計(jì)數(shù)器大于5,清零
{
recnum=0;
}
if (f_sleep==1) //休眠標(biāo)
{
msdelay(10);
f_start=0;
f_sleep=0;
sleep(); //休眠power down
}
if (f_volt==1) //低電提示
{
f_volt=0;
//燈全關(guān)
d_vote = 1;
P3 |= 0xe0;
for (i=0;i<5;i++)
{
//閃爍5次d_vote
d_vote=0; //亮d_vote
msdelay(500);
WDR();
d_vote=1; //滅d_vote
msdelay(500);
WDR(); //喂狗
}
}
//---------------------------------------------------
if (s1==0) //按鍵S1 P3.4 同意
{
ty++;
time_f=0;
msdelay(10);
if ((s1==0) && (ty==1))
{
offled(1); //點(diǎn)亮D1,關(guān)閉D2、D3
time=0;
if (f_start==1) //如果是投票狀態(tài)
{
key0=1;
}
key1++; //按鍵次數(shù)加1
if(key1>3)
{
key1=0; //按三次
}
}
}
else
{
ty=0;
}
//----------------------------------------------------
if ((s2==0)&(s1=1))//s2按下,s1未按,key0=3
{
qq++;
time_f=0;
msdelay(10);
if ((s2==0)&(s1=1) & (qq==1))
{
offled(2);//點(diǎn)亮D2,關(guān)閉D1、D3
time=0;
if (f_start==1) key0=3;
if ((key1>2)&(key1<5))
{
key1++; //同意按三次后棄權(quán)按過2次
}
else key1=0;
}
}
else
{
qq=0;
}
//--------------------------------------------------------
if (s3==0) //s3按下,key0=2
{
fd++;
time_f=0;
msdelay(10);
if ((s3==0) && (fd==1))
{
offled(3); //點(diǎn)亮D3,關(guān)閉D2、D1
if (f_start==1) key0=2;
time=0;
d3=1; //關(guān)d3
if ((key1>4)&(key1<8))
{
key1++; //之后反對按3下
}
else key1=0;
}
if(key1==8) //按第3下反對 一整套進(jìn)入工廠模式動(dòng)作做完
{
REN=1; //允許串口接收
key1=0;
//offled(1);
key0=12; //key0=12,編地址狀態(tài)
}
}
else
{
fd=0;
}
//-------------------------------------------------
if(key0==12) //工廠模式
{
//從下往上循環(huán)亮燈
//燈全關(guān)
d_vote = 1;
P3 |= 0xe0;
d3=0; //開d3
msdelay(500);
WDR();
d3=1; //關(guān)d3
d2=0;
msdelay(500);
WDR(); //喂狗
d2=1;
d1=0;
msdelay(500);
WDR();
d1=1;
d_vote=0;
msdelay(500);
WDR(); //喂狗
d_vote=1;
time_m++;
}
if ((key0==12) && (time_m>5)) //循環(huán)超過5次
{
key0=0;
time_m=0;
//燈全關(guān)
d_vote = 1;
P3 |= 0xe0;
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -