求助:mega16 按键复位不是很好,上电也不复位,什么原因

求助:mega16 按键复位不是很好,上电也不复位,什么原因,第1张

///////////////////////////////////////////////////////////伏做谨//

// 文件:KEY_Interrupt.C //

// 环境:编译为ICC AVR6.31A,仿真为AVR Studio4.12sp4 //

// 硬件:ATMEGA16芯片 //

// 日期:2007年5月28日//

// 功能:定时扫描数码管,INT0、INT1按键,下降沿出发中断,使//

//键值分别加、减1。//

// 备注: //

///////////////胡行//////////////////////////////////////////////

#include <iom16v.h>//包含单片机型号头文件

#include <macros.h>//包含"位" *** 作头文件

#include <delay.h>//包含延时头文件

#include <AVR_XQV12.h>//包含通用函数及宏定义头文件

/*******************************************************/

/****** 函数名称: Int0_isr()******/

/****** 功能: INT0中断函数,使键值加1 ******/

/****** 参数: 无******/

/****** 返回值 : 无******/

/*******************************************************/

#pragma interrupt_handler Int0_isr:2

void Int0_isr(void)

{

delay_nms(20)//延时大约20毫秒,去抖

if(KEY0==0) //再次判断按键是否按下

{

while(KEY0==0)//等待按键释放

Key_Number++//键值加1

}

}

/*******************************************************/

/****** 函数名称: Int1_isr()******/

/****** 功能: INT1中断函数,使键值减1 ******/

/****** 参数: 无******/

/****** 返回值 : 无******/

/*******************************************************/

#pragma interrupt_handler Int1_isr:3

void Int1_isr(void)

{

delay_nms(20)//延时大约20毫秒,去抖

if(KEY1==0) //再次判断按键是否按下

{

while(KEY1==0)//等待按键释放

Key_Number--//键值减1

}

}

/*******************************************************/

/****** 函数名称: Timer0_ovf_isr() ******/

/****** 功能: Timer0溢出中缺基断,数码管扫描******/

/****** 参数: 无******/

/****** 返回值 : 无******/

/*******************************************************/

#pragma interrupt_handler Timer0_ovf_isr:10

void Timer0_ovf_isr(void)

{

Display_One_SMG(1,Key_Number/10)//在第二位数码管显示十位

Display_One_SMG(0,Key_Number%10)//在第一位数码管显示个位

}

/*******************************************************/

/****** 函数名称: Timer0_Init() ******/

/****** 功能: Timer0初始化程序 ******/

/****** 参数: 无******/

/****** 返回值 : 无******/

/*******************************************************/

void Timer0_Init(void)

{

TCCR0 = 0x00//停止Timer0工作

TCNT0 = 0x00//清TCNT0

TCCR0|=(1<<CS02)//启动Timer0,系统时钟256分频

}

/*******************************************************/

/****** 函数名称: main()******/

/****** 功能: 定时扫描数码管,INT0、INT1按键 ******/

/****** 下降沿出发中断,使键值分别加、******/

/****** 减1。 ******/

/****** 参数: 无******/

/****** 返回值 : 无******/

/*******************************************************/

void main(void)

{

CLI() //关闭中断

CPU_Init() //初始化CPU

Timer0_Init()//初始化定时器0

MCUCR|=(1<<ISC11)|(1<<ISC01)//设置INT0、INT1下降沿触发中断

GICR|=(1<<INT1)|(1<<INT0)//使能INT0、INT1中断

TIMSK|=(1<<TOIE0)//使能Timer0溢出中断

SEI()//打开中断

while(1)//动态暂停

}

2009-07-17,11:49:04 资料 邮件 回复 引用回复 编辑 删除

【1楼】 TAIYUAN

积分:9

派别:

等级:------

来自:

#pragma interrupt_handler Timer0_ovf_isr:10

void Timer0_ovf_isr(void)

{

Display_One_SMG(1,Key_Number/10)//在第二位数码管显示十位

Display_One_SMG(0,Key_Number%10)//在第一位数码管显示个位

}

是不是这个函数里没有对TCNT0重新初始化改成如下试试:

#pragma interrupt_handler Timer0_ovf_isr:10

void Timer0_ovf_isr(void)

{

TCNT0=0X00

Display_One_SMG(1,Key_Number/10)//在第二位数码管显示十位

Display_One_SMG(0,Key_Number%10)//在第一位数码管显示个位

}

刚刚橡凯贺好我前段时间编了一个。

就是时钟作为中断,中断一次计数一次,当计数到6,000,000时(即1s钟,如果没有外部分频的话)时,灯的寄存器取反。

主程序:检查计数,灯的寄存器取反

中断子程序:计数

前段时间我编的例子,只要把时钟改一下,因为我用的是40MHz时钟外部分频到125Khz的中断,然梁派后显示改成取反就行了,原来我的是控制字码管。希望对你有帮助哦 (*^__^*) 嘻嘻……

********************************************************

AVR汇编程序实例

使用INT0、INT1控制LED数码管显示

Mega16 4MHz

********************************************************

.include "m16def.inc"

.def temp = r23 临时变量

.def counter = r24 计数变量

.def flag=r25

中断向量区配置,FLASH空间$000~$028

.org $000

jmp RESET 复位处理

jmp EXT_INT0 IRQ0 中断向量

nop

reti Timer2 比较中断向量

nop

reti Timer2 溢出中断向量

nop

reti Timer1 捕孙局捉中断向量

nop

reti Timer1 比较A 中断向量

nop

reti Timer1 比较B 中断向量

nop

reti Timer1 溢出中断向量

nop

reti Timer0 溢出中断向量

nop

reti SPI 传输结束中断向量

nop

reti USART RX 结束中断向量

nop

reti UDR 空中断向量

nop

reti USART TX 结束中断向量

nop

reti ADC 转换结束中断向量

nop

reti EEPROM 就绪中断向量

nop

reti 模拟比较器中断向量

nop

reti 两线串行接口中断向量

nop

reti IRQ2 中断向量

nop

reti 定时器0 比较中断向量

nop

reti SPM 就绪中断向量

nop

.org $02A

RESET: 上电初始化程序

ldi r16, high(RAMEND)

out SPH, r16

ldi r16, low(RAMEND)

out SPL, r16 设置堆栈指针为RAM 的顶部

ldi r16, 156

ser temp

out ddra, temp 设置PORTA为输出,段码输出

out porta,temp 设置PORTA输出全1

设置中断方式

ldi temp, 0x0a

out mcucr, temp INT0、INT1下降沿触发

ldi temp, 0xc0

out gicr, temp 允许INT0、INT1中断

out gifr, temp 清除INT0、INT1中断标志位

clr counter

clr flag

sei 使能中断

state: ldi zl, low(led_7 * 2)

ldi zh, high(led_7 * 2) Z寄存器取得7段码组的首指针

clr counter

loop:

cpi flag,1

brbs 1,stop

cpi counter,0x10

brbs 1,state

lpm

inc counter

inc zl

out porta, r0

call delay

rjmp loop

stop: cpi flag,0

brbs 1,loop

rjmp stop

EXT_INT0: in temp, sreg

pus

单片机一定要ATmega16的,LCD是1602的,秒表程序是c语言编的,要是能带注释名称:液晶控制与显示程序 说明:本程序毕郑是埋缓通用的1602液晶手液颂AVR6.31A,仿真为


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12444860.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存