//13-12-09 11:12 唐湘衡
//同级优先级的掌握
/*熟悉中断功能,没有发生中断时第,板子上的额第一个数码管RA0亮,并循环显示0-9
//如当外部产生中断(高优先级)(RB0)按下时,数码管显示暂停,蜂鸣器响5秒,然后数码管循环闪
//如按下RB2(定义为高低优先级)时,蜂鸣器嗒响5下, 然后数码管循环闪*/
/*器件:MPLAB软件8.2以上,MCC18编译器,mcd—II仿真器,工程板一块,芯片PIC18F4520*/
//实验问题:当程序在板子上运行时,低优先级只能执行1次 !然后在按RB2就无反应了,但高优先级一直有效
#include<p18cxxx.h>
const char table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98}; //0-9共阳极设置
void PIC18F_High_isr(void); //中断服务程序
void PIC18F_Low_isr(void);
void Inio(); //端口初始化程序
void Buzze(); //蜂鸣器响函数
void Delay_Onesecond(); //一秒延时函数
void Need_Delay(unsigned x); //通过参数可获得秒的倍
void Delay(unsigned int x); //延时函数
void Buzze2(void); //高优先级闹铃
void Delay(unsigned int x)
{
unsigned int i;
i = x;
for (i=x; i>0; i--);
}
void Buzze2(void) //高优先级闹铃
{
int i = 5;
for (i=5; i>0; i--)
{
TRISC = 0;
PORTC = 0x04; //RC2=1 发声
Delay(100000); //100ms 微妙
PORTCbits.RC2= 0; //不发声
Delay(100000); //100000us 100ms 毫秒
}
}
void Delay_Onesecond() //一秒延时函数 数字1在此芯片中执行 +1 或-1 所需时间为0.2us(微妙)
{ //那1秒钟所需值为(1us等于5个数字) 5000 000
unsigned int i ;
for (i=10000000; i>0; i--);
}
void Need_Delay(unsigned x) //通过参数可获得秒的倍数
{
unsigned int i;
for (i=x; i>0; i--)
{
Delay_Onesecond(); //调用1秒函数
}
}
void Inio() //端口初始化程序
{
TRISA = 0X7e; //RA0允许为亮
TRISD = 0X00; //D端口全部设为输出
ADCON1 = 0X07; //设置A口为普通I/O口(模数转换寄存器)查表吧
TRISC = 0; //设置c端口为输出,蜂鸣器用 高电平有效
PORTA = 0X00;
PORTD = 0XFe; //开启第1数码管 低电平有效
}
//***********************************************
void Buzze() //蜂鸣器响函数
{
TRISC = 0;
PORTCbits.RC2=1; //发声
Need_Delay(5); //发声延时5秒
PORTCbits.RC2 = 0; //不发声
}
//**********************************************
#pragma code high_vector_section = 0x8//#pragma code指定后面的程序在rom的起始地址为0X8,终止于0x17
void high_vector()
{
_asm goto PIC18F_High_isr _endasm //通过此指令逃到中断服务程序
}
//**************************************************
#pragma code Low_vector_section = 0x18
void low_vector()
{
_asm goto PIC18F_Low_isr _endasm //通过此指令逃到中断服务程序
}
//****************************************************************
#pragma code //返回默认的代码段
#pragma interrupt PIC18F_High_isr //#pragma interrupt 关键字 跳转到高中断服务程序,下面一定是次程序
void PIC18F_High_isr() //高级中断服务程序 记得要清中断标志位
{
//同级优先级的判断-标志位进行判断
if(INTCONbits.INT0IF == 1)
{
Buzze(); //蜂鸣器响函数
INTCONbits.INT0IF = 0; //iINT0外部中断标志位 INTCON1寄存器 写成INTCON
}
if (INTCON3bits.INT2IF == 1)
{
Buzze2();
INTCON3bits.INT2IF = 0; //INT2外部中断标志清除 INTCON1寄存器 写成INTCON
}
}
#pragma interruptlow PIC18F_High_isr //跳转到低中断服务程序 记得要清楚中断标志位
void PIC18F_Low_isr()
{
// Buzze2(); //低优先级闹铃
//INTCON3bits.INT2IF = 0; //INTCON3寄存器
}
void main()
{
char num;
Inio(); //端口初始化程序
INTCONbits.GIE = 0; //关闭全局中断 INTCON1
//初始化程序
TRISB = 0x05; //RB0,RB2设为输入,当有按键按下时,将会自动执行
INTCON2bits.RBPU = 0; //S使能B端口的上拉电位
//PORTBbits.RB0
RCONbits.IPEN = 1; // 使能中断优先级 RCON
//高优先级设置 1
INTCON2bits.INTEDG0 = 0; //INTCON2 使能外部中断触发边缘中断(下降源)
INTCONbits.INT0IF = 0; //清外部中断标志优先位
INTCONbits.INT0IE = 1; //使能int0(供RB0使用)外部中断使能位
//INTCON3bits.INT0IP = 0; //外部中断优先级为高优先级 INT0IP不存在,默认的
//高优先级设置 2
INTCON2bits.INTEDG2 = 0; //INTCON2 使能外部中断触发边缘中断(下降源)
INTCON3bits.INT2IF = 0; //清外部中断标志优先位
INTCON3bits.INT2IP = 1; //外部中断优先级为高低优先级 INTCON3
INTCON3bits.INT2IE = 1; //使能部中断
INTCONbits.GIEL = 1; //所有外设中断允许低优先级使能
RCONbits.IPEN = 1; //使能中断优先级
INTCONbits.GIE = 1; //开启全局中断
//主程序
/*总结:中断模块中,记得三个寄存器:标志,使能,优先级,在程序中,先把他们关闭,然后才打开*/
while (1) //循环显示0-9
{
for (num=0; num<10; num++)
{
PORTD = table[num];
Delay_Onesecond(); //1秒延时
}
}
}