tag 标签: 边学嵌入式

相关博文
  • 热度 23
    2012-8-13 21:30
    1744 次阅读|
    0 个评论
    2.非向量IRQ实例程序   作者:下家山(上海索漫培训教材 http://www.xiajiashan.com) #include "config.h" volatile uint8 FLAG=0; #define LED1 119 // P1/**************************************************************************** * 名 称:IRQ_Eint3() * 功 能:外部中断EINT3服务函数* 入口参数:无 * 出口参数:无 ****************************************************************************/ void __irq IRQ_Eint3(void) { FLAG=1; /* 等待外部中断信号恢复为高电平(若信号保持为低电平,中断标志会一直置位) */ while( (EXTINT(13))!=0 ); EXTINT = 13; // 清除EINT3中断标志,3 等价于0x08 VICVectAddr = 0; // 向量中断结束 } /**************************************************************************** 【By 下家山 Q群 75303301        上海松江文汇路928号258室    松江大学城 上海索漫科技  http://www.xiajiashan.com  专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训】 ****************************************************************************/ int main(void) { PINSEL1 = 38; // 设置管脚连接,P0.20设置为EINT3 IO1DIR = LED1; // EXTMODE = 0x00; // 设置EINT3中断为电平触发模式 /* 打开EINT3中断(使用非向量IRQ) */ VICIntSelect = 0x00000000; // 设置所有中断分配为IRQ中断 VICDefVectAddr = (int)IRQ_Eint3; // 设置中断服务程序地址 EXTINT = 13; // 清除EINT3中断标志 VICIntEnable = 117; // 使能EINT3中断,EINT3在Bit17上 while(1){// 等待定时器中断或定时器匹配    if(FLAG==1){        if( (IO1SETLED1) == 0 )           {             IO1SET = LED1;          }else{             IO1CLR = LED1;          }      FLAG=0;   } ] return(0); } 未完待续: IRQ中断实例分析(一):向量IRQ实例程序 IRQ中断实例分析(二):非向量IRQ实例程序 IRQ中断实例分析(三):向量非向量IRQ实例程序  
  • 热度 18
    2012-8-13 21:24
    2431 次阅读|
    1 个评论
    作者:下家山(上海索漫培训教材 http://www.xiajiashan.com)1. 向量IRQ实例程序 我们再来分析之前的定时器中断程序 #include "config.h" volatile uint8 FLAG=0; #define LED1 119 // P1.19引脚控LED1/**************************************************************************** * 名 称:IRQ_Time0() * 功 能:定时器中断服务程序****************************************************************************/ void __irq IRQ_Time0(void) { FLAG= 1; T0IR = 0x01; // 清除中断标志 VICVectAddr = 0x00; // 通知VIC中断处理结束 } /**************************************************************************** * 名 称:Time0Init() * 功 能:初始化定时器,定时时间为S,并使能中断。 * 入口参数:无 * 出口参数:无 ****************************************************************************/ void Time0Init(void) { T0PR = 99; // 设置定时器分频为分频,得Hz T0MCR = 0x03; // 匹配通道匹配中断并复位T0TC T0MR0 = 110592; // 比较值(1S定时值) T0TCR = 0x03; // 启动并复位T0TC T0TCR = 0x01; /* 设置定时器中断IRQ */ VICIntSelect = 0x00; // 所有中断通道设置为IRQ中断 VICVectCntl0 = 0x24; // 定时器中断通道分配最高优先级(向量控制器) VICVectAddr0 = (uint32)IRQ_Time0; // 设置中断服务程序地址向量 VICIntEnable = 0x00000010; // 使能定时器中断 } /**************************************************************************** 【By 下家山 Q群 75303301        上海松江文汇路928号258室    松江大学城 上海索漫科技  http://www.xiajiashan.com  专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训】 ****************************************************************************/ int main(void) { IO1DIR = LED1; // 设置I/O为输出 Time0Init(); // 初始化定时器及使能中断 while(1){// 等待定时器中断或定时器匹配    if(FLAG==1){        if( (IO1SETLED1) == 0 )           {             IO1SET = LED1;          }else{             IO1CLR = LED1;          }      FLAG=0;   } ] return(0); } 未完待续: IRQ中断实例分析(一):向量IRQ实例程序 IRQ中断实例分析(二):非向量IRQ实例程序 IRQ中断实例分析(三):向量非向量IRQ实例程序  
  • 热度 24
    2012-8-13 21:17
    2327 次阅读|
    0 个评论
    3. 向量非向量IRQ实例程序 /**************************************************************************** * 文件名:main.c * 功 能:有四个中断,UART0,UART1,I2C,SPI0,其中 * UART0,SPI0分配为向量IRQ * UART1,I2C分配为非向量IRQ * 说 明: ****************************************************************************/ #include "config.h" #define UART1_IRQ 1 7 #define I2C_IRQ 1 9 /**************************************************************************** * 功 能:中断服务程序。 ****************************************************************************/ void __irq IRQ_SPI0(void) { 代码略 } void __irq IRQ_UART0(void) { 代码略 } void __irq NoVector_ISR(void) { volatile uint32 tmp; tmp = VICIRQStatus; if( tmp UART1_IRQ) { UART1中断处理代码略 } if( tmp I2C_IRQ) { I2C中断处理代码略 } VICVectAddr = 0; // 向量中断结束 } /**************************************************************************** 【By 下家山 Q群 75303301        上海松江文汇路928号258室    松江大学城 上海索漫科技  http://www.xiajiashan.com  专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训】 ****************************************************************************/ int main(void) { PINSEL0 = 0x55555555; // 配置管脚功能 /*I2C,SPI0,UART0,UART1相关初始化代码部分略 */ /* 中断部分设置*/ VICIntSelect = 0x00000000; // 所有中断通道设置为IRQ中断 VICDefVectAddr = (uint32)NoVector_ISR; // 设置非向量中断服务程序地址向量 VICVectAddr0 = (uint32)IRQ_UART0; // 设置uart0中断服务程序地址向量 VICVectAddr1 = (uint32)IRQ_SPI0; // 设置spi0中断服务程序地址向量 VICVectCntl0 = 0x00000026; // 6号中断源使能为向量IRQ并设置为最高优先级 VICVectCntl1 = 0x0000002A; // 10号中断源使能为向量IRQ并设置为次高优先级 VICIntEnable = 0x000006C0; /* 使能UART0,UART1,I2C,SPI0=bit10,bit9,bit7和bit6=1*/ while(1) // 等待中断发生 { 代码略 } return(0); }  本文的一些截图来自philips lpc2136英文datasheet. 写于上海松江                    下家山   有什么问题可与我联系:1209050967 上海索漫提供 http://www.xiajiashan.com IRQ中断实例分析(一):向量IRQ实例程序 IRQ中断实例分析(二):非向量IRQ实例程序 IRQ中断实例分析(三):向量非向量IRQ实例程序  
  • 热度 26
    2012-8-10 13:39
    8109 次阅读|
    4 个评论
    作者:下家山 (请尊重原创,转载请注明:上海索漫科技培训教材http://www.xiajiashan.com ) 向量,即指有方向的量。这里所说的方向就是向量地址。 向量中断——由硬件提供中断服务程序入口地址; 非向量中断——由软件件提供中断服务程序入口地址。 上面提到的中断向量表: Reset中断向量地址是0x00000000,那么当复位中断发生时,程序自动跳到0x00000000开始的地址执行。这一过程由硬件实现。 当定时器中断发生时,程序自动跳到0x00000018开始的位置执行。因为该地址是IRQ地址,IRQ不同于Reset,Reset只有一个,但IRQ有很多个。所以,程序跳到0x00000018时还要进行分支选择,那么怎么选择呢? 最开始,0x00000018是从VICVectAddr寄存器中找到当前中断服务程序地址执行的,那么向量中断和非向量中断,该选哪个呢? ARM中断核(PrimeCell)规定所有“非向量中断”共用到“默认向量地址寄存器”中。 同时规定,“向量中断”地址保存在“向量地址寄存器0-15”中。 所以,当IRQ中断发生时,ARM中断核(PrimeCell)会到16个IRQ solt中查找,如果没有找到则装载“默认向量地址寄存器”中的地址到”向量地址寄存器”中。 其实,可以把非向量中断理解成优先级最低的向量中断,因为在ARM中断核(PrimeCell)从“向量地址寄存器”读取地址时,是先扫描(Scan)整个IRQ slot,如果没有找到则无条件的装载“默认向量地址寄存器”的值。这个值就是非向量IRQ中断服务程序入口地址。 【By 下家山 Q群 75303301        上海松江文汇路928号258室    松江大学城 上海索漫科技  http://www.xiajiashan.com  专注嵌入式(ARM7,Cortex-M0,Cortex-M3,ARM9,linux)培训】 可以这么理解,向量IRQ有16个地址,而非向量IRQ只有一个地址。 疑问:可以设置多个非向量IRQ吗,怎么设置,中断发生后怎么处理? 答案: 可以同时设置两个(两个以上)的非向量IRQ,但是这些非向量IRQ共用一个中断服务程序入口地址,但中断发生后,由软件通过IRQ状态寄存器判断当前发生的哪个IRQ中断。(IRQ状态寄存器不区分是向量IRQ还是非向量IRQ) 写于上海松江 作者:下家山(请尊重原创, 转载请注明)    http://www.xiajiashan.com ,有什么问题可与我联系: ximenpiaoxue4016@sina.com
  • 热度 33
    2012-4-4 12:41
    3333 次阅读|
    6 个评论
    上一篇:" 《学习ARM7从跑马灯和蜂鸣器开始(一)》 7.写代码实现跑马灯 下面是led实验工程代码main.c中的代码内容 #include "config.h" #include "delay.h" 上面两条语句用来包含config.h和delay.h两个头文件,因为下面要用到的uint32,IO0DIR等寄存器,还有delay()函数等内容都定义在这些头文件里面。 #define LED_1 10 #define LED_2 11 #define LED_3 12 上面四条语句用来定义四个led等所在引脚的位置,便于程序使用。 #define LED1_TO_3 (LED_1|LED_2|LED_3) 上面这条语句把四个LED灯所在引脚或运算后定义到一个常量LED1_TO_3中,也是为了方便程序编写。 /**************************************************************************** * 名称:initSystem() * 功能:初始化IO ****************************************************************************/ void initSystem(void) { PINSEL1 = PINSEL1 (~(0xff12)); //led1~3设置为GPIO IO0DIR=IO0DIR | LED1_TO_3; //led1~3设置为输出功能 IO0SET=IO0SET | LED1_TO_3; //led1~3同时输出高 } 上面的initSystem函数是为了初始化cpu的各个IO脚的状态,及设置四个LED灯所在IO脚的状态,并初始化它们。 /**************************************************************************** * 名称:Led_On(uint32 num) * 功能:点亮LED ****************************************************************************/ void Led_On(uint32 num) { IO0SET=IO0SET | LED1_TO_3; //所有的led灭 IO0CLR=IO0CLR | num; //点亮num } 上面的这个函数是为了点亮所给led号,其中参数num就是传进来的参数,代表哪个LED。 /**************************************************************************** * 名称:main() * 功能:初始化led,并实现3个led灯轮流闪烁的效果。 ****************************************************************************/ int main(void) { initSystem(); while(1) { Led_On(LED_1); delay(10); Led_On(LED_2); delay(10); Led_On(LED_3); delay(10); } return 0; } Ads的安装使用方法见附录一。 四、独立写第一个程序:蜂鸣器 如果,跑马灯完全搞懂了,蜂鸣器程序是可以独立完成的。