当前位置:文档之家› avr实验报告

avr实验报告

avr实验报告
avr实验报告

通达学院

2014 /2015 学年第一学期

课程设计实验报告

模块名称A VR单片机课程设计(proteus)专业通信工程

学生班级

学生学号

学生姓名

指导教师李虹戴海鸿杨洁王明伟

AVR单片机软件设计(proteus)报告

基本内容包括:

1)总体设计原理、思路;

根据题目的要求,我们需要事先得到3种波形的信号源,并将其在程序存储器中,然后取出程序存储器里的信号源存放在atmega128的外部RAM中,并通过DAC0832输出到示波器上显示图形。采用按键方式控制输出波形,并且通过DS18B20上的温度来控制信号的频率,温度在1~10时显示2Hz,温度为11~20时显示4Hz,温度为21~30时为8Hz,温度为31~40时为15Hz,温度大于40时为19Hz。最后在LM016L上显示出输出的波形名称和温度以及频率。

2)硬件方面原理图的设计:包括使用的元器件、典型芯片的介绍;原理图的说明等

1、ATmega128

ATmega128为基于AVR RISC结构的8位低功耗CMOS微处理器。由于其先进的指令集以及单周期指令执行时间,ATmega128 的数据吞吐率高达1 MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。

2、DS18B20

DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发

的温度报警触发器TH和TL、配置寄存器。光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的,也就是你要做的是配置寄存器。

根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

3、DAC0832

DAC0832是采样频率为八位的D/A转换芯片,集成电路内有两级输入寄存器,使DAC0832芯片具备双缓冲、单缓冲和直通三种输入方式,以便适于各种电路的需要(如要求多路D/A异步输入、同步转换等)。DAC0832是8分辨率的D/A 转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。DAC0832逻辑输入满足TTL电平,可直接与TTL电路或微机电路连接。

3)软件方面程序流程图的设计、关键代码的说明

关键代码:

#include

#include //包含_nop_()函数定义的头文件 #include "DS18B20.h" //DS18B20驱动程序软件包 #include "delay.h" //包含_nop_()函数定义的头文件

#define uchar unsigned char

#define uint unsigned int

#define key1 PINB&(1<

#define key2 PINB&(1<

#define key3 PINB&(1<

#define key4 PINB&(1<

#define key5 PINB&(1<

#define key6 PINB&(1<

#define key7 PINB&(1<

#define key8 PINB&(1<

uchar const table_sjb[256] = //三角波

{

0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,

0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,

0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,

0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,

0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,

0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,

0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,

0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,

0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,

0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,

0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,

0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,

0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,

0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,

0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0,

0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,

0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0,

0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8, 0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0,

0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,

0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0,

0xBF,0xBE,0xBD,0xBC,0xBB,0xBA,0xB9,0xB8,

0xB7,0xB6,0xB5,0xB4,0xB3,0xB2,0xB1,0xB0,

0xAF,0xAE,0xAD,0xAC,0xAB,0xAA,0xA9,0xA8, 0xA7,0xA6,0xA5,0xA4,0xA3,0xA2,0xA1,0xA0,

0x9F,0x9E,0x9D,0x9C,0x9B,0x9A,0x99,0x98,

0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90, 0x8F,0x8E,0x8D,0x8C,0x8B,0x8A,0x89,0x88,

0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80

};

uchar const table_zxb[256] = //正弦表{

0x80,0x83,0x86,0x89,0x8D,0x90,0x93,0x96,

0x99,0x9C,0x9F,0xA2,0xA5,0xA8,0xAB,0xAE, 0xB1,0xB4,0xB7,0xBA,0xBC,0xBF,0xC2,0xC5,

0xC7,0xCA,0xCC,0xCF,0xD1,0xD4,0xD6,0xD8,

0xDA,0xDD,0xDF,0xE1,0xE3,0xE5,0xE7,0xE9,

0xEA,0xEC,0xEE,0xEF,0xF1,0xF2,0xF4,0xF5,

0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,

0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,

0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,

0xF5,0xF4,0xF2,0xF1,0xEF,0xEE,0xEC,0xEA,

0xE9,0xE7,0xE5,0xE3,0xE1,0xDE,0xDD,0xDA,

0xD8,0xD6,0xD4,0xD1,0xCF,0xCC,0xCA,0xC7,

0xC5,0xC2,0xBF,0xBC,0xBA,0xB7,0xB4,0xB1,

0xAE,0xAB,0xA8,0xA5,0xA2,0x9F,0x9C,0x99,

0x96,0x93,0x90,0x8D,0x89,0x86,0x83,0x80,

0x80,0x7C,0x79,0x78,0x72,0x6F,0x6C,0x69,

0x66,0x63,0x60,0x5D,0x5A,0x57,0x55,0x51,

0x4E,0x4C,0x48,0x45,0x43,0x40,0x3D,0x3A,

0x38,0x35,0x33,0x30,0x2E,0x2B,0x29,0x27,

0x25,0x22,0x20,0x1E,0x1C,0x1A,0x18,0x16,

0x15,0x13,0x11,0x10,0x0E,0x0D,0x0B,0x0A,

0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,

0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,

0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 0x0A,0x0B,0x0D,0x0E,0x10,0x11,0x13,0x15,

0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x25,

0x27,0x29,0x2B,0x2E,0x30,0x33,0x35,0x38,

0x3A,0x3D,0x40,0x43,0x45,0x48,0x4C,0x4E,

0x51,0x55,0x57,0x5A,0x5D,0x60,0x63,0x66,

0x69,0x6C,0x6F,0x72,0x76,0x79,0x7C,0x80

};

uchar const table_fb[256] = //方波 {

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 };

uint t1_cnt;

uchar flag=1;

uchar pinlv_flag;//频率标志

uchar dis_flag=1;

uint cnt;

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

以下是对液晶模块的操作程序

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

#define RS_0 PORTC&=~(1<

#define RS_1 PORTC|=(1<

#define RW_0 PORTC&=~(1<

#define RW_1 PORTC|=(1<

#define E_0 PORTC&=~(1<

#define E_1 PORTC|=(1<

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

函数功能:延时若干微秒

入口参数:n

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

void delaynus(unsigned int n)

{

if (n == 0)

return ;

while (--n);

}

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

函数功能:延时1ms

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

void delay1ms(void)

{

unsigned int i;

for(i=0;i<114;i++);

}

void delaynms(unsigned int n) //N ms延时函数

{

unsigned int i=0;

for (i=0;i

delay1ms();

}

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

函数功能:延时若干毫秒

入口参数:n

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

void delay(uint xms)

{

int i,j;

for(i=0;i

{ for(j=0;j<114;j++) ; }

}

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

函数功能:判断液晶模块的忙碌状态

返回值:result。result=1,忙碌;result=0,不忙

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

unsigned char BusyTest(void)

{

unsigned char result;

DDRA=0x00;

RS_0; //根据规定,RS为低电平,RW为高电平时,可以读状态

RW_1;

E_1; //E=1,才允许读写

delay1ms();

//delaynus(40);

result=PINA&0x80; //将忙碌标志电平赋给result

E_0; //将E恢复低电平

return result;

}

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

函数功能:将模式设置指令或显示地址写入液晶模块

入口参数:dictate

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

void Write_com (unsigned char dictate)

{

DDRA=0xff;

// while(BusyTest()); //如果忙就等待

RS_0; //根据规定,RS和R/W同时为低电平时,可以写入指令

RW_0;

E_0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0"

delay1ms();

PORTA=dictate; //将数据送入P0口,即写入指令或地址

//delaynus(40);

delay1ms();

E_1;//E置高电平

delay1ms();

//delaynus(40);

E_0; //当E由高电平跳变成低电平时,液晶模块开始执行命令

delay1ms();

}

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

函数功能:指定字符显示的实际地址

入口参数:x

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

void WriteAddress(unsigned char x,unsigned char y)

{

switch(y){

case 1:Write_com(x|0x80);break; //显示位置的确定方法规定为"80H+地址码x"

case 2:Write_com(x|0xc0);break; //显示位置的确定方法规定为"80H+地址码x"

default : break;

}

}

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

函数功能:将数据(字符的标准ASCII码)写入液晶模块

入口参数:y(为字符常量)

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

void WriteData(unsigned char dat)

{

DDRA=0xff;

// while(BusyTest());

RS_1; //RS为高电平,RW为低电平时,可以写入数据

RW_0;

E_0; //E置低电平(根据表8-6,写指令时,E为高脉冲,

// 就是让E从0到1发生正跳变,所以应先置"0"

delay1ms();

PORTA=dat; //将数据送入P0口,即将数据写入液晶模块

// delaynus(40);

delay1ms();

E_1; //E置高电平

delay1ms();

//delaynus(40);

E_0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 }

void Write_string(unsigned char *s)

{

while(*s!='\0')

{

WriteData(*s);

s++;

}

}

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

函数功能:对LCD的显示模式进行初始化设置

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

void LcdInt(void)

{

delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间

Write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口

delay(5); //延时5ms

Write_com(0x38);

delay(5);

Write_com(0x38); //3次写设置模式

delay(5);

Write_com(0x0c); //显示模式设置:显示开,有光标,光标闪烁

delay(5);

Write_com(0x06); //显示模式设置:光标右移,字符不移

delay(5);

Write_com(0x01); //清屏幕指令,将以前的显示内容清除

delay(5);

}

int GetKey(void)

{

int keyval,keyval2;

keyval = PINB;

keyval = (~keyval)&0xff;

if(keyval!=0xff)

delaynms(10);

switch(keyval)

{

case 1:while(!(PIND & (1 << PB0)));//等待按键释放

return 1;

case 2:while(!(PIND & (1 << PB1)));//等待按键释放

return 2;

case 4:while(!(PIND & (1 << PB2)));//等待按键释放

return 3;

case 8:while(!(PIND & (1 << PB3)));//等待按键释放 return 4;

case 0x10:while(!(PIND & (1 << PB4)));//等待按键释放 return 5;

case 0x20:while(!(PIND & (1 << PB5)));//等待按键释放 return 6;

case 0x40:while(!(PIND & (1 << PB6)));//等待按键释放 return 7;

case 0x80:while(!(PIND & (1 << PB7)));//等待按键释放 return 8;

default:

return 0;

}

}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF void timer1_ovf_isr(void)

{

//TIMER1 has overflowed

// TCNT1H = 0xe0; //reload counter high value

// TCNT1L = 0xc0; //reload counter low value

if(pinlv_flag==5)//0.800MS *64

{

TCNT1H = 0xe7; //reload counter high value

TCNT1L = 0x00; //reload counter low value

}

else if(pinlv_flag==4)//1MS *64

{

TCNT1H = 0xe0; //reload counter high value

TCNT1L = 0xc0; //reload counter low value

}

else if(pinlv_flag==3)//2MS *64

{

TCNT1H = 0xc1; //reload counter high value

TCNT1L = 0x80; //reload counter low value

}

else if(pinlv_flag==2)//4MS *64

{

TCNT1H = 0x83; //reload counter high value

TCNT1L = 0x00; //reload counter low value

}

else //8MS *64

{

TCNT1H = 0x06; //reload counter high value TCNT1L = 0x00; //reload counter low value }

t1_cnt+=4;

if(t1_cnt>=255)

t1_cnt=0;

if(flag==1)

PORTD=table_zxb[t1_cnt];

else if(flag==2)

PORTD=table_fb[t1_cnt];

else if(flag==3)

PORTD=table_sjb[t1_cnt];

else if(flag==4)

PORTD=255-t1_cnt;

cnt++;

if(cnt>=100)

{

cnt=0;dis_flag=1;

}

}

//TIMER1 initialize - prescale:1

// WGM: 0) Normal, TOP=0xFFFF

// desired value: 1mSec

// actual value: 1.000mSec (0.0%)

void timer1_init(void)

{

TCCR1B = 0x00; //stop

TCNT1H = 0xE0; //setup

TCNT1L = 0xC0;

OCR1AH = 0x1F;

OCR1AL = 0x40;

OCR1BH = 0x1F;

OCR1BL = 0x40;

OCR1CH = 0x1F;

OCR1CL = 0x40;

ICR1H = 0x1F;

ICR1L = 0x40;

TCCR1A = 0x00;

TCCR1B = 0x01; //start Timer

}

//call this routine to initialize all peripherals

void init_devices(void)

{

//stop errant interrupts until set up

CLI(); //disable all interrupts

XDIV = 0x00; //xtal divider

XMCRA = 0x00; //external memory

timer1_init();

MCUCR = 0x00;

EICRA = 0x00; //extended ext ints

EICRB = 0x00; //extended ext ints

EIMSK = 0x00;

TIMSK = 0x04; //timer interrupt sources

ETIMSK = 0x00; //extended timer interrupt sources

SEI(); //re-enable interrupts

//all peripherals are now initialized

}

void main(void )

{

uint key_num,temp;

DDRA=0xff; //配置为输出,1602使用

PORTA=0xff;

DDRC=0X7f;

PORTC=0XFF;

DDRD=0Xff;

PORTD=0XFf;

DDRB=0X00;

PORTB=0XFf;

init_devices();

LcdInt(); //调用LCD初始化函数

delaynms(10);

WriteAddress(0,1);

Write_string("Zheng Xian Bo");

while(1)

{

if(dis_flag)

{

dis_flag=0;

temp=readTempDS18B20()/16;

temp=readTempDS18B20()/16;

if(temp<10){pinlv_flag=1;WriteAddress(6,2);Write_string(" 2HZ");}

else

if(temp>=10&&temp<20){pinlv_flag=2;WriteAddress(6,2);Write_string("

4HZ");}

else

if(temp>=20&&temp<30){pinlv_flag=3;WriteAddress(6,2);Write_string("

8HZ");}

else

if(temp>=30&&temp<40){pinlv_flag=4;WriteAddress(6,2);Write_string("15HZ ");}

else {pinlv_flag=5;WriteAddress(6,2);Write_string("19HZ");}

WriteAddress(0,2);

WriteData(temp/100+'0');WriteData(temp%100/10+'0');WriteData(temp%10+ '0');WriteData('^');WriteData('C');

}

key_num=GetKey();

if(key_num)

{

if(key_num==1)

{

flag=1;

WriteAddress(0,1);

Write_string("Zheng Xian Bo");

}

else if(key_num==2)

{

flag=2;

WriteAddress(0,1);

Write_string(" Fang Bo");

}

else if(key_num==3)

{

flag=3;

WriteAddress(0,1);

Write_string("San Jiao Bo");

}

else if(key_num==4)

{

flag=4;

WriteAddress(0,1);

Write_string("Ju chi Bo");

}

}

}

}

4)调试过程,最终的实现结果分析等。

1、正弦波

2、方波

3、三角波

4、锯齿波

5、温度1~10度2HZ

6、温度11~20度4HZ

7、温度21~30度8HZ

8、温度31~40度15HZ

9、温度大于40度19HZ

5)收获、心得、建议

这两周的课程设计对我来说是一个挑战,我之前从来没有学过Avr,一路头我从参考书上找来了课题,可是事实是参考书,做到当时觉察良多法式都是不完好的,这让我伤透了脑子。看着别人都弄得有模有样了,可是我很着急。然后我和我一个课题的同学巨匠一路齐心合力,从教员上课的举例、书本上的学问以及教员的教育和其他同窗的辅佐下事实完成了。同时也知道了一些ATmega128、DS18B20等芯片的基本原理。

这次开放性试验虽然结束了,但是在试验中训练出的动手能力,培养出的思考问题方式却会一直陪伴着我。我认为开放性设计非常适合我们大学生的学习方式,可以激发出我们的潜力。

设计成绩评定

AVR单片机EEPROM和FLASH区别

AVR单片机EEPROM和FLASH区别 为什么A VR单片机既有FLASH又有EEPROM?我如果要烧写程序只用HEX文件行么?那个EEP文件有什么作用? 你的程序代码是保存在FLASH里的,只烧写HEX文件就可以。EEP文件是EEPROM的初始化数据文件,如果不烧写,EEPROM会保持FF,如果烧写了这个文件,就会按照你的初始化要求初始化EEPROM。在实际中有时往往不仅仅需要程序代码,还需要用到一些数据,而这些数据又会根据情况的不同而变化。举个例子,比如我要测量一个电机的转数,而每天电机最多测量12个小时,要求记录这12个小时的转数,然后第二天从这个数值继续测量,当然第二天单片机也会重新上电。遇到这个情况你如何去保存你的记录数值呢?当然这就需要用到EEPROM了。EEPROM存取数据方便,掉电不丢失,适合记录这种要求有变化又要求掉电不丢失的数据。当然EEPROM也可以作为程序存储器来存放程序。但是A VR单片机的BOOTLOADER是ATMEL提供的,只能够从FLASH开始。其次,即使能够使用EEPROM做程序存储器,如今也不会采用这样的方式,因为EEPROM造价比FLASH要高很多,同时存取速度比FLASH要慢得多,因此如今的程序基本都是被放入FLASH中,而EEPROM只用来存放那些不希望丢失的数据而用了 FLASH 一个静态的只读存储器,单片机本身无法修改自己 EEPROM 是指5V或3.3V可擦写存储器,可以由单片机本身编程写入一般用来做掉电保护,也可以由烧程器写入。烧程时当然只用HEX文件AVR编程的时候,可以对EEPROM编程 设置你想要的初始化量 简单的说,flash是保存程序的,eeprom是保存程序需要用到的,掉电不会丢失的变量,通常是初始值之类的。通常flash不会被程序改写(avr有bootloader 功能,可以修改flash甚至bootloader自身),而eeprom则很容易被改写。 一般来讲,实际应用中eeprom用的不多,除非对成本极为看重,因为片内的eeprom比较不可靠,当电压不稳时,数据容易丢失。 AVR系列单片机的FLASH存储器、SRAM存储器、EEPROM存储器各有什么用途? FLASH:单片机运行的程序存储的地方。

AVR学习笔记十九、4X4矩阵键盘实验

A VR学习笔记十九、4X4矩阵键盘实验 19.1 实例功能 在前面的实例中我们已经学习了在单片机系统中检测独立式按键的接口电路和程序设计,独立式按键的每个按键占用1位I/O口线,其状态是独立的,相互之间没有影响,只要单独测试链接案件的I/O口线电平的高低就能判断键的状态。独立式按键电路简单、配置灵活,软件结构也相对简单。此种接口方式适用于系统需要按键数目较少的场合。在按键数量较多的情况下,如系统需要8个以上按键的键盘时,采用独立式接口方式就会占用太多的I/O口,这对于I/O口资源不太丰富的单片机系统来说显得相当浪费,那么当按键数目相对较多的时候,为了减少I/O口资源的占用,应该采取什么样的方式才能够既满足多按键识别,又减少I/O口的占用呢? 当然我们可以采用端口扩展器件比如串并转换芯片实现单片机I/O口的扩展,但是这种方式既增加了电路的复杂性,又增加了系统的成本开销。有没有比较经济实惠的方法呢? 事实上,在实际引用中我们经常采用矩阵式键盘的方式来节约I/O口资源和系统成本。 在这个实验中,我们采用4X4矩阵键盘来实现使用8个I/O口识别16个按键的实验,本实例分为三个功能模块,分别描述如下: ●单片机系统:利用A Tmega16单片机与矩阵键盘电路实现多按键识别。 ●外围电路:4X4矩阵键盘电路、LED数码管显示电路。 ●软件程序:编写软件,实现4X4矩阵键盘识别16个按键的程序。 通过本实例的学习,掌握以下内容: ●4X4矩阵键盘的电路设计和程序实现。 19.2 器件和原理 19.2.1 矩阵键盘的工作原理和扫描确认方式 当键盘中按键数量较多时,为了减少对I/O口的占用,通常将按键排列成矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图1所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU通过检测行或列线上的电平变化可以确定哪个按键被按下。 图1为一个4 x 4的行列结构,可以构成16个键的键盘。很明显,在按键数量多的场合,矩阵键盘与独立式按键键盘相比可以节省很多的I/O口线。 图1 4X4键盘扫描电路

AVR单片机实验报告PCF8563

南京邮电大学 2011 /2012 学年第一学期 课程设计实验报告 模块名称A VR单片机课程设计 专业 学生班级 学生学号 学生姓名 指导教师李虹戴海鸿杨洁王明伟 日期: 2011年9月26日至 2011年10月20日

A VR单片机课程设计报告 一.课程设计目的 1.学习ATmega128单片机的仿真环境(A VR Studio)及C语言编程环境 (ICC A VR)。 2.学习ATmega128单片机的C语言编程,熟悉使用板载JTAG进行仿 真调试。 二.课程设计内容 1.基本要求: 1) 访问时钟芯片PCF8563,在LCD1602上显示年、月、日、时、分、秒,或通 过串口将时间传至PC。 2) 合理定义板上按键功能,随机设定、调整时间和日期。 2.扩展要求: 1) 闹钟功能,启动蜂鸣器鸣叫。 2)有闰年功能 三.课程设计过程 1. 设计原理: 利用A Tmega128内部的IIC,读写实时时钟芯片PCF8563内部的寄存器,通过PC显示出来,可通过按键,设置当前时间。 2. 实验原理图: 按键部分 4个独立按键,接在PD4~PD7,通过一个电阻到地,键盘按下时为低电平,释放为高电平。

实时时钟芯片PCF8563部分 实时时钟芯片PCF8563通过IIC总线连接到A Tmega128的SDA和SCL 总线上。 3.软件设计 1)思路如下:使用ATmega128内部TWI通过IIC总线读写实时时钟 芯片PCF8563内部的寄存器实现实时时钟功能,使用四个按键设置时 钟的年,月,日,时,分,秒,并把时钟显示到PC上。 2)程序流程图 3)关键代码: void PowerOnInitial(void) {

AVR studio 中断、计时器程序

本程序应用了外部中断1、0,定时器中断0, 初始显示变量uname(100000), 按下中断1显示内容减1,中断0加1,定时器每隔一秒加1 显示子函数A VR_display; 频率1M A口接数码管段选 B口接数码管位选 */ #include #include volatile unsigned long Ex_i; //定时器用的变量 volatile unsigned long uname=100000;//初始显示内容 /*=====0-9=====A-G=====*/ unsigned char table[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F /*0-7*/ unsigned char num[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共阳极数码管的wei码0 1 2 3 4 5 6 7 8 void init_avrinter();//外部中断初始化 void init_avrtimer0();//计数器0初始化 void delay(unsigned int x);//延时函数 void AVR_display(unsigned long nnn);//显示函数 int main() //主程序 { DDRA=0xff; //设置方向寄存器为输出 DDRB=0xff; DDRD=0xff; PORTD=0xff; init_avrinter(); init_avrtimer0(); while(1) { A VR_display(uname); } } void init_avrinter()//外部中断初始化 { sei(); //开总中断

avrEEPROM数据丢失问题原因与解决方案

avr EEPROM 数据丢失问题原因与解决方 案 总结一下引起AVR内部EEPROM数据丢失的原因: 1.程序问题; 2.程序跑飞; 3.EEPROM相关寄存器因强磁场、高压静电等外部干扰出错所产生的写入动作; 4.系统有很大的感性负载,在断电的时候会产生一 个反向高压,EEPROM有可能会自擦除。 ……(还有什么原因,欢迎大家继续列举,以便完善及想办法解决) 针对问题1,程序问题不再该文讨论范围内。 针对问题2,程序跑飞,这个因该是引起EEPROM数据丢失的主要原因。但是引起程序跑飞的原因却是多方

面的。 第一.电压不正常,工作不稳定,程序跑飞。针对这个问题,可以开启内部BOD、或者外加复位芯片解决,在低功耗场合,外部复位是有必 要的,毕竟BOD功耗太高。 第二,晶体振荡受干扰,频率不稳定,程序跑飞。针对这个问题,建议晶体使用全幅振荡,并且走线的时候尽量短,并且使用地线隔离。 第三系统受外界环境干扰,修改了PC等寄存器,程序跑飞。针对这个干扰问题,这个引起程序跑飞的可能性应该不大,如果环境实在恶劣 ,那么就应该想到做电磁屏蔽,ESD保护等,如果还不行,那么只能建议换换别的单片机试试看了。 针对问题3,我们只能优化电路设置,尽量避免,比如加屏蔽罩,加ESD保护,加TVS保护,电源加电容退耦等等。

针对问题4,如果系统真的具有很大的感性负载,那么请注意加续流二极管、滤波电容等做保护,不要让这种反向高压产生,无论如何,这 种因为感性负载突然断电自激产生的高压,不仅仅会对EEPROM有影响,而是对整个系统都存在威胁。 ================================================= ================================================= ============ 经过上面硬件上的一些处理,虽然EEPROM数据丢 失的可能已经很小了,但是我们仍然不能保证EEPROM数据就不会丢失了。这时EEPROM数据的可*性,那就得从软件上去考虑了,接着我们从 软件的方面继续讨论。 我的做法是,数据分块,分区,校验,备份。当然这里讲的处理方法,仅仅是提供一种想法,你可以做不同数据长度的分块,不同大小的 分区,采用不同的地址映射方法,以及采用更多次的数据备份。下面以Mega168为例继续讨论。 1.Mega168EEPROM512字节,把EEPROM分为两个区,每个

AVR学习笔记

ATmega16

中断表

第一节课 Avr单片机的每个引脚有三个寄存器来控制: DDRnx(输入输出控制寄存器1输出,0输入) PORTnx(引脚输出电平控制) PINnx(输入寄存器) 第二节课 AVR单片机的AD转换 涉及寄存器:ADMUX sbit[7;6]参考电压选择,sbit[5] AD转换数据对齐方式选择,sbit[4:0]通道与增益选择; ADCSRA sbit[7]AD使能,sbit[6]AD开始转换,sbit[5]自动触发使能,sbit[4]AD 中断使能,sbit[3:0]分频设置; SFIOR(触发源的选择)sbit[7:5] (ADTS)选择触发源, ADCL,ADCH数据寄存器; 初始化步骤: 1:设置通道的IO口为输入(高阻); 2:设置与AD有关的寄存器; 3:开总中断,SREG=BIT(7); 4:写中断函数 (中断标号是15) 第三节课 AVR有三个定时计数器,T/C0,T/C1,T/C2; T/C0,T/C2是两个8BIT的计数器; T/C1定时计数器,普通模式 时机寄存器: TCCR1B:2:0时钟选择 TCNT1L,TCNTH:定时数据

TIMSK :TOIE 中断使能位 使用方法 1, 选择时钟源,TCCR1B ; 2, 设计初值,TCNT1L ,TCNT1H ; 3, 设置中断使能位;TIMSK{2},SREG{7} 4, 选中断号,写中断函数 5, (中断号9) CTC 模式 如果输出波形,则设IO 位输出 设置波形模式和时钟源TCCR1B 设置输出模式TCCR1A 根据需要设置上限OCR1ATCCR1A 设置输出口 频率计算:() A OCR N f f clk o 112+??= 控制寄存器A TCCR1A COM1A1:0: 通道A 的比较输出模式 COM1B1:0: 通道B 的比较输出模式 COM1A1:0与COM1B1:0分别控制OC1A 与OC1B 状态。如果COM1A1:0(COM1B1:0)的一位或两位 被写入"1”,OC1A(OC1B) 输出功能将取代I/O 端口功能。此时OC1A(OC1B)相应的输出引脚 数据方向控制必须置位以使能输出驱动器。

avr实验报告

通达学院 2014 /2015 学年第一学期 课程设计实验报告 模块名称A VR单片机课程设计(proteus)专业通信工程 学生班级 学生学号 学生姓名 指导教师李虹戴海鸿杨洁王明伟

AVR单片机软件设计(proteus)报告 基本内容包括: 1)总体设计原理、思路; 根据题目的要求,我们需要事先得到3种波形的信号源,并将其在程序存储器中,然后取出程序存储器里的信号源存放在atmega128的外部RAM中,并通过DAC0832输出到示波器上显示图形。采用按键方式控制输出波形,并且通过DS18B20上的温度来控制信号的频率,温度在1~10时显示2Hz,温度为11~20时显示4Hz,温度为21~30时为8Hz,温度为31~40时为15Hz,温度大于40时为19Hz。最后在LM016L上显示出输出的波形名称和温度以及频率。 2)硬件方面原理图的设计:包括使用的元器件、典型芯片的介绍;原理图的说明等 1、ATmega128 ATmega128为基于AVR RISC结构的8位低功耗CMOS微处理器。由于其先进的指令集以及单周期指令执行时间,ATmega128 的数据吞吐率高达1 MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。 2、DS18B20 DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发

的温度报警触发器TH和TL、配置寄存器。光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的,也就是你要做的是配置寄存器。 根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。 3、DAC0832 DAC0832是采样频率为八位的D/A转换芯片,集成电路内有两级输入寄存器,使DAC0832芯片具备双缓冲、单缓冲和直通三种输入方式,以便适于各种电路的需要(如要求多路D/A异步输入、同步转换等)。DAC0832是8分辨率的D/A 转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。DAC0832逻辑输入满足TTL电平,可直接与TTL电路或微机电路连接。 3)软件方面程序流程图的设计、关键代码的说明

AVR单片机教程13—第十三课 ATMEAG16L的外部中断编程实践

—————————————————————————— 第十三课ATMEAG16L的外部中断编程实践 本教程节选自周兴华老师《手把手教你学AVR单片机C程序设计》教程,如需转载,请注明出处!读者可通过当当网、淘宝网等网站购买本教程,如需购买配书 实验器材,可登陆周兴华单片机培训中心网购部自助购买! Atmega16L具有多达20个中断源,这里我们进行外部中断的实验,其它的等到介绍到相关内容时可进行适当的实验。 1.外部中断0 外部中断0由引脚INT0(PIND2)触发。如果INT0引脚按照MCUCR寄存器中的ISC01、ISC00设置的方式发生跳变,则不管是否lNT0中断使能,INT0中断标志位INTF0都将置位。如果SREG 寄存 器的全局中断位I和通用中断控制寄存器GICR中的INT0中断使能位INT0置位,则单片机培训开始 执行中断程序。在进入中断服务程序时,INTF0被硬件清零。必须指出,不管INT0(PIND2)引脚 方向位设置如何,只要INT0引脚发生规定的跳变,都会触发中断。中断标志位INTF0只在满足发生 中断的条件时置位,一旦条件变化,INTF0被硬件清零。向INTF0位写“1”也会对其清零。 2.外部中断1 外部中断0由引脚INT1(PIND3)触发。如果INT1引脚按照MCUCR寄存器中的ISC11、ISC10设置的方式发生跳变,则不管是否lNT1中断使能,INT1中断标志位INTF1都将置位。如果SREG 寄存 器的全局中断位I和通用中断控制寄存器GICR中的INT1中断使能位INT1置位,则开始执行中断程 序。在进入中断服务程序时,INTF1被硬件清零。必须指出,不管INT1(PIND3)引脚方向位设置 如何,只要INT1引脚发生规定的跳变,FPGA培训都会触发中断。中断标志位INTF1只在满足发生 中断的条件时置位,一旦条件变化,INTF1被硬件清零。向INTF1位写“1”也会对其清零。 3.外部中断2 外部中断2由引脚INT2(PINB2)触发。如果INT2引脚按照MCUCR寄存器中的ISC2设置的方式发生跳变,则不管是否lNT2中断使能,INT2中断标志位INTF2都将置位。如果SREG 寄存器的全局 中断位I和通用中断控制寄存器GICR中的INT2中断使能位INT2置位,则开始执行中断程序。在进 入中断服务程序时,INTF2被硬件清零。必须指出,不管INT2(PINB2)引脚方向位设置如何,只 要INT2引脚发生规定的跳变,都会触发中断。中断标志位INTF2只在满足发生中断的条件时置位, 一旦条件变化,INTF2被硬件清零。向INTF1位写“1”也会对其清零。 8.2.1 INT1中断实验

软件维护实验报告yxx

实验一检查程序的可维护性 一.实验内容 a、认真分析程序代码,了解程序的功能; b、找出程序中的错误,对其进行修改; c、找出程序中不符合规范的地方,进行修改; d、对输入的分数进行检测,要求不小于零,不大于100; e、为了检测程序输出的对错,要求通过在输入结束后,显示输入的学生数据; f、如果学生人数为6,每个同学有4门课,请在源程序上修改。 程序代码: struct student { char num[6]; char name[8]; int fenshu[3]; float avr; } stu[5]; int main() { int i,j,sum; FILE *fp; /*input*/ for(i=0,i<5,i++) {printf("\n please input No. %d fenshu:\n",i); printf("stuNo:"); scanf("%s",stu[i].num); printf("name:"); scanf("%s",stu[i].name);sum=0; for(j=0,j<3,j++) {printf("fenshu %d.",j+1); scanf("%d",&stu[i].fenshu[j]); sum+=stu[i].fenshu[j]; } stu[i].avr=sum/3.0; } fp=fopen("stud","w"); for(i=0,i<5,i++) fprintf(fp,"%s\t%s\t%d\t%d\t%d\t%f\n", stu[i].num, stu[i].name, stu[i].fenshu[0], stu[i].fenshu[1], stu[i].fenshu[2],stu[i].avr); fclose(fp); }

AVR单片机WinAVR及Proteus仿真外部中断

本文主要以AVR单片机atmega48的外部中断的在Proteus上仿真的例子介绍AVR单片机C 语言开发环境WinAVR的使用(如何包含头文件,如何写中断服务程序,如何配置编译产生hex文件),及其在Proteus上的仿真实现(如何建立仿真图,载入hex文件进行仿真) 本例子完全为PC上软件仿真所以不涉及硬件,其全部所需软件清单如下: WinAVR、Proteus、atmega48_Datasheet 软件的下载安装,请参考网上其他教程,有很多,很容易的。 atmega48单片机的数据手册网上中英文的版本也都可以下载到。 下图是笔者所使用的软件截图,不同版本可能稍有差异,但基本不影响使用。 下面我将在假设您已经安装好2个软件(当然目前您不需要知道它们是怎么用的),并且对单片机和C语言有基本了解的基础上进行例程的演示。 let's begin。 首先要明确我们要完成的功能:单片机开始工作后,点亮LED灯1S,灭掉LED灯1S,如此循环3次,然后单片机进入无限循环,等待外部按键button按下,LED等再次点亮,当再次按下button时,LED等灭掉,如此循环。

接着画出要实现这个功能的电路,以便后续仿真。 先在桌面建一个文件夹Hello_AVR,如图。 打开软件,这个图标。 在软件界面上,右键Place->Component->From Libraries 在Keywords里面输入atmega48,选择一个32PIN管脚的单片机放到图上

同样的方法,放置一个LED灯,一个button,电阻,电容。

放置POWER和GND

图完成,在文件夹Hello_AVR下新建文件夹Sim,保存在这里 这里用PB0管脚来驱动LED灯,查阅芯片的数据手册或直接从图中可以知道,外部中断0(INT0)在PD2管脚。而且Proteus的好处是,这里我们给单片机画电源的麻烦也可以省去。 接下来要做的就是看数据手册和建立工程,编程,编译的事了。 打开Programmers Notepad File->New->Project新建工程Hello_AVR,保存到Hello_AVR文件夹

AVR常用操作

IAR编译器配置(AVR ) 一、EEPROM 区域数据存储: __eeprom unsigned char a;//定义一个变量存放在EEPROM空间 __eeprom unsigned char a @ 0x8;//定义一个变量存放在EEPROM空间0X08单元 __eeprom unsigned char p[] @ 0x22//定义一个数组存放在EEPROM空间,开始地址为0X22单元 __eeprom unsigned char a @ 0x08=9;//定义一个常数存放在EEPROM空间0X08单元 __eeprom unsigned char p[] @0x22={1,2,3,4,5,6,7,8}; EEPROM操作宏取函数:在comp_a90.h intrinsics.h头文件里有详细说明。 自动生成.eep文件置:在Project->Options->linker->config>的linker command line中观察该Project使用了哪个XCL文件。本文使用M8编译,使用文件 是”TOOLKIT_DIR$\src\template\cfgm8.xcl”-Ointel-extended,(CODE)=.hex -Ointel-extended,(XDATA)=.eep 二、FLASH 区域数据存储: 用关键字__flash 控制来存放,__ flash 关键字写在数据类型前后效果一样 __flash unsigned char a @ 0x8;//定义变量存放在flash 空间0X08单元__flash unsigned char p[] @ 0x22//定义数组存放在flash 空间,开始地址为0X22单元 __flash unsigned char a @ 0x08=9;//定义常数存放在flash 空间0X08单元 __flash unsigned char p[] @ 0x22={1,2,3,4,5,6,7,8}; unsigned int __flash * p;//定义个指向flash 空间地址的指针,16位。 unsigned int __farflash * p;//定义指向flash 空间地址的指针,24位。 __flash unsigned char * p; //定义指向SARMM空间地址的指针,指针本身存放在flash 中。 flash 操作宏函数:在comp_a90.h intrinsics.h头文件里有详细说明 三、IAR编译器对位的支持更强大: PORTB_ Bit2=1; //置PORTB的第2位=1 PORTC_Bit4=PORTB_Bit2;//把PORTB的第2位传送到PORTC的第4位 四、头文件 avr_macros.h里面包含了读写16位寄存器的简化书写,和几个位操作函数 comp_a90.h对大量的内在函数做了简要书写,flash 操作宏函数 ina90.h包含"inavr.h" "comp_A90.h"文件 intrinsics.h内在函数提供最简单的操作处理器底层特征。休眠,看门狗,FLASH函数。 iomacro.H I/O寄存器定义文件样本。 #include #include #include #include #include #include #include #include #include

AVR学习笔记

A VR学习笔记(基于LT_Mini_M16) 一、点亮发光二极管 一、实验内容和目的 本实验通过硬件电路和软件程序,利用A TMega16单片机来控制发光二极管的点亮和熄灭。通过此实验初步掌握单片机的I/O口功能。 二、硬件电路 1、电路分析(对照LT_Mini_M16原理图) 1)电源电路:外接稳压直流电源(最好是DC9V)加到电路的U1处,经过电容C16稳压滤波后加到稳压模块AMS1117-5.0上,然后连接到电源开关按钮S1,从开关按钮出来后经过发光二极管D9和电阻R7,再经过电容C1、C2、C3、C4、C5、C7稳压滤波后加到单片机以及各个模块的电源端。 分析:a) 电容的作用是稳压滤波,其中C1、C2、C3、C4、C5这5电容为0.1PF (俗称104电容,一般为瓷片电容)。主要作用为滤出电源电路中的高频成分;而C16、C7是电解电容,主要作用是稳压,即把电源电路中的尖峰电压拉低到正常电压水平;C16是稳定外接直流电源的电压(9V),C7是稳定AMS1117-5.0输出的5V电压。 b)稳压芯片采用ASM1117-5.0,该稳压芯片输入电压范围为6.5V-15V,输出电压稳定在5.0+0.1V,最大输出电流可达1A,可以满足一般电路需要。 c) 电源开关按钮S1的作用当然是接通和断开电源了。在此电路中S1采用的是单刀双掷开关,一旦断开电源,则电源的正负极都断开了。 d)发光二极管D9的作用是指示电源是否连接成功,如果外部电源成功的连接上,则发光二极管发光指示电源连接成功;电阻R7的作用是对发光二极管进行限流,一般发光二极管只能通过10mA左右的电流,且发光二极管上面的压降只需要1.5V左右,加到发光二极管上面的电流如果超出额定值,则会烧毁。而系统工作的电压是5V,如果全部加在发光二极管上,则发光二极管很容易就会被烧毁。所以要在电源和发光二极管之间串接一个限流电阻。该限流电阻阻值的计算:(VCC-发光二极管上的电压)/流过发光二极管的电流。一般发光二极管的压降是1.5V左右,电流为10mA左右,则可计算如下:限流电阻的阻值=(5.0-1.5)/0.01=350欧姆,一般这个阻值可以取得稍微大一些。 2)复位电路:单片机的第9脚(RESET,复位管脚)经过按钮K5连接到地。 分析:a)A VR单片机是低电平复位(51单片机是高电平复位,刚好相反)。需要单片机复位时,最少要在复位管脚加上1.5微秒的低电平,才能确保单片机正确复位。 b)按下按钮K5,复位管脚被直接拉到电源地,这样复位管脚的电平就被拉低,从而使单片机复位;一般情况下按钮按下的时间超过毫秒级别,这样就能确保单片机正确复位。 3)ISP电路(程序下载电路):ISP下载接口不需要任何的外围零件。使用双排2*5排针。 分析:a)由于没有外围零件,故PB5(MOSI)、PB6(MISO)、PB7(SCK)、复位脚仍可以正常使用,不受ISP的干扰。 b)ISP下载接口的1、3、5、7、9脚分别接单片机的PB5(MOSI)、PB6(MISO)、PB7(SCK)、复位脚;2接VCC,4、6、8、10都接在GND上。 4)晶振电路:晶体的两脚分别接单片机的12、13脚(晶体的管脚没有正负和顺序,可以随意连接),电容C11、C12分别于晶体的两脚和地连接。

实验三实验报告

[实验三]定时器的应用 [实验目的] 1.结合定时/计数器的应用,更深入的了解AVR中断系统原理,响应过程,以及中断服务 程序的编写。 2.掌握定时器的基本应用,了解定时器的各种用途 [基本实验内容]: 根据需要给出电原理图和程序清单。 1.了解CTC的用途,通过定时器的CTC实现LED的定时闪烁,定时时间1S。 /***************************************************** Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include bit time_1s_ok=0; int time_counter=0; interrupt [TIM0_COMP] void timer0_comp_isr(void) { if(time_counter>=500)

{time_counter=0; time_1s_ok=1; } } void main(void) { PORTC=0x01; // 显示控制I/O口初始化 DDRC=0x01; TCCR0=0x0B; //内部时钟,64分频 TCNT0=0x00; OCR0=0x7C; //OCR0=0x7c(124),(124+1)/62.5KHz=2ms TIMSK=0x01; //允许T/C0比较比配中断 #asm("sei") while (1) { if(time_1s_ok){ time_1s_ok=0; PORTC=~PORTC; } }; } 2.阅读器件手册,查阅定时器相关寄存器,通过使用定时器改写P188页的例6.7中的点阵LED箭头移动程序。箭头运动速度保持与原来相同。 /********************************************* Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *********************************************/ #include #define row 12 #define speed 25*8 //移动速度调节 flash unsigned char char_7[row]={0x10,0x38,0x7C,0xFE,0x38,0x38,0x38,0x38,0x 00,0x00,0x00,0x00}; bit time_1ms_ok; unsigned char dis_buff[8]; interrupt [TIM0_COMP] void timer0_comp_isr(void) // 1ms 中断一次 { time_1ms_ok = 1;

avr睡眠模式(包涵源程序)

AVR单片机电源管理及睡眠模式应用实例(含源代码) AVR单片机电源管理及睡眠模式应用实例(含源代码) /*********************************************** **** AVR 电源管理_睡眠模式范例 *** **** *** **** 作者: HJJourAVR *** **** 编译器:WINAVR20050214 *** **** *** ***********************************************/ /* 本程序简单的示范了如何令AVR ATMEGA16进入睡眠状态及唤醒 电源管理及睡眠模式的介绍 进入最低耗电的掉电模式 关闭各种模块 外部中断唤醒 M16掉电模式的耗电情况(看门狗关闭),时钟为内部RC 1MHz 0.9uA@Vcc=5.0V [手册的图表约为1.1uA] 0.3uA@Vcc=3.3V [手册的图表约为0.4uA] //测量的数字万用表是FLUKE 15B,分辨率0.1uA 这个程序需要MCU进入休眠状态,为实现最低功耗,JTAG接口会被关闭,只能通过LED的变化来观察程序的运行。 这个实验里面,用STK500(AVRISP) ISP下载线来烧录更方便。 熔丝位设置 1 关断BOD功能 BODEN=1 2 如果用ISP方式烧录,就可以完全关闭JTAG口了 OCEEN=1,JTAGEN=1 */ #include #include #include #include //时钟定为内部RC 1MHz,F_CPU=1000000 也可以采用其他时钟 #include /* sleep.h里面定义的常数,对应各种睡眠模式 #define SLEEP_MODE_IDLE 0 空闲模式 #define SLEEP_MODE_ADC _BV(SM0) ADC 噪声抑制模式

AVR使用范例--EEPROM使用详解

AVR使用范例--EEPROM使用详解 本页关键词:什么是eeprom spi eeprom eeprom程序eeprom资料eeprom结构eeprom 读写eeprom的读写 本页详细介绍ICC自带EEPROM操作函数的操作方法,包括单字符读写,数组读写,结构体读写。 程序代码:下载相关文件 ?void main(void) ?{ ? unsigned char temp1,temp2; /*定义变量*/ ? unsigned char buffer[10]; /*定义数组*/ ? unsigned char buf[]="AVR与虚拟仪器"; /*定义字符串*/ ? ? EEPROMwrite(0x10,'a'); /*单字符写入到0x10,注意是单引号*/ ? temp1 = EEPROMread(0x10); /*读一个字符到temp1*/ ? ? ? EEPROM_WRITE(0x20,"abcdefg"); /*写字符串到0x20*/ ? EEPROM_READ(0x20,temp2); /*读字符到temp2,temp2=a*/ ? EEPROM_READ(0x20,buffer); /*读字符串到数组中 buffer[10]=abcdefg */ ?

? EEPROM_WRITE(0x30,buf); /*数组中的值写到EEPROM中:0X30开始为"AVR与虚拟仪器"*/? ? while(1) ? ; ?} ? 调试后的效果: 调试eeprom的时候,记住设置Avr studio保护eeprom数据,否则每次都会将eeprom中的数据改为0xFF。如下图: 打开调试选项: 钩选保护eeprom数据选项:

AVR单片机嵌入式系统原理与应用实践——学习笔记

AVR单片机嵌入式系统原理与应用实践 学习笔记 1.AVR单片机的基本结构 1.1.单片机的基本组成 1.1.1.单片机的基本组成结构 单片机的基本组成单元 CPU 程序存储器数据存储器I/O接口 CPU与各基本单元通过芯片内的内部总线连接。 一般情况下,内部总线中的数据总线宽度(或指CPU字长)也是单片机等级的一个重要指标。 内部总线:数据总线、地址总线、控制总线。 1.1. 2.单片机的基本单元与作用 1)MCU单元 MCU单元部分包括CPU、时钟系统、复位、总线控制逻辑等电路。 CPU: 时钟和复位电路: 总线控制电路:

2)片内存储器 单片机的存储器一般分为程序存储器和数据存储器,它们往往构成互不相同的两个存储空间,分别寻址,互不干扰。 单片机的内部结构通常使用哈佛体系结构,在这种体系中采用分开的指令和数据总线以及分开的指令和数据空间,分别采用专用的总线与CPU交换,可以实现对程序和数据的同时访问,提高了CPU的执行速度和数据的吞吐量。 3)程序存储器 程序存储器用于存放嵌入式系统的应用程序。 4)数据存储器 单片机在片内集成的数据存储器一般有两类:随机存储器RAM、电可擦除存储器EEPROM。 随机存储器RAM: 电可擦除存储器EEPROM 5)输入输出端口 并行总线I/O端口: 通用数字I/O端口:

片内功能单元的I/O端口: 串行I/O 通信口: 其他专用接口: 6)操作管理寄存器 管理、协调、控制、操作单片机芯片中各功能单元的使用和运行。 1.2.ATmega16单片机的组成 1.2.1.AVR单片机的内核结构 “快速访问”意味着在一个周期内执行一个完整的ALU操作。 AVR的算术逻辑单元ALU支持寄存器之间、立即数与寄存器之间的算术与逻辑运算功能,以及单一寄存器操作。每一次运算操作的结果将影响和改变状态寄存器(SREG)的值。 ALU操作 从寄存器组中读取两个操作数 操作数被执行将执行结果写回目的寄存器 1.2.2.ATmega16的外部引脚与封装

单片机mega16实验报告——二十四小时倒计时程序

单片机实验报告实验原理: 原理图 实物图:

实验内容:程序功能介绍 二十四小时倒计时程序,启动程序后六位数码管点亮显示程序初始设置的时间(22 57 57)时,分,秒各占两位。然后利用四个独立按键输入(pb4~pb7)进行校时,其中,pb4对秒进行校时,每按一下秒加一;pb5对分校时,每按一下分加一;pb6对时校时,每按一下时加一;按下pb7则停止校时。程序开始倒计时,计时为零之后六位数码管灭,程序驱动蜂鸣器发音的同时驱动四位二极管逐次点亮,二极管点亮一遍之后变灭同时蜂鸣器停止发音,然后六位数码管重新点亮显示24 00 00,重新倒计时。 程序: /***************************************************** This program was produced by the CodeWizardAVR V1.25.6 Evaluation Automatic Program Generator ?Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l. https://www.doczj.com/doc/1d14800711.html, Project : Version : Date : 2010/10/29 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : ATmega16 Program type : Application Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/

arduino学习笔记

arduino学习笔记 arduino学习笔记1 - 什么是arduino? 要了解arduino就先要了解什么是单片机,arduino平台的基础就是A VR指令集的单片机。 1、什么是单片机?它与个人计算机有什么不同? 一台能够工作的计算机要有这样几个部份构成:中央处理单元CPU(进行运算、控制)、随机存储器RAM(数据存储)、存储器ROM(程序存储)、输入/输出设备I/O(串行口、并行输出口等)。在个人计算机(PC)上这些部份被分成若干块芯片,安装在一个被称之为主板的印刷线路板上。而在单片机中,这些部份全部被做到一块集成电路芯片中了,所以就称为单片(单芯片)机,而且有一些单片机中除了上述部份外,还集成了其它部份如模拟量/数字量转换(A/D)和数字量/模拟量转换(D/A)等。 2、单片机有什么用? 实际工作中并不是任何需要计算机的场合都要求计算机有很高的性能,一个控制电冰箱温度的计算机难道要用酷睿处理器吗?应用的关键是看是否够用,是否有很好的性能价格比。如果一台冰箱都需要用酷睿处理起来进行温度控制,那价格就是天价了。 单片机通常用于工业生产的控制、生活中与程序和控制有关(如:电子琴、冰箱、智能空调等)的场合。 下图就是一个Atmega328P-PU单片机,基于A VR指令集的8位处理器,频率20MHz,存储器空间32KB。 什么是Arduino? Arduino是一个能够用来感应和控制现实物理世界的一套工具。它由一个基于单片机并且开放源码的硬件平台,和一套为Arduino板编写程序的开发环境组成。 Arduino可以用来开发交互产品,比如它可以读取大量的开关和传感器信号,并且可以控制各式各样的电灯、电机和其他物理设备。Arduino项目可以是单独的,也可以在运行时和你电脑中运行的程序(例如:Flash,Processing,MaxMSP)进行通讯。Arduino板你可以选择自己去手动组装或是购买已经组装好的;Arduino开源的IDE可以免费下载得到。 Arduino的编程语言就像似在对一个类似于物理的计算平台进行相应的连线,它基于处理多媒体的编程环境。

相关主题
文本预览
相关文档 最新文档