⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main._c

📁 ATmega16休眠模式的应用:使用程序关闭没有使用的模块
💻 _C
字号:
#include <iom16v.h>
#include <macros.h>
#include "lcd.h"
#include "usart.h"
#include "delay.h"
#define vref   256
volatile unsigned int extint_count=0;
volatile unsigned char act_flag=0;
volatile unsigned int adc_result;
unsigned char adc_show[6];
/** /
volatile:数据类型声明,表明该变量在程序执行中可被隐含改变
编译器有时会将SRAM中的数据拷贝到通用寄存器中以提高程序的执行效率
(在通用寄存器中对数据的操作速度比操作SRAM中的数据要快),这样会带来
一个问题,如果该SRAM中的数据已经被隐含改变(比如中断),那么编译器仍然
读取寄存器中之前的SRAM拷贝值显然与其实际值不同,从而出现错误。
本例中extint_count的值在外部中断服务程序中被改变,通过volatile
声明通知编译器。
/**/
/** /
MCUCR &= 0X40;   //将休眠模式清0,即休眠模式1

MCUCR |= 0X10;  //将休眠模式为1,即休眠模式2
/**/
void port_init(void)
{
 PORTA = 0xFE;
 DDRA  = 0xFE;
 PORTB = 0xFF;
 DDRB  = 0xFF;
 PORTC = 0xFF; 
 DDRC  = 0xFF;
 DDRD  = 0xFB;  //PD2(INT0)引脚设置为输入
 PORTD = 0xFB;  //关闭内部上拉
}
/*      AD转换程序     */
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
   unsigned int temp=0;
   while(temp<6)
      temp++;                //短延时
   adc_result = ADC;         //读取AD转换值
	   
   //ADCSRA |= (1<<ADSC);      //再次启动转换 			 	 		 
} 
void data_con(void)
{
   unsigned int temp;
   unsigned char i;
   temp=(unsigned int)(((unsigned long)((unsigned long)adc_result*vref))/1024);
   for(i=0;i<3;i++)
   {
	  adc_show[3-i]=temp%10+0x30;  //转换电压值用来在LCD上显示
	  temp=temp/10;
   }
	adc_show[0]=adc_show[1];
	adc_show[1]='.';	
	adc_show[4]='V';	
	adc_show[5]=0;	              //数组结束标记
}

#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
   extint_count++;
   if (act_flag!=1)
   {
      act_flag = 1;
   }
}
void adc_init(void)
{
   ADMUX = (1<<REFS1)|
           (1<<REFS0)|    //选择内部2.56v作为参考电压
           0x00;          //使用ad转换0通道
		                  //ADLAR = 0,转换结果选择右对齐
   ADCSRA = //(1<<ADEN)|     //ADC使能
            //(1<<ADSC)|     //开始一次ad转换
		    (1<<ADIF)|     //写1,将ADIF位清0
		    (1<<ADIE)|     //允许ADC中断
		    0x06;          //时钟分频系数为64
}
void sleep_init(void)
{
   MCUCR |= 0X40;  //使能休眠
}
//call this routine to initialize all peripherals
void init_devices(void)
{
 CLI();         //关闭全局中断
 port_init();   //CPU端口初始化
 /** /
 MCUCR = 0x02;  //INT0引脚上的下降沿触发中断
 GICR  = 0x40;  //外部中断0请求使能
 /**/
 /**/
  MCUCR = 0x00;  //INT0引脚上的低电平触发中断
  GICR  = 0x40;  //外部中断0请求使能
 /**/
 /** /
  MCUCR = 0x01;  //INT0引脚上的上升沿和下降沿都触发中断
  GICR  = 0x40;  //外部中断0请求使能
 /**/
 /** /
  MCUCR = 0x03;  //INT0引脚上的上升沿触发中断
  GICR  = 0x40;  //外部中断0请求使能
 /**/
 adc_init();
 sleep_init();
 SEI(); //打开全局中断
 
}
void main(void)
{
   char temp_show[5];  //定义数组用作在液晶屏上进行显示
   unsigned char i;
   unsigned int temp;
   for(i=0;i<5;i++)
   {
      temp_show[i] = 0;
   }
   temp_show[4] = 0xff;  //显示结束标志
   /**/
   init_devices();
   LCDReady();
   LcdInit();          //LCD初始化
   CharsWrite(0,1,"SYSTEM INIT");  //在LCD的第一行显示"SYSTEM INIT"
   CharsWrite(0,2,"......");            //在第二行显示“......”
   uart_init();        //串口初始化
   delay_ms(1000);
   /**/
   while(1)
   {
      ClearLcd();     //清屏LCD
	  delay_us(80);   //等待清屏操作完成
	  CharsWrite(0,1,"SLEEP IN IDLE");
	  MCUCR &= 0X40;   ////将休眠模式位清0,即休眠模式1
	  asm("sleep");   //在线嵌入汇编,CPU进入idle休眠模式
	                  //等待外部中断唤醒
	  PORTA = 0X00;    //点亮PA口LED
	  CharsWrite(0,2,"NOW MCU WAKEUP");
	  delay_ms(5000);
	  PORTA = 0XFF;   //55秒钟后熄灭PA口LED   
	  
	                  //测试ADC噪声抑制模式
	                    
	  ClearLcd();     //清屏LCD
	  delay_us(80);   //等待清屏操作完成
	  ADCSRA |= (1<<ADEN);    //使能ADC
	  CharsWrite(0,1,"SLEEP IN ADC:");  //在LCD的第一行显示"SLEEP IN ADC"
	  MCUCR &= 0X40;   
	  MCUCR |= 0X10;  //将休眠模式位送1,即休眠模式2,ADC噪声抑制模式
	  asm("sleep");   //在线嵌入汇编,CPU进入ADC休眠模式
	                  //在此模式下,进入休眠会自动启动一次AD转换,转换完成中断将唤醒MCU
	  PORTA = 0X00;    //ADC转换完成唤醒MCU,点亮PA口LED
	  CharsWrite(0,2,"NOW MCU WAKEUP");
	  delay_ms(5000);
	  PORTA = 0XFF;   //5秒钟后显示AD转换结果 
	  data_con();                      //将ad转换值转换为电压值
	  ClearLcd();     //清屏LCD
	  delay_us(80);   //等待清屏操作完成
	  CharsWrite(0,1,"ADO VOLTAGE:"); 
	  CharsWrite(0,2,adc_show);        //在LCD上显示转换电压值
	  delay_ms(5000);
	  ADCSRA &=~ (1<<ADEN);    //禁止ADC,因为进入IDLE模式,如果ADC被使能,
	                           //也将开始一次AD转换
	  ClearLcd();     //清屏LCD
	  delay_us(80);   //等待清屏操作完成						   
	  CharsWrite(0,1,"POWERDOWN MODE"); 
	  MCUCR &= 0X40;   
	  MCUCR |= 0X20;  //将休眠模式位送1,即休眠模式2,ADC噪声抑制模式
	  asm("sleep");   //在线嵌入汇编,CPU进入掉电休眠模式
	                  //等待外部中断唤醒
	  PORTA = 0X00;    //点亮PA口LED
	  CharsWrite(0,2,"NOW MCU WAKEUP");
	  delay_ms(5000);
	  PORTA = 0XFF;   //1秒钟后熄灭PA口LED   
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -