📄 main.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
声明通知编译器。
/**/
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
}
//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();
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,"AD0 VOLTAGE:"); //在LCD的第一行显示"AD0 VOLTAGE:"
CharsWrite(0,2,"0.0V"); //在第二行显示“0.0V”
uart_init(); //串口初始化
delay_ms(1000);
/**/
while(1)
{
ClearLcd(); //清屏LCD
delay_us(80); //等待清屏操作完成
CharsWrite(0,1,"AD0 VOLTAGE:"); //在LCD的第一行显示"AD0 VOLTAGE:"
data_con(); //将ad转换值转换为电压值
CharsWrite(0,2,adc_show); //在LCD上显示转换电压值
delay_ms(300);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -