我想测占空比需要测3次CCP的值第一次测上升沿第二次测下降沿第三次测上升沿然后计算除时间 现在的问题是第一次可以测下面就不好测了寄存器设置没问题 是啥情况
代码如下:
#include <p18f4520.h>
#define RS PORTAbits.RA2
#define RW PORTAbits.RA3
#define EN PORTAbits.RA5
char m=0;
unsigned char ccp1[2];
unsigned char ccp2[2];
unsigned char ccp3[2];
unsigned char BCD[5];//存放万,千,百,十,个位
int shuju1=0X00;
int shuju2=0X00;
int shuju3=0X00;
int shu1,shu2; //存放周期和
int shu; //占空比
int zhongjianzhi; //存放余数
void shuzhizhuanhuan();
void display();
void delay(unsigned char k);
void write_com(char com);
void write_data(char data);
void lcd_init();
void jisuan(void);/*中断服务函数声明*/
void PIC18F_Low_isr(void);
//#pragma code high_vector_section=0x8
/*高优先级中断响应时,会自动跳转到0x8处*/
/*利用预处理器指令#pragma code来指定后面的程序在ROM中的起始地址为0x08,*/
/*它是告诉连接器定位到特定的代码段,HIGH_INTERRUPT_VECTOR 是该特定代码段的段名*/
void high_vector (void)
{
_asm goto jisuan _endasm/*通过一条跳转指令(汇编指令),跳转到中断服务函数(中断服务程序)处*/
}
#pragma code
/*这条语句不是多余的,它是告诉连接器回到默认的代码段,*/
/*如果不加的话,连接器就会傻傻地把后面的代码紧跟着上面的代码一直放下去。*/
/*而18f4520.lkr文件里定义了向量区地址最多到0x29,所以如果没加此句通常会报错*/
/*---高优先级中断服务程序---*/
//#pragma interrupt jisuan
/*利用预处理器指令#pragma interrupt来声明后面的函数是低优先级中断服务函数(中断服务程序),*/
/*注意:关键字是interrupt,和低优先级中断时不同*/
/*一旦指定后面的函数是低优先级中断服务程序,系统在进入该函数时,会自动保护现场,退出前自动恢复现场,*/
/*同时中断服务程序执行完毕后,会自动返回断点,*/
/*中断服务函数前必须加该语句*/
void jisuan (void)
{
/*如果只有一个同级中断源被使能:*/
/*1、执行中断服务语句部分*/
/*2、清除中断标记*/
/*如果有多个同级中断源被使能:*/
/*1、用查询法确定是哪个中断源提出了中断请求*/
/*2、确定是哪个中断源提出了中断请求后,执行中断服务语句部分*/
/*3、最后清除该中断源中断标志*/
m++;
if(m>=1)
{
ccp1[0]=CCPR1L;
ccp1[1]=CCPR1H;
shuju1=(shuju1|ccp1[0])<<8;
shuju1=shuju1|ccp1[1];
CCP1CON=0x04; //CCP1捕捉模式,每个下降沿捕捉
PIR1bits.CCP1IF=0;//CCP1中断标志位,清零
}
if (m>=2)
{
ccp2[0]=CCPR1L;
ccp2[1]=CCPR1H;
shuju2=(shuju2|ccp2[0])<<8;
shuju2=shuju2|ccp2[1];
//m++;
CCP1CON=0x05; //CCP1捕捉模式,每个上升沿捕捉
PIR1bits.CCP1IF=0;//CCP1中断标志位,清零
}
if (m>=3)
{
ccp3[0]=CCPR1L;
ccp3[1]=CCPR1H;
shuju3=(shuju3|ccp3[0])<<8;
shuju3=shuju3|ccp3[1];
// m=1;
//CCP1CON=0x05; //CCP1捕捉模式,每个上升沿捕捉
PIR1bits.CCP1IF=0;//CCP1中断标志位,清零
TMR1H=0X00; //初始化TMR1定时器计数初值
TMR1L=0X00;
shu1=shuju3-shuju1;//一个周期时间
shu2=shuju3-shuju2;//高电平时间
shu=shu2/shu1; //占空比
}
}
void shuzhizhuanhuan()
{
BCD[0]=shu/10000; //二进制转换成8421BCD码
zhongjianzhi=shu%10000;
BCD[1]=zhongjianzhi/1000;
zhongjianzhi=zhongjianzhi%1000;
BCD[2]=zhongjianzhi/100;
zhongjianzhi=zhongjianzhi%100;
BCD[3]=zhongjianzhi/10;
zhongjianzhi=zhongjianzhi%10;
BCD[4]=zhongjianzhi/1;
BCD[0]=BCD[0]|0x48; //8421BCD码转换成ASCII码
BCD[1]=BCD[1]|0X48;
BCD[2]=BCD[2]|0X48;
BCD[3]=BCD[3]|0X48;
BCD[4]=BCD[4]|0X48;
}
void delay(unsigned char k)
{
unsigned int i,j;
for(j=k;j>0;j--)
{
for(i=100;i>0;i--);
}
}
void write_com(char com)
{
TRISA=0X00; //端口A为输出端口
TRISD=0x00; //端口D为输出端口
delay(1);
PORTD=com;
RW=0;
RS=0;
EN=0;
delay(1);
EN=1;
delay(1);
EN=0;
}
void write_data(char data)
{
TRISA=0X00; //端口A为输出端口
TRISD=0x00; //端口D为输出端口
delay(1);
PORTD=data;
RW=0;
RS=1;
EN=0;
delay(1);
EN=1;
delay(1);
EN=0;
}
void lcd_init()
{
ADCON1=0x0F;//IO端口配置位0xff全数字端口
write_com(0x38);
// delay(1);
write_com(0x38);
// delay(1);
write_com(0x38);
// delay(1);
write_com(0x08);
// delay(1);
write_com(0x01);
// delay(1);
write_com(0x06);
// delay(1);
write_com(0x0c);
// delay(1);
}
void display()
{
lcd_init();
write_com(0x85); //显示上排数据
write_data('P');
write_data('M');
write_data('W');
write_com(0xc5); //显示下排数据
write_data(BCD[0]);
write_data(BCD[1]);
write_data(BCD[2]);
write_data(BCD[3]);
write_data(BCD[4]);
write_data('%');
}
void main()
{
DDRCbits.RC2=1; //PORTC.3为输入
RCON=0x80; //使能中断优先级
CCP1CON=0x05; //CCP1捕捉模式,每个上升沿捕捉
PIR1bits.CCP1IF=0;//CCP1标志位清零
PIR1bits.TMR1IF=0;//TIMER1定时器标志位清零
IPR1bits.CCP1IP=1;//CCP1为高优先级中断
IPR1bits.TMR1IP=1;//TIMER1定时器位高优先级中断
T3CON=0X08; //TMR1配给CCP1
T1CON=0x81; //使能通过一次16 位操作对Timer1 寄存器进行读写
TMR1H=0X00; //初始化TMR1定时器计数初值
TMR1L=0X00;
PIE1bits.CCP1IE=1;//CCP1使能
PIE1bits.TMR1IE=0;//TIMER1使能
//INTCONbits.GIE=0;
//INTCONbits.PEIE=0;
INTCONbits.GIE=1;
INTCONbits.PEIE=1;
while(1)
{
if(m>=3)
{
shuzhizhuanhuan();
display();
m=0;
}
}
} |