共2条
1/1 1 跳转至页
紧急求救!关于中断控制数码管显示的一段程序。谢谢!
问
/****************************************************************************
* File:中断控制数码管显示.C
* 功能:键盘控制数码管显示。当检测到有按键输入时,对数码管显示速度进行控制。
* 使用I/O口输入方式对按键进行扫描。当按下key1时数码管显示速度慢,
* 当按下key3时数码管显示速度快,当按下key2时数码管显示暂停。
* 同时,用Led1--Led4显示数码管对应的数值Led1(低位)----Led4(高位)。
* 说明:将跳线器JP8、JP9、JP11短接。
****************************************************************************/
#include "config.h"
#define SPI_CS 0x00000100 /* P0.8 */
#define SPI_DATA 0x00000040 /* P0.6 */
#define SPI_CLK 0x00000010 /* P0.4 */
#define SPI_IOCON 0x00003D50 /* SPI接口和LED1、LED2、LED3、LED4等的I/O设置字
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly 延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void DelayNS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
/****************************************************************************
* 名称:HC595_SendDat()
* 功能:向74HC595发送一字节数据
* 入口参数:dat 要发送的数据
* 出口参数:无
* 说明:发送数据时,高位先发送。
****************************************************************************/
void HC595_SendDat(uint8 dat)
{ uint8 i;
IOCLR = SPI_CS; // SPI_CS = 0
for(i=0; i<8; i++) // 发送8位数据
{ IOCLR = SPI_CLK; // SPI_CLK = 0
/* 设置SPI的DATA输出值 */
if( (dat&0x80)!=0 ) IOSET = SPI_DATA;
else IOCLR = SPI_DATA;
dat <<= 1;
IOSET = SPI_CLK; // SPI_CLK = 1
}
IOSET = SPI_CS; // SPI_CS = 1,输出显示数据
}
/****************************************************************************
* 名称:IRQ_Eint0()
* 功能:外部中断EINT0服务函数,数码管和Led显示速度变慢。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint2(void);
void __irq IRQ_Eint1(void);
void __irq IRQ_Eint0(void)
{ const uint8 DISP_TAB[16] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E };
uint8 i;
{ for(i=0; i<16; i++)
if ((EXTINT&0x04)!=0)
{ VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
}
else if ((EXTINT&0x02)!=0)
{ VICVectCntl1 = 0x2F;
VICVectAddr1 = (int)IRQ_Eint1;
}
else
{HC595_SendDat(DISP_TAB[i]); // 输出LED显示数据
IOSET = 0x00003C00;
IOCLR = i<<10; // 设置LED显示输出
DelayNS(10); // 延时
}
}
while( (EXTINT&0x01)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x01; // 清除EINT0中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:IRQ_Eint1()
* 功能:外部中断EINT1服务函数,数码管和Led显示速度加快。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint1(void)
{ const uint8 DISP_TAB[16] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E };
uint8 i;
{ for(i=0; i<16; i++)
if((EXTINT&0x04)!=0)
{ VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
}
else if((EXTINT&0x01)!=0)
{ VICVectCntl0 = 0x2E;
VICVectAddr0 = (int)IRQ_Eint0;
}
else
{ HC595_SendDat(DISP_TAB[i]); // 输出LED显示数据
IOSET = 0x00003C00;
IOCLR = i<<10; // 设置LED显示输出
DelayNS(150); // 延时
}
}
VICVectAddr = 0x00;
while( (EXTINT&0x02)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x02; // 清除EINT1中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:IRQ_Eint2()
* 功能:外部中断EINT2服务函数,暂停正在显示的数码管和Led。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint2(void)
{
/*************************************************************************
请问哪位能帮帮忙,按照我写的说明给补写这段程序,实现按键key2实现暂停,然后
再按它时实现返回。按照原来的显示继续循环。谢谢哈!
**************************************************************************/
VICVectAddr = 0x00;
while( (EXTINT&0x02)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x02; // 清除EINT1中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:main()
* 功能:按键控制LED数码管显示,并控制LED1、LED2、LED3、LED4显示。
****************************************************************************/
int main(void)
{
PINSEL0 = 0xA0000000; // 设置IO口工作模式,P0.14设置为EINT1
//P0.15设置为EINT2
PINSEL1 = 0x00000001; // P0.16设置为EINT0
IODIR = SPI_IOCON; // 设置SPI控制口为输出
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl0 = 0x2E; // EINT0通道分配到IRQ slot 0,即优先级最高
VICVectAddr0 = (int)IRQ_Eint0; // 设置EINT0向量地址
VICVectCntl1 = 0x2F;
VICVectAddr1 = (int)IRQ_Eint1;
VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
VICIntEnable = 0x0001C000; // 使能EINT0、EINT1中断
EXTINT = 0x07; // 清除外部中断标志
while(1); // 等待中断
return(0);
}
答 1: 问问题要说清楚撒...首先说你用的是哪款芯片撒...LPC2104...LPC2114...LPC213X?
其次....建议去看书,看那本黄色的<ARM嵌入式系统基础教程>,也是周工编写的,中断那节有介绍怎么开两个外部中断..
另:"实现按键key2实现暂停,然后再按它时实现返回。按照原来的显示继续循环"做法很多,我就讲一个最笨的..中断里开一个全局变量赋值带出,主程序里做一个IF语句扫描这个变量并配合一个一个WHILE的死循环........
OK? 答 2: 是LPC2104哈
* File:中断控制数码管显示.C
* 功能:键盘控制数码管显示。当检测到有按键输入时,对数码管显示速度进行控制。
* 使用I/O口输入方式对按键进行扫描。当按下key1时数码管显示速度慢,
* 当按下key3时数码管显示速度快,当按下key2时数码管显示暂停。
* 同时,用Led1--Led4显示数码管对应的数值Led1(低位)----Led4(高位)。
* 说明:将跳线器JP8、JP9、JP11短接。
****************************************************************************/
#include "config.h"
#define SPI_CS 0x00000100 /* P0.8 */
#define SPI_DATA 0x00000040 /* P0.6 */
#define SPI_CLK 0x00000010 /* P0.4 */
#define SPI_IOCON 0x00003D50 /* SPI接口和LED1、LED2、LED3、LED4等的I/O设置字
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly 延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void DelayNS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
/****************************************************************************
* 名称:HC595_SendDat()
* 功能:向74HC595发送一字节数据
* 入口参数:dat 要发送的数据
* 出口参数:无
* 说明:发送数据时,高位先发送。
****************************************************************************/
void HC595_SendDat(uint8 dat)
{ uint8 i;
IOCLR = SPI_CS; // SPI_CS = 0
for(i=0; i<8; i++) // 发送8位数据
{ IOCLR = SPI_CLK; // SPI_CLK = 0
/* 设置SPI的DATA输出值 */
if( (dat&0x80)!=0 ) IOSET = SPI_DATA;
else IOCLR = SPI_DATA;
dat <<= 1;
IOSET = SPI_CLK; // SPI_CLK = 1
}
IOSET = SPI_CS; // SPI_CS = 1,输出显示数据
}
/****************************************************************************
* 名称:IRQ_Eint0()
* 功能:外部中断EINT0服务函数,数码管和Led显示速度变慢。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint2(void);
void __irq IRQ_Eint1(void);
void __irq IRQ_Eint0(void)
{ const uint8 DISP_TAB[16] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E };
uint8 i;
{ for(i=0; i<16; i++)
if ((EXTINT&0x04)!=0)
{ VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
}
else if ((EXTINT&0x02)!=0)
{ VICVectCntl1 = 0x2F;
VICVectAddr1 = (int)IRQ_Eint1;
}
else
{HC595_SendDat(DISP_TAB[i]); // 输出LED显示数据
IOSET = 0x00003C00;
IOCLR = i<<10; // 设置LED显示输出
DelayNS(10); // 延时
}
}
while( (EXTINT&0x01)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x01; // 清除EINT0中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:IRQ_Eint1()
* 功能:外部中断EINT1服务函数,数码管和Led显示速度加快。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint1(void)
{ const uint8 DISP_TAB[16] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E };
uint8 i;
{ for(i=0; i<16; i++)
if((EXTINT&0x04)!=0)
{ VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
}
else if((EXTINT&0x01)!=0)
{ VICVectCntl0 = 0x2E;
VICVectAddr0 = (int)IRQ_Eint0;
}
else
{ HC595_SendDat(DISP_TAB[i]); // 输出LED显示数据
IOSET = 0x00003C00;
IOCLR = i<<10; // 设置LED显示输出
DelayNS(150); // 延时
}
}
VICVectAddr = 0x00;
while( (EXTINT&0x02)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x02; // 清除EINT1中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:IRQ_Eint2()
* 功能:外部中断EINT2服务函数,暂停正在显示的数码管和Led。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_Eint2(void)
{
/*************************************************************************
请问哪位能帮帮忙,按照我写的说明给补写这段程序,实现按键key2实现暂停,然后
再按它时实现返回。按照原来的显示继续循环。谢谢哈!
**************************************************************************/
VICVectAddr = 0x00;
while( (EXTINT&0x02)!=0 ) // 等待外部中断信号恢复为高电平
{ EXTINT = 0x02; // 清除EINT1中断标志
}
VICVectAddr = 0x00;
}
/****************************************************************************
* 名称:main()
* 功能:按键控制LED数码管显示,并控制LED1、LED2、LED3、LED4显示。
****************************************************************************/
int main(void)
{
PINSEL0 = 0xA0000000; // 设置IO口工作模式,P0.14设置为EINT1
//P0.15设置为EINT2
PINSEL1 = 0x00000001; // P0.16设置为EINT0
IODIR = SPI_IOCON; // 设置SPI控制口为输出
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl0 = 0x2E; // EINT0通道分配到IRQ slot 0,即优先级最高
VICVectAddr0 = (int)IRQ_Eint0; // 设置EINT0向量地址
VICVectCntl1 = 0x2F;
VICVectAddr1 = (int)IRQ_Eint1;
VICVectCntl2 = 0x30;
VICVectAddr2 = (int)IRQ_Eint2;
VICIntEnable = 0x0001C000; // 使能EINT0、EINT1中断
EXTINT = 0x07; // 清除外部中断标志
while(1); // 等待中断
return(0);
}
答 1: 问问题要说清楚撒...首先说你用的是哪款芯片撒...LPC2104...LPC2114...LPC213X?
其次....建议去看书,看那本黄色的<ARM嵌入式系统基础教程>,也是周工编写的,中断那节有介绍怎么开两个外部中断..
另:"实现按键key2实现暂停,然后再按它时实现返回。按照原来的显示继续循环"做法很多,我就讲一个最笨的..中断里开一个全局变量赋值带出,主程序里做一个IF语句扫描这个变量并配合一个一个WHILE的死循环........
OK? 答 2: 是LPC2104哈
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |