PIC实验报告中断定时PWMAD程序代码.docx
《PIC实验报告中断定时PWMAD程序代码.docx》由会员分享,可在线阅读,更多相关《PIC实验报告中断定时PWMAD程序代码.docx(16页珍藏版)》请在冰豆网上搜索。
PIC实验报告中断定时PWMAD程序代码
实验一:
定时器
1.实验目的:
利用定时器0,定时器1,定时2实现4盏流水灯
2.实验内容
a,程序框图
定时器0:
/**************************************************
计算公式:
(256-X)*K*T=25000us,定时器延时25ms,
预分频为K为64,利用软件编程实现1s脉冲输出,RB0作为输出
************************************************/
#include
__CONFIG(0x20F1);
__CONFIG(0x3F71);
#defineT0_25MS61
chara=0;
voidinterruptISR()
{
if(T0IF==1)
{
T0IF=0;
TMR0=T0_25MS;
a++;
if(a==20)//输出1s脉冲
{
PORTD=(PORTD<<1);
a=0;
if(PORTD==0x10)
PORTD=0x01;
}
}
}
voidtimer0init()
{
OPTION=0b10000110;//,预分频器给TMR0,TMR0预分频系数为1:
64
INTCON=0b10100000;//GIE,PEIE置1
}
voidmain()
{
timer0init();
TRISD=0;
PORTD=0x01;
while
(1);
}
定时器1:
/**************************************************
计算公式:
(65536-X)*K*T=500000us,定时器延时500ms,
预分频为8,利用软件编程实现1s脉冲输出,RB0作为输出
************************************************/
#include
__CONFIG(0x20F1);
__CONFIG(0x3F71);
#defineT1_500MS3036
voidinterruptISR()
{
if(TMR1IF==1)
{
TMR1IF=0;
TMR1H=T1_500MS>>8;
TMR1L=T1_500MS;
PORTD=(PORTD<<1);
if(PORTD==0x10)
PORTD=0x01;
}
}
voidtimer1init()
{
TMR1H=T1_500MS>>8;
TMR1L=T1_500MS;
TMR1IE=1;
INTCON=0b11000000;//GIE,PEIE置1
T1CON=0b00110001;;//TMR1预分频系数为1:
8
}
voidmain()
{
timer1init();
TRISD=0;
PORTD=0x01;
while
(1);
}
定时器2:
/**************************************************
计算公式:
(PR2+1)*K1*K2*T=50000us,定时器延时50ms,
预分频为K1为16,后分频器K2为15利用软件编程实现1s脉冲输出,RB0作为输出
************************************************/
#include
__CONFIG(0x20F1);
__CONFIG(0x3F71);
#defineLEDRB0
chara=0;
voidinterruptISR()
{
if(TMR2IF==1)
{
TMR2IF=0;
a++;
if(a==10)//1秒到了
{
PORTD=(PORTD<<1);
a=0;
if(PORTD==0x10)
PORTD=0x01;
}
}
}
voidtimer2init()
{
TMR2IE=1;
PR2=207;
INTCON=0b11000000;//GIE,PEIE置1
T2CON=0B001110111;//TMR2预分频系数为1:
16,后分频器为1:
15
}
voidmain()
{
timer2init();
TRISD=0;
PORTD=0x01;
while
(1);
}
实验二:
RB0中断
1.实验目的:
a.利用外部中断RB0实现流水灯左移
2.程序框图:
程序:
#include
__CONFIG(0x20F1);
__CONFIG(0x3f71);
voiddelaynms(unsignedintn);
voidinterruptISR(void);
voidmain()
{
OPTION=0b00000000;
ANS12=0;
WPUB0=1;
TRISB=0b00000001;
INTCON=0b10010000;
TRISD=0b00000000;
PORTD=0x01;
while
(1);
}
voidinterruptISR(void)
{
if(INTF==1)
{
delaynms(30);
INTF=0;
PORTD=(PORTD<<1);
if(PORTD==0x10)
PORTD=0x01;
}
}
voiddelaynms(unsignedintn)
{
unsignedintj;
chark;
for(j=0;jfor(k=246;k>0;k--)NOP();
}
实验三:
AD转换
1.实验目的:
利用PIC内部AD转换器,AN0通道口采集模拟数据,通过LCD1602显示结果
2.程序框图:
程序:
#include
__CONFIG(0x3F39);
__CONFIG(0x20F1);
#defineRSRD4
#defineRWRD5
#defineERD6
#defineuintunsignedint
charQW,BW,SW,GW;
//8段共阳LED显示代码,0位-7位分别控制a-h段
constcharLED_CODE[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,
0b10010010,0b10000010,0b11111000,0b10000000,0b10010000,0b01111111};
uintAD_SUB(chark);
voidinit1602();//1602初始化
voidwrite_com(charcom);//写指令
voidwrite_date(chardata);//写数据
voiddelaynms(unsignedintn);
voidspiinit();
voidSPI_WRITE(char);
voiddisplayled();
voiddisplay1602();
voidBCD(uintR1);
voidmain()
{
uinty;
TRISA=0b00000001;
ANSEL=0b11111111;//AN0~AN7为模拟输入,上电默认,可不设
TRISD=0;//D口设置为输出
PORTD=0;
spiinit();
init1602();
while
(1)
{
y=AD_SUB(0);//0表示第0个通道
BCD(y);
displayled();
display1602();
delaynms(500);//此不不能忽略
}
}
voidBCD(uintR1)
{
QW=0;BW=0;SW=0;GW=0;
while(R1>=1000)
{R1-=1000;QW++;}
while(R1>=100)
{R1-=100;BW++;}
while(R1>=10)
{R1-=10;SW++;}
GW=R1;
}
voiddisplayled()
{
SPI_WRITE(GW);//先发个位
SPI_WRITE(SW);//发十位
SPI_WRITE(BW);//发百位
SPI_WRITE(10);//发小数点
SPI_WRITE(QW);//发千位
}
voiddisplay1602()
{
write_com(0x80);
write_date(0x30+QW);
write_date(0x2e);//小数点
write_date(0x30+BW);
write_date(0x30+SW);
write_date(0x30+GW);
write_date(0x56);//"V"
}
voidSPI_WRITE(charb)
{
charBUF;
BUF=LED_CODE[b];
SSPBUF=BUF;//发出数据
while(BF==0);
BUF=SSPBUF;
}
voidspiinit()
{
TRISC=0b00010000;
SSPEN=1;
CKP=1;
SSPM3=0;
SSPM2=0;
SSPM1=0;
SSPM0=1;
SMP=1;
CKE=0;
}
uintAD_SUB(chark)
{
chari;
uinttemp;
floatx;
ADCON0=0b01000001;//TAD=8TOSC,
ADFM=1;//设置成右对齐
ADCON0|=(k<<4);
for(i=1;i<5;i++)NOP();//打开AD通道后延时20us左右
GODONE=1;//开始AD转换
while(GODONE==1);//等待转换完成
ADIF=0;
temp=ADRESH<<8;
temp|=ADRESL;
x=temp/1023.0*5.0;
temp=x*1000;
return(temp);
}
voidinit1602()
{
delaynms(20);//延时时间大于15ms
write_com(0x03);
delaynms(5);
write_com(0x03);
delaynms(5);
write_com(0x03);
delaynms(5);
write_com(0x02);//归HOME位,此不不可少
delaynms(5);
write_com(0x28);//工作方式设置,4位数据线,2行字符,5*7字体
write_com(0x0c);//显示开关设置,画面开,光标消失,禁止闪烁
write_com(0x06);//输入方式设置,AC为加一计数器
write_com(0x01);//清屏
write_com(0x80);//开始显示位置
delaynms
(2);
}
voidwrite_com(charcom)
{
RS=0;//写指令
RW=0;
PORTD&=0xf0;//低四位清0
E=1;//有效发送
PORTD|=((com>>4)&0x0f);//先发高四位
delaynms(5);
E=0;
PORTD&=0xf0;
E=1;
PORTD|=(com&0x0f);//再发低四位
delaynms(5);
E=0;
}
voidwrite_date(chardata)
{
RS=1;//写数据
RW=0;
PORTD&=0xf0;
E=1;
PORTD|=((data>>4)&0x0f);//先发高四位
delaynms(5);
E=0;
PORTD&=0xf0;
E=1;
PORTD|=(data&0x0f);//再发低四位
delaynms(5);
E=0;
RS=0;
}
voiddelaynms(unsignedintn)
{
unsignedintj;
chark;
for(j=0;jfor(k=246;k>0;k--)NOP();
}
实验四:
PWM
1.实验目的:
通过PIC单片机输出PWM不同占空比脉冲波形
2.程序流程:
程序:
#include
__CONFIG(0x3f3a);
chara;
voidCSH();
voidinterruptISR(void);
voiddelaynms(unsignedintn);
voidmain()
{
CSH();
while
(1)
{
if(a==0)
CSH();
}
}
voidCSH()
{
TRISC2=0;
TRISD=0;
PR2=249;
CCPR1L=0x32;
CCP1CON=0x0c;
T2CON=0x05;
OPTION=0b00000000;
ANS12=0;
WPUB0=1;
TRISB=0b00000001;
INTCON=0b10010000;
}
voidinterruptISR(void)
{
if(INTF==1)
{
delaynms(30);
if(RB0==0)
{
INTF=0;
a++;
switch(a)
{
case1:
CCPR1L=0x19;PR2=249;CCP1CON=0x0c;T2CON=0x05;break;//占空比0.1
case2:
CCPR1L=0x4b;PR2=249;CCP1CON=0x0c;T2CON=0x05;break;//占空比0.3
case3:
CCPR1L=0x96;PR2=249;CCP1CON=0x0c;T2CON=0x05;break;//占空比0.6
case4:
CCPR1L=0xe1;PR2=249;CCP1CON=0x0c;T2CON=0x05;break;//占空比0.9
case5:
a=0;break;
}
}
}
}
voiddelaynms(unsignedintn)
{
unsignedintj;
chark;
for(j=0;jfor(k=246;k>0;k--)NOP();
}