|
以下程序?yàn)槭褂肧TC12C5A60S2單片機(jī),采用ADC中斷掃描模式,并且初始化定時(shí)器P進(jìn)行WM輸出,用串口輸出溫度數(shù)值:
難點(diǎn):ADC中斷與PWM輸出靠定時(shí)器0發(fā)生并且串口通訊波特率靠定時(shí)器1發(fā)生,這幾個(gè)中斷在代碼編寫與調(diào)試過程中,發(fā)現(xiàn)這幾個(gè)程序獨(dú)立應(yīng)用的代碼直接移植過來,并不能正常使用,這幾個(gè)中斷的優(yōu)先級(jí)順序和初始化順序會(huì)產(chǎn)生相互干擾,因此經(jīng)過查找相關(guān)資料,最終解決了這個(gè)問題,下面為詳細(xì)代碼(注釋是手打上去的,不知道為啥從keil往這里粘貼會(huì)出現(xiàn)問題)
void PWM_init() //PWM初始化函數(shù),初始化占空比為0
{
CMOD=0x02; //0000 0010 空閑時(shí)不計(jì)數(shù),不產(chǎn)生中斷,時(shí)鐘源fosc/2,因此輸出占用率fosc/512
CL=0x00;
CH=0x00;
CCAPM0=0x42; //0100 001,8位PWM
CCAP0L=0x00;
CCAP0H=0x00; //PWM實(shí)現(xiàn)方法,因?yàn)槭?位,CL基礎(chǔ)計(jì)算器從0xFF遞減到0x00,溢出后將CCAPOH的值加載到CCAPOL,若CL遞減過程中,若大于CCAPOL,則輸出高電平,否則為低電平
CCAPM1=0x42;
CCAP1H=0x00;
CCAP1L=0x00;
CR = 1; //開啟PCA計(jì)數(shù)器
}
void PWM_set(uchar x,uchar y) //占空比設(shè)置函數(shù) 引腳為P1.3和P1.4
{
CCAP0H=x*2.55; /占空比公式D=(256-CCAPnH)/256(8位PWM模式)
CCAP0L=x*2.55; //乘2.55轉(zhuǎn)換為0--100%
CCAP1H=y*2.55;
CCAP1L=y*2.55;
}
void Timer0_Init(void)
{
TH0=(65536-TIME)/256; //開定時(shí)器0
TL0=(65536-TIME)%256;
EA=1; //開全局中斷
ET0=1; //允許定時(shí)器0中斷
TR0=1;
IE = 0xa0;
}
void timer0() interrupt 1 //interrupt 1: ¶¨ê±Æ÷0£¬interrupt3£o¶¨ê±Æ÷3
{
TH0=(65536-TIME)/256; //高八位,(需要表示Xms的定時(shí),計(jì)數(shù)器由65536-X數(shù)到65536,由于16位,只能分高低位)
TL0=(65536-TIME)%256; /低八位
num++;
if(num==500)
{
flagTime ++;
num = 0;
}
Init_ADC();
}
/*------------------------------------------------
串口初始化
------------------------------------------------*/
void Init_UART (void)
{
SCON = 0x50; //8位數(shù)據(jù),可變波特率
TMOD |= 0x20; //設(shè)定定時(shí)器1為16位自動(dòng)重裝方式
TL1 = 0xC0; //設(shè)定定時(shí)器高8位初值
TH1 = 0xFA; //設(shè)定定時(shí)器低8位初值
TR1 = 1; //啟動(dòng)定時(shí)器
EA = 1;
}
/*------------------------------------------------
發(fā)送一個(gè)字節(jié)
------------------------------------------------*/
void SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
/*------------------------------------------------
發(fā)送一個(gè)字符串
------------------------------------------------*/
void SendStr(unsigned char *s)
{
while(*s!='\0')// \0表示字符串結(jié)束標(biāo)志
/通過檢測(cè)是否是字符串末尾
{
SendByte(*s);
s++;
}
}
/*----------------------------
ADC interrupt service routine
----------------------------*/
void adc_isr() interrupt 5 using 1
{
//V_5REF=V_1REF*256/da_ref;
if(ADC_Chanul_Turn%2==0) //外部基準(zhǔn)電壓
{
temp1=ADC_RES; //獲取轉(zhuǎn)換結(jié)果
ADC_1Data=((double)temp1/256)*5; //取八位計(jì)算基準(zhǔn)電壓Data
adc1 = ADC_1Data;
}
if(ADC_Chanul_Turn%2==1)
{
temp0=ADC_RES; //獲取轉(zhuǎn)換結(jié)果
ADC_0Data=((double)temp0/256)*5; //取八位計(jì)算實(shí)際值Data
adc0 =ADC_0Data;
}
ADC_CONTR = ADC_POWER | ADC_SPEEDH | ADC_START | ADC_Chanul_Turn;
ADC_Chanul_Turn++;
if(ADC_Chanul_Turn==2)
ADC_Chanul_Turn=0;
}
/*----------------------------
Initial ADC sfr
----------------------------*/
void Init_ADC()
{
P1ASF = 0x03; //Set all P1 as analog input port
ADC_RES = 0; //Clear previous result
// ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
if(ADC_Chanul_Turn%2==0)//外部基準(zhǔn)電壓
{
ADC_CONTR=0xF0; //AD轉(zhuǎn)換控制器,1111,0000 P10口
_nop_();
_nop_();
_nop_();
_nop_();
ADC_CONTR=0xE8; //1110,1000 (清0flag,置位start)
}
if(ADC_Chanul_Turn%2==1)
{
ADC_CONTR=0xF1; // 1111,0001 P11口
_nop_();
_nop_();
_nop_();
_nop_();
ADC_CONTR=0xE9; //1110,1001
}
delay_1ms(20); //ADC power-on delay and Start A/D conversion
}
|
評(píng)分
-
查看全部評(píng)分
|