基于avr的ds18b20程序
第一篇:基于avr的ds18b20程序
基于AVR的DS18b20程序
//说明:单片机ATmega16的18B20程序。调这个18B20程序问题主要出现在延时部分,即单片机实际输出的延时与设定不符。//后面为别人精确延时,我用自己的单片机通过示波器重新测量实际延时。建议调延时用示波器先看看。我用的晶振12M,但延时根本就与理论不符。其中480us的延时要在480us与960us之间,选取550us比较合适,一般都这么选。 最后一句话:DS18B20的程序很多,模块基本相似,调不出来就是因为延时问题,示波器是必备工具,否则很盲目。
#include
#define uchar unsigned char
#define uchar unsigned char
#define uint unsigned int
//------------------------//
//.....18B20........
void init_1820(void)
{
int Flag_1820Error;
uchar i;
uint j=0;
PORTD|=(1<<7);//PORTC|=(1<<7);
PORTD&=~(1<<7);//PORTC&=~(1<<7);
for(i=0;i<8;i++)delay(180);//delay_60us();//480us以上
PORTD|=(1<<7);//PORTC|=(1<<7);
DDRD&=~(1<<7);//DDRC&=~(1<<7);//
delay(40);//delay_15us();//15~60us
delay(40);//delay_15us();
Flag_1820Error=0;
while(PIND&(1<<7)
{ delay(180);//delay_60us();
j++;
if(j>=18000){Flag_1820Error=1;break;}
}
DDRD|=(1<<7);//DDRC|=(1<<7);//PORTC7 is OUTPUT
PORTD|=(1<<7);//PORTC|=(1<<7);
for(i=0;i<4;i++)delay(180);//delay_60us(); //240us
}
/********************************/
/********************************/
void write_1820(uchar x)
{
uchar m;
for(m=0;m<8;m++)
{
if(x&(1<
{
PORTD&=~(1<<7);//PORTC&=~(1<<7);delay_5us(); //5usPORTD|=(1<<7);//PORTC|=(1<<7); //write"1"delay(40);//delay_15us(); //15~45usdelay(40);//delay_15us();delay(40);//delay_15us();
}
else
{
PORTD&=~(1<<7);//PORTC&=~(1<<7);delay_15us();//15us
delay(40);//delay_15us(); //write"0"delay(40); //delay_15us(); //15~45usdelay(40);//delay_15us();
PORTD|=(1<<7);//PORTC|=(1<<7);
}
PORTD|=(1<<7);// PORTC|=(1<<7);
}
/*******************************/
uchar read_1820(void)
{
uchar temp,k,n;
temp=0;
for(n=0;n<8;n++)
{
PORTD&=~(1<<7);//PORTC&=~(1<<7);
delay(13);//delay_5us();
PORTD|=(1<<7);//PORTC|=(1<<7);
delay(13);//delay_5us();
DDRD&=~(1<<7);//DDRC&=~(1<<7);//"PINC7 is INPUT"k=(PIND&(1<<7));//k=(PINC&(1<<7)); //读数据,从低位开始if(k)
temp|=(1<
else
temp&=~(1<
delay(40);//delay_15us();//45us
delay(40);//delay_15us(); delay(40);//delay_15us();
DDRD|=(1<<7);//DDRC|=(1<<7);//
}
return (temp);
}
/*************************************/
float read_temperature(void)
{
float temp;////////////
uchar teml=0,temh=0;
unsigned long t=0;
init_1820();//复位18b20write_1820(0xcc);// 发出转换命令write_1820(0x44);
//Delay_nms(100);
init_1820();
write_1820(0xcc);//发出读命令write_1820(0xbe);
teml=read_1820();//读数据byte1temh=read_1820();//byte2
t=temh;
t=t<<8; t=t|teml; temp=t*0.0625*260/286; return(temp); /*if(temh&0xf8)sign=0; else sign=1; if(sign==0){temh=255-temh;teml=255-teml;}temh=temh<<4;
temh|=(teml&0xf0)>>4;
}
//再在主程序中调用一下read_temperature(void),读取温度。 teml=teml&0x0f; teml=(teml*10)/16; tempval=temh;e[0]=tempval/100; tempval=temh;e[1]=(tempval/10)%10; tempval=temh;e[2]=tempval%10; tempval=teml;e[3]=tempval;*/
第二篇:DS18B20学习总结
及其高精度温度测量的实现
1.1 DS18B20简介
DS18B20是美国DALLAS半导体公司生产的可组网数字式温度传感器. 主要由三个数据部件组成:64的激光ROM,温度灵敏原件,非易失性温度告警触发器TH和TL。 封装如图一:
图一 1.
2DS18B20的特点:
1. 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
2. DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现多点测温。 3. DS18B20在使用中不需要任何外围元件。
4. 测温范围-55℃~+125℃,固有测温分辨率0.5℃。 5. 测量结果以9位数字量方式串行传送。
内部结构框图如图二所示。
图二
2.1 访问温度计的协议:
(一)初始化
(二)ROM操作命令
(三)存贮器操作命令
(四)处理/数据
由热敏原件中晶振特性计算出所测的温度。 注意:复位操作如下图三
图三 必需要给DS18B20输入脉冲激活其复位功能。
DS18B20的驱动程序:
/*************************此部分为18B20的驱动程序*************************************/
#include #include sbit D18B20=P3^7; sbit error=P3^4; #define NOP() _nop_() /* 定义空指令 */ #define _Nop() _nop_() /*定义空指令*/ void TempDelay (unsigned char idata us); void Init18b20 (void); void WriteByte (unsigned char idata wr); //单字节写入 void read_bytes (unsigned char idata j); unsigned char CRC (unsigned char j); void GemTemp (void); void Config18b20 (void); void ReadID (void); void TemperatuerResult(void); bit flag; unsigned int idata Temperature; unsigned char idata temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节 unsigned char idata id_buff[8];
unsigned char idata crc_data; unsigned char code CrcTable [256]={ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
void GetTemp() {
if(TIM==100)
{ TIM=0;
TemperatuerResult();
每隔 1000ms 读取温度。
void TemperatuerResult(void) {
p = id_buff;
ReadID();
//先确定是第几个DS18B20
Config18b20(); //配置DS18B20的报警温度和分辨度
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0x44);
//Temperature convert
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0xbe);
//read Temperature
p = temp_buff;
GemTemp(); //读取温度
}
void GemTemp (void) {
read_bytes (9);
if (CRC(9)==0) //校验正确
{
Temperature = temp_buff[1]*0x100 + temp_buff[0]; //
Temperature *= 0.0625;
Temperature /= 16;
TempDelay(1);
} } *Function:CRC校验 *parameter: *Return: *Modify: *************************************************************/ unsigned char CRC (unsigned char j) {
unsigned char idata i,crc_data=0;
for(i=0;i
crc_data = CrcTable[crc_data^temp_buff[i]];
return (crc_data); }
/************************************************************ *Function:向18B20写入一个字节 *parameter: *Return: *Modify:
void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //
5 _nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************ *Function:读18B20的一个字节 *parameter: *Return: *Modify: *************************************************************/ unsigned char ReadByte (void)
//读取单字节
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); } /************************************************************ *Function:读18B20 *parameter: *Return: *Modify: *************************************************************/ void read_bytes (unsigned char idata j) {
unsigned char idata i;
for(i=0;i
{
*p = ReadByte();
p++;
} } /************************************************************ *Function:延时处理 *parameter: *Return: *Modify: *************************************************************/ void TempDelay (unsigned char idata us) {
while(us--); } /************************************************************ *Function:18B20初始化 *parameter: *Return: *Modify: *************************************************************/ void Init18b20 (void) {
D18B20=1;
_nop_();
D18B20=0;
TempDelay(80);
//delay 530 uS//80
_nop_();
D18B20=1;
TempDelay(14);
//delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
{flag = 1; error=0; }
//detect 1820 success!
else
{flag = 0; error=1; }
//detect 1820 fail!
TempDelay(20);
//20
_nop_();
_nop_();
D18B20 = 1; }
/************************************************************
向18B20写入一个字节 *parameter: *Return: *Modify: *************************************************************/ void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //5
_nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************
读18B20的一个字节
*/ unsigned char ReadByte (void)
//读取单字节 {
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); }
/************************************************************ 3.1.2
SPI数据线配置。
/*************************此部分为74HC595的驱动程序使用SPI总线连接*************************************/
#include #include
#define NOP()
_nop_()
/* 定义空指令 */ #define _Nop() _nop_()
/*?定义空指令*/ void HC595SendData(unsigned int SendVal);
//SPI IO sbit
MOSIO =P1^5; sbit
R_CLK =P1^6; sbit
S_CLK =P1^7; sbit
IN_PL =P3^4;
//74HC165 shift load
把数据加载到锁存器中 sbit
IN_Dat=P3^5;
//74HC165 output
数据移出 sbit
OE
=P3^6;
/********************************************************************************************************* ** 函数名称: HC595SendData ** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/ void HC595SendData(unsigned int SendVal) {
unsigned char i;
for(i=0;i<16;i++)
{
if((SendVal<
else MOSIO=0;
S_CLK=0;
NOP();
NOP();
S_CLK=1;
}
R_CLK=0; //set dataline low
NOP();
NOP();
R_CLK=1; //片选
OE=0; }
3.1.
3试验数码管上显示温度
#include extern GetTemp();
//声明引用外部函数 extern unsigned int idata Temperature;
// 声明引用外部变量 void delay(unsigned int i);
sbit
LS138A=P2^2;
//管脚定义 sbit
LS138B=P2^3; sbit
LS138C=P2^4;
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned long LedOut[5],LedNumVal; void system_Ini() {
TMOD|= 0x11;
TH1 = 0xD8;
//10
TL1 = 0xF0;
IE = 0x8A;
TR1 = 1 main() { unsigned char i;
system_Ini();
while(1)
{
GetTemp();
/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature;
//把实际温度送到LedNumVal变量中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10];
//个位
for(i=0; i<4; i++)
{
P0 = LedOut[i] ;
switch(i)
{
//138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}
delay(100);
}
P0 = 0;
} }
//延时程序
void delay(unsigned int i) {
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--); } 4.1 讨论DS18B20的自动报警功能实现。
DS18B20只是一个测温元件,所谓的报警功能要通过程序由单片机来实现。
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,头2个字节包含测得的温度信息,第3和第4字节TH(报警温度上限)和TL(报警温度下限)的拷贝。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。第
6、
7、8字节保留未用。要实现报警,完成温度转换后,就把测得的温度值与RAM中的TH、TL字节内容作比较(当然要自己编程序)。若T>TH或T
第三篇:数字温度传感器DS18B20控制接口设计
摘 要: DS18B20是一款经典的单总线数字温度传感器芯片,较传统的温度传感器具有结构简单、体积小、功耗小、抗干扰能力强、使用简单、可组网实现多点温度测量等优点。本设计简要介绍了数字温度传感器DS18B20 的特性及工作原理,着重论述了用FPGA实现对此传感器的控制,并将测到的温度在LED数码管上显示出来。
关键词:DS18B20;温度传感器;FPGA;LED数码管
Abstract: DS18B20 is a classic single-bus digital temperature sensor chip, the more traditional temperature sensor has a simple structure, small size, low power consumption, and anti-interference ability, easy to use networking to achieve multi-point temperature measurement. The design brief describes the features and working principle of the digital temperature sensor DS18B20, focuses on the control of this sensor using FPGA, and the measured temperature is displayed on the LED digital tube. Keywords: DS18B20; temperature sensor; FPGA; LED digital tube
1 引言
传统的温度传感器系统大都采用放大、调理、A/ D 转换, 转换后的数字信号送入计算机处理, 处理电路复杂、可靠性相对较差, 占用计算机的资源较多。DS18B20 是一线制数字温度传感器, 它可将温度信号直接转换成串行数字信号送给微处理器, 电路简单, 成本低, 每一只DS18B20 内部的ROM 存储器都有唯一的64位系列号, 在1 根地址/ 信号线上可以挂接多个DS18B20, 易于扩展, 便于 组网和多点测量。
随着科技的发展 ,温度的实时显示系统应用越来越广泛 ,比如空调遥控器上当前室温的显示、热水器温度的显示等等。实现温度的实时采集与显示系统有很多种解决方案 ,本文使用全数字温度传感器DS18B20来实现温度的实时采集FPGA作为控制中心与数据桥梁;LED数码管作为温度实时显示器件。其中DS18B20作为FPGA的外部信号源,把所采集到的温度转换为数字信号,通过接口 (113脚)传给FPGA,FPGA启动ROM内的控制程序驱动LED数码管,通过IO口和数据线把数据传送给LED数码管,将采集到的温度实时显示出来。该设计结构简单、测温准确,成本低,工作稳定可靠,具有一定的实际应用价值。
2 DS18B20数字温度传感器介绍
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。DS18B20的性能特点如下:
2.1 DS18B20的性能特点
1独特的单线接口仅需要一个端口引脚进行通信; ○2多个DS18B20可以并联在惟一的三线上,实现多点组网功能; ○3无须外部器件; ○4可通过数据线供电,电压范围为3.0~5.5V; ○5零待机功耗; ○6温度以9或12位数字; ○7用户可定义报警设置; ○8报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件; ○9负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作;○ 2.2 DS18B20的内部结构图
DS18B20采用3脚PR-35封装或8脚SOIC封装,其内部结构框图如图2-1所示。
图2-1 DS18B20内部结构框图 图2-2 DS18B20字节定义
64位ROM的结构开始8位是产品类型的编号,接着是每个器件的惟一的序号,共有48位,最后8位是前面56位的CRC检验码,这也是多个DS18B20可以采用一线进行通信的原因。温度报警触发器TH和TL,可通过软件写入户报警上下限。DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,结构如图2-2所示。头2个字节包含测得的温度信息,第3和第4字节TH和TL的拷贝,是易失的,每次上电复位时被刷新。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。DS18B20工作时寄存器中的分辨率转换为相应精度的温度数值。该字节各位的定义如图3-4所示。低5位一直为1,TM是工作模式位,用于设置DS18B20在工作模式还是在测试模式,DS18B20出厂时该位被设置为0,用户要去改动,R1和R0决定温度转换的精度位数,来设置分率。 2.3 DS18B20测温原理
DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一个频率稳定的计数脉冲。
高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。 初始时,计数器1预置的是与-55℃相对应的一个预置值。以后计数器1每一个循环的预置数都由斜率累加器提供。为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。
DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±1/2LSB,即0.25℃。
温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。
DS18B20测量温度时使用特有的温度测量技术。DS18B20内部的低温度系数振荡器能产生稳定的频率信号;同样的,高温度系数振荡器则将被测温度转换成频率信号。当计数门打开时,DS18B20进行计数,计数门开通时间由高温度系数振荡器决定。芯片内部还有斜率累加器,可对频率的非线性度加以补偿。测量结果存入温度寄存器中。一般情况下的温度值应该为9位,但因符号位扩展成高8位,所以最后以16位补码形式读出。 2.4 DS18B20供电方式
DS18B20有两种供电方式,一种是寄生电源强上拉供电方式,一种是外部供电方式,如下图:
图2-3 寄生电源强上拉供电方式电路图
在寄生电源供电方式下,DS18B20 从单线信号线上汲取能量:在信号线 DQ 处于高电平期间把能量储存在内部电容里,在信号线处于低电平期间消耗电容上的电能工作,直到高电平到来再给寄生电源(电容)充电。为了使 DS18B20 在动态转换周期中获得足够的电流供应,当进行温度转换或拷贝到 E2 存储器操作时,用 MOSFET 把 I/O 线直接拉到 VCC 就可提供足够的电流,在发出任何涉及到拷贝到 E2 存储器或启动温度转换的指令后,必须在最多 10μS 内把 I/O 线转换到强上拉状态。在强上拉方式下可以解决电流供应不走的问题,因此也适合于多点测温应用,缺点就是要多占用一根 I/O 口线进行强上拉切换。
图2-4 外部电源供电方式电路图
在外部电源供电方式下,DS18B20 工作电源由 VDD 引脚接入,此时 I/O 线不需要强上拉,不存在电源电流不足的问题,可以保证转换精度,同时在总线上理论可以挂接任意多个 DS18B20 传感器,组成多点测温系统。在外部供电的方式下,DS18B20的GND引脚不能悬空,否则不能转换温度,读取的温度总是 85℃。 3 设计需求
1温度测量范围:-55℃~+125℃ ○2可编程为9位~12位A/D转换精度 ○3测温分辨率可达0.0625℃ ○4 LED数码管直读显示 ○4 设计方案
4.1 硬件设计
将[DF2C8]FPGA 核心板和[EB-F2]基础实验板连接在一起,同时使能DS18B20 模块和数码管模块:数码管使能:用“短路帽”将实验板上的JP4和JP5全部短接。DS18B20 温度传感器使能跳线JP10 全部短接,元件安装示意如下图4-1和4-2(注意方向,半圆形的一边朝板子内部,平面朝外,和板上的图示一致)。
图 4-1:数码管使能图示 图 4-2:温度传感器安装和使能图示
4.1.1 温度传感器 DS18B20 电路
基础实验板上提供了一个由DS18B20构成的温度测量模块,其原理如图4-3所示。该电路选择外部供电方式。外部电源供电方式工作稳定可靠, 抗干扰能力强。
图4-3 单线制温度传感器 DS18B20 电路图
DS18B20与[DF2C8]FPGA核心板的连接关系如表4-1所示
表 4-1:DS18B20与[DF2C8]FPGA核心板连接时的管脚对应关系
4.1.2 数码管显示电路
基础实验板上具有2个共阳极的位七段数码管,构成8位构,其电路如图4-4 所示。
图 4-4:七段数码管显示电路图
数码管的控制引脚由两个跳线JP4和JP5使能(如图4-1所示) R10~R17是段码上的限流电阻,位码由于电流较大,采用了PNP三极管驱动。当位码驱动信号为低电平(0)时,对应的数码管才能操作;当段码驱动信号为低电平(0)时,对应的段码点亮。数码管不核心板连接时的管脚对应如表4-2所示:
表 4-2:数码管与[DF2C8]FPGA核心板连接时的管脚对应关系
4.2 HDL编码 4.2.1 时序
(1)复位: 使用DS18B20 时, 首先需将其复位, 然后才能执行其它命令。复位时, 主机将数据线拉为低电平并保持480Ls~ 960Ls, 然后释放数据线, 再由上拉电阻将数据线拉高15~ 60Ls, 等待DS18B20 发出存在脉冲, 存在脉冲有效时间为60~ 240Ls, 这样, 就完成了复位操作。其复位时序如图4-5所示。
图4-5:初始化时序
图4-6:写时序
(2)写时隙: 在主机对DS18B20 写数据时, 先将数据线置为高电平, 再变为低电平, 该低电平应大于1us。在数据线变为低电平后15us 内, 根据写“1”或写“0” 使数据线变高或继续为低。DS18B20 将在数据线变成低电平后15us~ 60us 内对数据线进行采样。要求写入DS18B20 的数据持续时间应大于60us 而小于120us, 两次写数据之间的时间间隔应大于1us。写时隙的时序如图4-6 所示
(3)读时隙 :当主机从DS18B20 读数据时, 主机先将数据线置为高电平, 再变为低电平, 该低电平应大于1us, 然后释放数据线, 使其变为高电平。DS18B20 在数据线从高电平变为低电平的15us 内将数据送到数据线上。主机可在15us 后读取数据线。读时隙的时序如图4-7 所示。
图4-7 :读时隙
4.2.2 DS18B20 的操作命令
主机可通过一线端口对DS18B20 进行操作, 其步骤为: 复位( 初始化命令) -> ROM 功能命令-> 存储器功能命令-> 执行/ 数据, DS18B20 的ROM 命令有5个( 见表1) , 存储器命令有6个( 见表2) 。命令的执行都是由复位、多个读时隙和写时隙基本时序单元组成。因此, 只要将复位、读时隙、写时隙的时序了解清楚, 使用DS18B20 就比较容易了, 时序如上文所述。
表4-3: 存储器命令操作表 表4-4:ROM命令功能操作表
4.2.3 Verilog HDL编码
详细Verilog HDL代码参见工程文件:DF2C8_13_DS18B20 工程文件中含有三个v 文件,LED_CTL.v 是数码管显示功能模块,DS18B20_CTL.v 是温度传感器的控制模块,TEMP.v 为顶层模块,实例化了前面两个模块,并将采集的温度值送至数码管中进行显示。其中最主要的温度传感器的控制模块,DS18B20_CTL.v。该程序对DS18B20 进行控制, 不仅可以简化程序, 还可以缩短1 次温度转换所需的时间. 这样的话, 1 次温度转换和数字温度值输出循环所涉及到的控制命令、数据交换和所需时隙如图4-8所示。
.
图4-8:1次温度转换的控制命令和时隙
5 仿真测试结果
5.1 仿真波形
温度测量模块仿真结果如图6-1所示:
图5-1:仿真波形
5.2 结果显示
下载配置文件后,可在数码管上观察到带一位小数的温度数值。如果用手捏住传感器,会发现显示的温度在升高。如下图:
图5-2 测温效果图示
参考文献:
[1] 沙占友 集成传感器的应用[M]. 中国电力出版社. [2] 罗钧,童景琳. 智能传感器数据采集与信号处理[M]. 化学工业出版社
[3] 周月霞,孙传友. DS18B20硬件连接及软件编程[J]. 传感器世界,2001,12. [4] 王晓娟,张海燕,梁延兴.基于DS18B20的温度实时采集与显示系统的设计与实现[J]. , 2007:38-41. [5] 党 峰, 王敬农, 高国旺. 基于DS18B20 的数字式温度计的实现[ J] . 山西电子技术, 2007( 3) [6] 金伟正. 单线数字温度传感器的原理与应用[ J] . 仪表技术与传感器, 2000( 7) : 42- 43. [7]DS18B20 Datasheet [ EB/ OL] . Dalla s: Dallas Semico nductor Cor po r atio n, 2005.
第四篇:基于AVR单片机的嵌入式系统的应用分析
关键字:AVR单片机 嵌入式系统
引言
随着技术的发展,嵌入式系统的设计及应用对人们的生活产生了很大的影响,并将逐渐改变人们未来的生活方式,在特定的操作系统上开发应用程序,可以使开发人员忽略掉很多底层硬件细节,使得应用程序调试更方便、易于维护、开发周期缩短并且降低开发成本,因而嵌入式操作系统深得开发人员的青睐。
AVR微处理器是Atmel公司开发的8位嵌入式RISC处理器,它具有高性能、高保密性、低功耗、非易失性等优点,而且程序存储器和数据存储器可独立编址,并具有独立访问的哈佛结构。AVR单片机内核有丰富的指令集,通过32个通用寄存器直接与逻辑运算单元相连接,允许在一个周期内一条单一指令访问两个独立的寄存器,这样的结构使代码的执行效率比传统的复杂指令集微处理器快了将近10倍。
AVRX是由1barello编写的源码公开的嵌入式操作系统,它专门针对AVR系列单片机的RTOS,具有免费和可以修改的特点,它的缺点是由于做为一种专用的操作系统很难移植到其他平台上。
1 AVRX 系统的特点
AVRX做为AVR专用RTOS有如下的特点:
◆ 完全支持占先式、优先级驱动的任务调度算法;
◆ 16个优先级,相同的优先级的任务采用Round robin调度算法轮流执行; ◆ 信号量可以用于信号传递、同步和互斥信号量,支持阻塞和非阻塞语法;
◆ 任务之间可以用消息队列相互传递信息,接收和确认消息可以用阻塞和非阻塞调用; ◆ 在中断子程序中,大部分非阻塞的中断服务程序可以使用;
◆ 支持单个定时器的时间队列管理,任何进程都可以设置一个定时器,并且任何一个任务都可以等待定时器时间到;
◆ 支持单步调式运行着的进程;
◆ 程序空间小,包含所有功能的版本占用1000字节;
◆ 与定时器/计算器有关的一些事务可以用AVRX写成任务级代码。 1.1 任务
AVRX2.6为了支持C语言,保存了所有的32个寄存器,最小的上下文是32个寄存器、SREG和PC,总共35个字节。AvrXInitTask()函数给所有的寄存器初始化为0x00;只有进程上下文保存在任务堆栈中,所有其他的使用(包括内核和中断)保存在内核堆栈。这样降低了第一个中断的上下文切换和进入内核API的SRAM消耗。随后的中断(如果允许中断嵌套)嵌入内核堆栈,API不进行上下文切换。 1.2 信号量
信号量是SRAM指针,它们有三中状态:PEND、WAITING和DONE。当一个进程被一个信号量阻塞时,它处于WAITING状态,多个任务可以排队等候一个信号量。在后一种情况下,信号量可以看作互斥信号量。提供的API函数如下:AvrXSetSemaphore、AvrXIntSetSemaphore、AvrXWaitSemaphore、AvrXtestSemaphore、AvrXIntTestSemaphore和AvrXResetSemaphore。 1.3 定时器
定时器控制块(TCB)长度为4(或6)个字节。它们管理一个16位计数值。定时器队列管理器管理一个分类的定时器队列,每个都调整为所有计数器的和到其延时需要的值。提供的API函数如下:AvrXStartTimer、AvrXTimerHandler、AvrXCancelTimer、AvrXWaitTimer、AvrXTestTimer和AvrXDelay。 1.4 消息队列
消息队列用消息控制块(MCB)做为队列首地址。任何进程、中断处理函数和多个进程都可以等待消息。MCB的长度是2或4个字节。消息可以认为是灵活性更大的信号量。提供的API函数如下:AvrXSendMessage、AvrXIntSendMessage、AvrXRecvMessage、AvrXWaitMessage、AvrXAckMessage、AvrXTestMessage和AvrXWaitMessageAck。 1.5 单步运行支持
通过重新汇编内核AVRX,可以允许和禁止单步运行的支持。单步运行可以通过编译内核库时定义下面的变量:#define SIGNALSTEPSUPPORT。
在能够单步运行以前,进程必须先暂停。有两种方法实现:一是仅仅初始化进程但不使能;二是用目标进程的ID调用AvrXSuspend,一旦目标进程挂起,调试SPI就能使用了,提供的API函数有:AvrXStepNext和AvrXSingleStepNext。 1.6 系统对象
AVRX是围绕系统对象的概念而构建的,系统对象包括一个链接和其后面的0个或者若干个字节的数据信号量。进程对象可以根据运行队列和信号量排队。计数器控制块只能根据计数器队列排队。消息控制块只能在消息队列排队。进程根据嵌入对象的信号量等待这些对象。
进程堆栈中可用的SRAM是限制系统规模的主要因素,每个进程都需要至少10~35字节的空间来存储进程上下文。提供的API函数如下:AvrXSetObjectSamaphore、AvrXIntObjectSamaphore、AvrXResetObjectSamaphore、AvrXWaitObjectSamaphore、AvrXTestObjectSamaphore和AvrXIntTestObjectSamaphore。 1.7 系统堆栈
AVRX需要足够大的堆栈来处理所有可能的中断嵌套,每次进入内核将会把10~35字节压进堆栈(标准上下文和返回地址),中断处理可能压进去更多。AVRX的API会临时压入2个以上的字节。GCC或者汇编代码定义于SRAM的顶部,保证AVRX的堆栈在有效SRAM空间之内是设计者的工作。 2 AVRX系统的应用
2.1 AVRX在不同型号AVR单片机上的移植
下面以ATmega16为例,介绍移植工作。 (1)编译器的选择
由于AVRX的编者是在GNU推出的AVR-GCC编译器下编写的,所以选用AVR-GCC编译器可以大大提高AVRX在不同AVR单片机上的移植特性。 (2)重新编译AVRX内核
为了将应用程序成功编译,需要重新编译AVRX内核,重新编译包括下述步骤。
① 新修改AVRX源码的Makefile文件,需要修改的几处如下 ABSPATH=„/avrx /*更改AVRX原路径到实际路径下*/ 修改
MCU=8535
AAVRMCU=1
GCCMCU=at90s$(MCU)
AVRXMCU=_AT90S$(MCU)_ 为
ICCMCU=m16
AAVRMCU=3
GCCMCU=atmega16
AVRXMCU=_AT90Mega16_
②重新修改AVRX源码的serialio.s文件,即根据不同的单片机修改串口部分的寄存器定义。需要增添如下代码:
#if defined(UBRRL)
#define UBRR UBRRL
#endif
#if defined(UBRRH)
sts UBRRH,p1h
#endif
③重新编译内核。具体做法是复制一个“令名提示符”到AVRX目录下,运行“命令提示符”,键入“makegcc”命令后运行就完成了AVRX内核的重新编译,会生成很多的.o文件和avrx.a文件。这些文件在以后的应用程序中会使用。
至此就完成了AVRX在ATmega16单片机上的内核移植,接着就可以编写应用程序了。 2.2 在AVRX上编写应用程序
这时候要用一个新的makefile文件,同时自己的程序可以不和AVRX的内核在一个目录,但是要指出依赖文件的明确路径。makefile的框架可以采用Winavr的sample文件夹下的makefile文件框架,这里的难点其实还是makefile文件的语法问题。下面介绍应用程序的makefile文件在实例中需要修改或增加的代码: MCU=atmega16 /*微处理器的名字*/ TARGET=test /*应用程序文件名*/ GCCLIB=$(AVRX)/avrx/avrx.a GCCINC=-L-I$(AVRX)/avrx-I$(AVR)/avr/inc /*加上相关的库*/ SCANF_LIB_MIN=-W1,-u,vfscanf-1scanf_min SCANF_LIB_FLOAT=-W1,-u,vfscanf-1scanf_flt SCANF_LIB /*设置sacnf函数库的类型,在不使用时可以注释掉,这样可以减小编译后的文件大小*/ LDFLAGS+=$(PRINTF_LIB)$(SCANF_LIB)$(MATH_LIB) /*新增的连接器参数设定*/ 3 系统测试
3.1 系统实时性测试
在实时系统中,实时系统的实时性表现在系统对外部事件的响应能力上,系统通过中断来响应外部事件的发生,并且在用户中断程序中做的事要尽量少,把大部分工作留给任务去做,只是通过信号量或者信息机制来通知任务运行。Mega16的定时器2设为比较匹配输出模式,在匹配时间到了之后产生一定周期脉冲输出,并产生中断。设置定时器1为计数模式来计数产生的脉冲输出。通过定时器2的比较匹配中断服务子程序来发信号量通知任务运行,并在中断子程序中不开中断,而在任务得到信号后开中断,以实现中断处理与任务运行的同步,任务中对一个全局变量计数,以记录任务执行的次数。运行一段时间后,在设置的匹配时间里,任务的运行次数和定时器1的计数一样,则系统在这段时间里是能完全响应外部事件的,当定时器2的比较匹配时间设为大于23μs时,2个计数是相等的;当小于23μs时,定时器1计数值大于任务计数值,说明任务没有完全得到响应。这说明中断的进入和返回即系统对外部时间的响应和处理时间为23μs,远远大于其他操作系统在AVR单片机上移植后的响应时间。 3.2 使用例程测试
这里只对源文件中的几个例程先进行简单的编译,然后去掉不必要的代码,加入自己想测试的一些代码,进行了定时器控制模块,信号量和消息队列以其简单组合的测试,均在ATmega16上达到了预期的效果。 4 心得体会
①AVRX的源码都是用汇编语言编写的,相对来讲代码效率很高,但是由于没有详细的API介绍文档,所以最好的入门方法就是先读懂RTOS的源码和例程,然后进行修改,再加上自己的代码逐渐熟练应用。
②AVRX需要分配的堆栈为35个字节加上任务代码需要的额外堆栈,具体的大小取决于每个进程用的本地变量个数。比较好的确定分配给任务堆栈大小的方法是:分配很大的堆栈(如70字节)运行一段应用程序后看堆栈到多深(因为GCC启动时把所有内存都清0了,这样很容易看到)。不过,为了安全起见,用编译器或仿真器在估计堆栈的顶端写入几个字节的0xFFFFF去验证到底达到了多少字节,然后分配给比测试结果多两个以上的字节给这个任务。
③启动的最后一个指令必须跳转到Epilog()。 5 结论
AVRX是一个不错的RTOS,最显著的特点就是内核小,速度快,编译后大概只需500~700字节,且基本的调度功能一个也不少。由于其代码公开,结合不同型号AVR单片机的特性,可以在此基础上进行系统的裁减和扩展,使之能达到更好的效果,本文为AVR嵌入式系统的应用提供了借鉴。
第五篇:AVR单片机C语言高级程序设计
前言 .................................................................................................................................................. 2 第1章 概述 ................................................................................................................................... 3
1.1提高编制单片机应用程序效率最好的办法是采用C语言编程 ..................................... 4 1.2 C语言具有突出的优点 ...................................................................................................... 5 1.3 AVR单片机的C编译器简介 ............................................................................................ 6 第二章AVR单片机简介及主要特性 ............................................................................................... 6
2.1 AVR单片机简介及主要特性 .......................................................................................... 6 2.2 学习开发AVR单片机用到的实验工具及器材 ............................................................. 8 第3章 AVR单片机开发软件的安装及初步使用 ...................................................................... 14
3.1 ICCAVR6.31A C语言编译器安装 ............................................................................... 14 3.2 AVR Studio集成开发环境安装 ..................................................................................... 18 3.3 PonyProg2000下载软件安装 ....................................................................................... 18 3.4 我们的第一个AVR入门程序 ....................................................................................... 19 第4章 AVR DEMO单片机综合试验板原理介绍及使用 .............................................................. 36
4.1 AVR DEMO单片机综合试验板 ........................................................................................ 36 4.2ATMEAG16L单片机的主要特点与内部组成 ................................................................... 38 4.3使用JTAGICE仿真器(JTAG ICE)调试AVR DEMO单片机综合试验板 ...................... 39
前言
世界进入21世纪后,由于电子技术及计算机技术的迅猛发展,新型电子产品的更新换代速度越来越快。以单片机为核心构成的智能化产品具有体积小、功能强、应用面广等优点,目前正以前所未见的速度取代着传统电子线路构成的经典系统,蚕食着传统数字电路与模拟电路固有的领地。
从前,汇编语言是单片机工程师进行软件开发的唯一选择,但汇编语言程序的可读性和可移植性较差,采用汇编语言编写单片机应用系统程序的周期长,而且调试和排错也比较困难。许多读者都发现,采用汇编语言设计一个大型复杂程序时,可读性较困难,往往隔一段时间再看,又要花脑力从头再来。并且不同类型的单片机,必须采用不同的汇编语言来编写,这是因为汇编语言完全依赖于单片机硬件。这样,对开发者而言,如果由于项目的变化而经常变更单片机类型,其开发的难度是可想而知的。因为对于学习一种单片机汇编语言开发,总少不了学习、探索、实践、进步这样一个过程,这个过程少则半年,多则1~2年,等你学完后再搞出产品,也许商机已消失。随着社会竞争的日益激烈,开发效率已成为商战致胜的最重要法宝之一。
为了提高编制单片机系统和应用程序的效率,改善程序的可读性和可移植性,最好的办法是采用高级语言编程。目前,C语言逐渐成为国内外开发单片机的主流语言。
C语言是一种通用的编译型结构化计算机程序设计语言,在国际上十分流行,它兼顾了多种高级语言的特点,并具备汇编语言的功能。它支持当前程序设计中广泛采用的由顶向下的结构化程序设计技术。一般的高级语言难以实现汇编语言对于计算机硬件直接进行操作(如对内存地址的操作、移位操作等)的功能,而C语言既具有一般高级语言的特点,又能直接对计算机的硬件进行操作。C语言有功能丰富的库函数、运算速度快、编译效率高,并且采用C语言编写的程序能够很容易地在不同类型的计算机之间进行移植。因此,C语言的应用范围越来越广泛,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。对汇编语言掌握到只要可以读懂程序,在时间要求比较严格的模块中进行程序的优化即可。采用C语言不必对单片机和硬件接口的结构有很深入的了解,编译器可以自动完成变量的存贮单元的分配,编程者就可以专注于应用软件部分的设计,大大加快了软件的开发速度。统计资料表明,不同单片机的C语言编译程序80%的代码是公共的,采用C语言可以很容易地进行单片机的程序移植工作,有利于产品中的单片机重新选型。C语言的编译效率也很高,对于同一个问题,用C语言编写的程序生成代码的效率仅比用汇编语言编写的程序低10%~20%,由于现在片上ROM(或FLASH ROM)空间做到32/64K字节(或更大)的单片机比比皆是,因此代码效率所差的10%~20%已经不是重要问题。至于对开发速度、软件质量、结构严谨、程序坚固等方面进行综合评述的话,则C语言的完美绝非是汇编语言编程所能比拟的。 本书以初学者为对象,从零开始,循序渐进地讲解当前最热门的AVR单片机的C语言高级程序设计,在介绍AVR单片机的各单元部分基本特性的同时,使用入门难度浅、程序长度短且又能立竿见影的初级实例,详细介绍了如何使用ATmega16L的片上资源,帮助初学者快速掌握AVR单片机的高效设计。最后3章详细介绍了3个以AVR单片机为核心的实际产品的软硬件设计。
随书所附的光盘中提供了本书的所有软件设计程序文件,读者朋友可参考。 本书的编写工作得到了中国电力出版社大力支持,出版社的资深编辑刘炽老师做了大量耐心细致的工作,使得本书得以顺利完成,在此表示衷心感谢。 由于作者水平有限,必定还存在不少缺点或漏洞,诚挚欢迎广大读者提出意见并不吝赐教。
第1章 概述
自从笔者出版了《手把手教你学单片机》(北京航空航天大学出版社出版)一书后,由于教学方式新颖独特,入门难度明显降低,结合边学边练的实训模式,很快有一大批读者入了单片机这扇门。据不完全统计,全国各地(包括港澳台地区)跟着《手把手教你学单片机》学习的读者超过30万名,其中不少读者已取得了丰硕的成果。有的读者给笔者来电说研制的“包装线控制器”已稳定运行数月,还有的读者利用单片机做“霓虹灯程序控制器”并投放市场,„„等等。总之,《手把手教你学单片机》使不少读者从传统的电子技术领域步入了微型计算机领域,进入了一个暂新的天地。
《手把手教你学单片机》一书是以汇编语言为主进行讲解实验的。所谓汇编语言就是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。汇编语言的主要优点是占用资源少、程序执行效率高。作为初学者必须基本掌握汇编语言的设计方法,因为汇编语言直接操作计算机的硬件,学习汇编语言对于了解单片机的硬件构造是有帮助的。
从前,汇编语言是单片机工程师进行软件开发的唯一选择,但汇编语言程序的可读性和可移植性较差,采用汇编语言编写单片机应用系统程序的周期长,而且调试和排错也比较困难。许多读者都发现,采用汇编语言设计一个大型复杂程序时,可读性较困难,往往隔一段时间再看,又要花脑力从头再来。更为重要的是,随着社会竞争的日益激烈,开发效率已成为商战致胜的最重要法宝之一。 大家知道,不同类型内核的单片机,其指令系统是不一样的,因此用来编写程序的汇编语言也是不一样的,这样就产生了很严重的问题。例如:我们原来是学51系列单片机的,也做过许多产品,创造出一定的经济效益。但是,忽然有一天,有客户要求用AVR单片机开发一款产品,其利益回报也相当不错,但是你怎么办呢?重新开始学AVR的汇编语言?!等到学好学熟起码要半年(有些人等到会熟练开发产品可能要一年以上的时间),客户会等不及,等半年后也许商机已消失。这只是其中的一个难题,因为现在新型的单片机层出不穷,如果你的一些客户经常拿不同的单片机要你开发设计,那你怎么办?要较好地解决这些问题,你只能采用高级语言编程了。目前在单片机中,C语言是首选的高级开发语言。
1.1提高编制单片机应用程序效率最好的办法是采用C语言编程
为了提高编制计算机系统和应用程序的效率,改善程序的可读性和可移植性,最好的办法是采用高级语言编程。目前,C语言逐渐成为国内外开发单片机的主流语言。
C语言是一种通用的编译型结构化计算机程序设计语言,在国际上十分流行,它兼顾了多种高级语言的特点,并具备汇编语言的功能。它支持当前程序设计中广泛采用的由顶向下的结构化程序设计技术。一般的高级语言难以实现汇编语言对于计算机硬件直接进行操作(如对内存地址的操作、移位操作等)的功能,而C语言既具有一般高级语言的特点,又能直接对计算机的硬件进行操作。C语言有功能丰富的库函数、运算速度快、编译效率高,并且采用C语言编写的程序能够很容易地在不同类型的计算机之间进行移植。因此,C语言的应用范围越来越广泛。
用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完备的系统。 因此,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。对汇编语言掌握到只要可以读懂程序,在时间要求比较严格的模块中进行程序的优化即可。采用C语言进行设计也不必对单片机和硬件接口的结构有很深入的了解,编译器可以自动完成变量存贮单元的分配,编程者就可以专注于应用软件部分的设计,大大加快了软件的开发速度。采用C语言可以很容易地进行单片机的程序移植工作,有利于产品中的单片机重新选型。
C语言的模块化程序结构特点,可以使程序模块大家共享,不断丰富。C语言可读性的特点,更容易使大家可以借鉴前人的开发经验,提高自己的软件设计水平。采用C语言,可针对单片机常用的接口芯片编制通用的驱动函数,可针对常用的功能模块、算法等编制相应的函数,这些函数经过归纳整理可形成专家库函数,供广大的工程技术人员和单片机爱好者使用完善,这样可大大提高国内单片机软件设计水平。
过去长时间困扰人们的“高级语言产生代码太长,运行速度太慢不适合单片机使用”的致命缺点已被大幅度地克服。目前,AVR系列单片机的C语言编译代码长度,已超过中等程序员的水平。而且,AVR系列单片机片上SRAM、FLASH空间都很大、运行速度很快,代码效率所差的10%~20%已经不是什么重要问题。关于速度优化的问题,只要有好的仿真器的帮助,用人工优化关键代码就是很简单的事了。至于谈到开发速度、软件质量、结构严谨、程序坚固等方面的话,则C语言的完美绝非是汇编语言编程所能比拟的。
1.2 C语言具有突出的优点
1. 语言简洁,使用方便灵活
C语言是现有程序设计语言中规模最小的语言之一,而小的语言体系往往能设计出较好的程序。C语言的关键字很少,ANSI C标准一共只有32个关键字,9种控制语句,压缩了一切不必要的成份。C语言的书写形式比较自由,表达方法简洁,使用一些简单的方法就可以构造出相当复杂的数据类型和程序结构。
2. 可移植性好
用过汇编语言的读者都知道,即使是功能完全相同的一种程序,对于不同的单片机,必须采用不同的汇编语言来编写。这是因为汇编语言完全依赖于单片机硬件。而现代社会中新器件的更新换代速度非常快,也许我们每年都要跟新的单片机打交道。如果每接触一种新的单片机就要学习一次新的汇编语言,那么也许我们将一事无成,因为每学一种新的汇编语言,少则几月,多则上年,那么我们还有多少时间真正用于产品开发呢?
C语言是通过编译来得到可执行代码的,统计资料表明,不同机器上的C语言编译程序80%的代码是公共的,C语言的编译程序便于移植,从而使在一种单片机上使用的C语言程序,可以不加修改或稍加修改即可方便地移植到另一种结构类型的单片机上去。这大大增强了我们使用各种单片机进行产品开发的能力。
3. 表达能力强
C语言具有丰富的数据结构类型,可以根据需要采用整型、实型、字符型、数组类型、指针类型、结构类型、联合类型、枚举类型等多种数据类型来实现各种复杂数据结构的运算。C语言还具有多种运算符,灵活使用各种运算符可以实现其他高级语言难以实现的运算。
4. 表达方式灵活
利用C语言提供的多种运算符,可以组成各种表达式,还可采用多种方法来获得表达式的值,从而使用户在程序设计中具有更大的灵活性。C语言的语法规则不太严格,程序设计的自由度比较大,程序的书写格式自由灵活。程序主要用小写字母来编写,而小写字母是比较容易阅读的,这些充分体现了C语言灵活、方便和实用的特点。
5. 可进行结构化程序设计
C语言是以函数作为程序设计的基本单位的,C 1.3 AVR单片机的C编译器简介
目前世界上几乎所有系列的单片机都支持C语言开发,开发AVR单片机的C编译器主要有:IAR Embedded Workbench(简称IAR)、Codevision AVR(简称CAVR)、Imagecraft C Compiler(简称ICC)、GNU C For AVR(简称GCCAVR)等。 IAR是瑞典IAR SYSTEMS公司开发的AVR单片机集成开发环境(IDE),包含嵌入式编译器、汇编器、连接定位器、库管理器、项目管理及调试器等。其特点是编译效率高、功能齐全,但价格昂贵。
CAVR 也是一个开发AVR单片机的集成开发环境,其界面友好,很容易上手。它带有一个叫Codewizard的代码生成器,可生成外围器件的相应初始化代码,另外,它还提供了很多常用的器件库代码,如:LCD、UART、SPI、实时时钟、温度传感器等。它的价格适中。
ICC是Imagecraft公司开发的使用标准C语言的AVR单片机集成开发环境,它有一个Application Wizard的代码生成器, 也可生成外围器件的初始化代码。其价格适中。
GCCAVR是一个公开源代码的自由软件,因此使用上时不必考虑价格因素,其缺点是没有集成开发环境(IDE),使用时麻烦一些。
本书中,我们使用ICC集成开发环境进行学习开发,ICC集成开发环境软件能够产生形式简洁、效率较高的程序代码,如果程序较大时在代码质量上可以与汇编语言程序相媲美。
第二章AVR单片机简介及主要特性
2.1 AVR单片机简介及主要特性
AVR单片机是ATMEL公司研发的增强型内置Flash的RISC(Reduced Instruction Set CPU)精简指令集高速8位单片机,设计时吸取了80C51及PIC单片机的优点,具备单时钟周期执行一条指令的能力,运行速度高达1Mips/MHz。AVR单片机可以广泛应用于计算机外部设备、工业实时控制、仪器仪表、通讯设备、家用电器等各个领域。
AVR单片机硬件结构采取8位机与16位机的折中策略,即采用局部寄存器存堆(32个寄存器文件)和单体高速输入/输出的方案(即输入捕获寄存器、输出比较匹配寄存器及相应控制逻辑),提高了指令执行速度,克服了瓶颈现象,增强了功能;同时又减少了对外设管理的开销,相对简化了硬件结构,降低了成本。AVR单片机在软/硬件开销、速度、性能和成本诸多方面取得了优化平衡,是一种高性价比的单片机。 其主要特性如下:
1.内嵌高质量的Flash程序存储器,可反复擦写,支持ISP和IAP,便于产品的调试、开发、生产、更新。内嵌长寿命的EEPROM可长期保存关键数据,避免断电丢失。片内具有大容量的RAM,有效支持使用高级语言开发系统程序。 2.高速度、低功耗,具有SLEEP(省电休眠)功能。每一指令执行速度可达50ns(20MHz),而耗电则在1mA~2.5mA之间(典型功耗,WDT 关闭时为100nA),AVR运用Harvard结构概念(具有预取指令功能),即对程序存储和数据带有不同的存储器和总线当执行某一指令时, 下一指令被预先从程序存储器中取出, 这使得指令可以在每一个时钟周期内被执行。AVR单片机可宽电压运行(2.7~5.5V),抗干扰能力强,可降低一般8位机中的软件抗干扰设计工作量和硬件的使用量。
3.AVR单片机的I/O线全部带可设置的上拉电阻,并行I/O 口输入输出特性与PIC 的HI/LOW输出及三态高阻抗HI-Z 输入类同外,也可设定类同80C51系列内部拉高电阻作输入端的功能,可单独设定为输入/输出、可设定(初始)高阻输入。使得I/O口资源灵活、功能强大、可充分利用。AVR的I/O 口是真正的I/O 口, 能正确反映I/O 口的输入/输出真实情况。
4.AVR单片机片内具备多种独立的时钟分频器,分别供URAT、IIC、SPI使用。其中与8/16位定时器配合的具有多达10 位的预分频器,可通过软件设定分频系数提供多种档次的定时时间。AVR单片机中的定时器/计数器(单)可双向计数形成三角波,再与输出比较匹配寄存器配合,生成占空比可变、频率可变、相位可变方波的脉宽调制输出PWM,令人耳目一新。
5.工业级产品,具有大电流10~20mA 或40mA(单一输出),可直接驱动SSR 或继电器。内置的看门狗定时器(WDT)用于防止程序跑飞,提高产品的抗干扰能力。
6.超功能精简指令。具有32 个通用工作寄存器(相当于80C51单片机中的32个累加器), 克服了单一累加器在数据处理时造成的瓶颈现象。
7.AVR单片机内有模拟比较器,I/O 口可作A/D 转换用, 可组成廉价的A/D 转换器。
8.像80C51一样,AVR有多个固定中断向量入口地址,因此可快速响应中断,而不会像PIC一样所有中断都在同一向量地址,需要以程序判别后才可响应。 9.AVR单片机有自动上电复位电路、独立的看门狗电路、低电压检测电路BOD,多个复位源(自动上下电复位、外部复位、看门狗复位、BOD复位),可设置的启动后延时运行程序,增强了系统的可靠性。
10.有串行异步通讯UART,不占用定时器和SPI 传输功能,因其速度高,故可以工作在一般标准整数频率,而波特率可达576K。 11.有多通道10 位A/D转换器及实时时钟RTC。
AVR单片机技术表现出单片机集多种器件(包括FLASH程序存储器、看门狗、EEPROM、同/异步串行口、TWI、SPI、A/D模数转换器、定时器/计数器等)和多种功能(增强可靠性的复位系统、降低功耗抗干扰的休眠模式、品种多门类全的中断系统、具输入捕获和比较匹配输出等多样化功能的定时器/计数器、具替换功能的I/O端口„„)于一身,充分体现了现代单片机技术向“片上系统SoC”过渡及发展的方向。
2.2 学习开发AVR单片机用到的实验工具及器材
学习一种新的单片机技术,实验与实践是必不可少的,否则只能是纸上谈兵。这里我们使用以下的器材进行AVR单片机的C语言设计。 1. ImageCraft公司的ICCAVR6.31A C语言编译器。 2. Atmel公司的AVR Studio集成开发环境。 3. PonyProg2000下载软件。 4. AVR DEMO单片机综合试验板。 5. AVR单片机JTAG仿真器。 6. 并口下载器。
7. 5V高稳定专用稳压电源。
8.TOP2004多功能USB编程器(可选购)。 9. 一台奔腾级及以上的家用电脑(PC机)。 下面简介一下这些实验工具及器材。
2.2 学习开发AVR单片机用到的实验工具及器材
学习一种新的单片机技术,实验与实践是必不可少的,否则只能是纸上谈兵。这里我们使用以下的器材进行AVR单片机的C语言设计。 1. ImageCraft公司的ICCAVR6.31A C语言编译器。 2. Atmel公司的AVR Studio集成开发环境。 3. PonyProg2000下载软件。 4. AVR DEMO单片机综合试验板。 5. AVR单片机JTAG仿真器。 6. 并口下载器。
7. 5V高稳定专用稳压电源。
8.TOP2004多功能USB编程器(可选购)。 9. 一台奔腾级及以上的家用电脑(PC机)。 下面简介一下这些实验工具及器材。 2.2.1 ICCAVR6.31A C语言编译器 ICCAVR6.31A 是ImageCraft公司开发的用于AVR单片机的C语言编译器,是一个综合了编辑器和工程管理器的纯32位集成开发环境(IDE)。由于ICCAVR功能强大,使用简单方便,具有良好的技术支持且价格合适,故得到了广泛的应用。图2-1 为ICCAVR的工作界面。
图2-1 ICCAVR的工作界面
2.2.2 AVR Studio集成开发环境
AVR Studio是一个Atmel公司开发的集项目管理、程序汇编、程序调试、程序下载、JTAG仿真等功能于一体的集成开发环境。但AVR Studio不支持C语言编译,因此当我们用C语言开发AVR单片机时,需先用ICCAVR编写C语言并进行编译,然后使用AVR Studio打开编译生成的*.cof文件,进行程序的仿真调试。图2-2 为AVR Studio的工作界面。
图2-2 AVR Studio的工作界面 2.2.3 PonyProg2000下载软件
PonyProg2000软件主要用于AVR单片机及PIC单片机的程序下载,能在Windows95/98/ME/NT/2000/XP等操作系统上使用。对英语不好的读者,还可以使用PonyProg2000的汉化程序。图2-3 为PonyProg2000的工作界面。
图2-3 PonyProg2000的工作界面
2.2.4 AVR DEMO单片机综合试验板
AVR DEMO单片机综合试验板为多功能实验板,对入门实习特别有效,其主要功能有:
1.可做AVR单片机的输入/输出实验。 2.可做音响实验。 3.可做A/D实验。 4.可做PWM(D/A)实验。
5.八位数码管动态扫描输出及驱动。 6.八位 LED 输出指示。 7.可做IIC及SPI总线实验。 8.DS18B20温度控制实验。 9.红外遥控实验。 10.16*2液晶驱动实验。 11.128*64液晶驱动实验。
12.与PC机连接做RS232通信实验。 图2-4~2-6为AVR单片机综合试验板外型。
图2-4 AVR DEMO单片机综合试验板外型
图2-5 AVR DEMO单片机综合试验板外型(驱动16*2字符型液晶)
图2-6 AVR DEMO单片机综合试验板外型(驱动128*64图型液晶) 2.2.5 AVR单片机JTAG仿真器
为经典的AVR仿真器,支持的芯片为: ATmega128,ATmega128L,ATmega16, ATmega162,ATmega162V,ATmega165,ATmega165V,ATmega169,ATmega169V, ATmega16L,ATmega32,ATmega323,ATmega323L,ATmega32L,ATmega64, ATmega64L 。图2-7为AVR单片机JTAG仿真器外型。
图2-7 AVR单片机JTAG仿真器外型
2.2.6 并口下载器 低价、可靠、实用。支持AVR单片机及AT89S51/52单片机。下载程序时必用的工具。图2-8为并口下载器外型。
图2-8 并口下载器外型
2.2.7 TOP2004多功能USB编程器
USB接口。支持AT8
9、AT87F、AT90、ATINY、ATMEGA、SST8
9、SM、MSU、GSM9
7、i87C/LC、P8
7、W77(78)E/LE、IS89C/LV、PIC12/16/17/
18、EM78P系列单片机。27/28/29/39/49/24C/93C系列存储器。16V
8、20V
8、22V10.支持7
4、4000/4500SRAM数字电路测试。支持芯片超过2000种,适合学习、开发、手机维修、电脑BIOS烧写。图2-9为TOP2004多功能USB编程器外型。
图2-9 TOP2004多功能USB编程器外型 第3章 AVR单片机开发软件的安装及初步使用
3.1 ICCAVR6.31A C语言编译器安装
在电脑中放入配套光盘,打开ICCAVR6.31A 安装文件后进入安装界面(图3-1),安装目录可使用默认方式将其安装在C盘的icc文件夹中(图3-2)。
图3-1 打开ICCAVR6.31A 安装文件后进入安装界面
图3-2 安装在C盘的icc文件夹中
安装完成后,需进行注册才能得到无时间限制的完全版软件。注册方式如下: 1.打开ICCAVR6.31A编译器界面,单击菜单栏Help→Regist Software(图3-3),系统会提示关掉计算机的防病毒程序,单击Continue按钮进入注册界面(图3-4)。
图3-3 单击菜单栏Help→Regist Software
图3-4 单击Continue按钮进入注册界面
2.选中并复制EMail Unlock Code栏右侧框内的7组数值。 3.打开注册器,粘贴刚才复制的数值(图3-5)。
图3-5 粘贴刚才复制的数值
4.点击得到解锁码(图3-6)。复制该解锁码。
图3-6 点击得到解锁码
5.在ICCAVR6.31A编译器的注册界面的Paste(~V)the unlock code from Imagecraft’s email栏中,粘贴入解锁码(图3-7),单击License按钮后再单击OK完成注册(图3-8)。注册完成后的ICCAVR6.31A启动界面如图3-9所示,主要由菜单栏、工具栏、源文件编辑窗口、工程窗口和编译输出窗口五部分组成。
图3-7 粘贴入解锁码
图3-8 单击License按钮后再单击OK完成注册
图3-9 注册完成后的ICCAVR6.31A启动界面 3.2 AVR Studio集成开发环境安装
打开配套光盘内的AVR Studio安装文件,双击Setup.exe文件,按照提示步骤进行安装。安装结束后,会出现一个关于安装USB驱动的界面,由于我们这里不用到USB驱动的器件,只需点击Cancel关闭即可。安装完成后的AVR Studio启动界面如图3-10所示。
图3-10 AVR Studio启动界面
3.3 PonyProg2000下载软件安装
PonyProg2000软件主要用于AVR单片机及PIC单片机的程序下载,能在Windows95/98/ME/NT/2000/XP等操作系统上使用。双击配套光盘内的PonyProgV206f软件进行安装,安装过程中只需按照提示,单击Next按钮,逐步进行即可。安装完成后,还可以进行汉化,选中汉化程序包中的PonyProg2000文件(注意不要打开),然后复制,
随后打开C:/Program Files/ PonyProg2000文件夹,直接点击粘贴。当弹出对话框提示是否需替换时,点确定,原文件即成为中文版。图3-11为PonyProg2000的启动界面。
图11 PonyProg2000的启动界面
AVR单片机开发过程为: 1.设置ICCAVR。 2.建立一个工程项目。 2.输入C源文件。
3.向工程项目中添加源文件。
4.编译文件,编译通过后生成COFF/HEX文件。
5. 在AVR Studio集成开发环境中打开COFF文件,使用JTAG仿真器进行实时在线仿真或进行软件模拟仿真。
7. 使用PonyProg2000软件将HEX文件下载到单片机中。 8.应用。
3.4 我们的第一个AVR入门程序
接下来我们来做第一个AVR程序,让程序跑起来,控制AVR单片机综合试验板上的8个LED,让它们亮、灭进行闪烁。
3.4.1 设置ICCAVR 通过ICCAVR对源程序编译连接工程之前,需要对编译器属性进行设置,设置好的某些属性可保留起来作为新建工程的默认属性。
打开ICCAVR软件界面,选择Project→Option进入属性设置对话窗。共有Paths、Compiler、Target、Config Salvo四个属性标签页。
1). Paths标签页(图3-12)
在属性中设置编译器的头文件目录(Include Path(s):)和库文件目录(Library Path:)。我们使用系统默认的头文件目录和库文件目录。
图3-12 Paths标签页
由于我们不使用汇编语言进行开发,因此汇编语言包含路径(Asm Include Path(s):)空着不填。
输出文件目录(Output Directory:)空着不填,则输出文件自动存放在工程项目目录中,否则存放在用户填写的路径下。
2).Compiler标签页(图3-13)
Strict ANSI C Checkings:选中表示进行严格的C语法检查。
图3-13 Compiler标签页
Accept Extensions(C++ comments,binary constants) :选中表示接受C++风格的程序注释。
Int size enum(for backword compatibility) :选中表示可以向下兼容程序。
Optimizations栏可以选择默认设置(Default)或使能代码压缩功能(Enable code compression),对程序的编译进行优化。
Output Format栏选择格式输出。COFF格式的文件用于程序的仿真调试,HEX格式的文件可烧写入单片机。
AVR Studio Version(COFF)栏中选择Studio 4.06 and above。 3).Target标签页(图3-14)
在Device Configuration下拉列表中,选择我们所使用的单片机芯片型号,这里我们选择ATMega16。其它采用默认设置。
图3-14 Target标签页
4).Config Salvo标签页(图3-15)
采用系统默认的为不带实时操作系统(Do not use Salvo Configurator)。
图3-15 Config Salvo标签页
完成设置后,单击OK即完成ICCAVR的属性设置。如果我们在开发下一个工程项目时,使用这些已经做好的属性设置,则不必再次进行属性设置了。
3.4.2 建立一个工程项目 在我的文档中新建一个ac3-1的文件夹。
在ICCAVR软件界面中,单击Project,在弹出的下拉菜单选中New选项,屏幕显示为图3-16。在出现的Save New Project As对话框中,选择工程项目存放的路径(存放在刚才新建的ac3-1文件夹中)并输入新建工程项目的名称(这里我们取名ac3-1),单击保存按钮,系统自动初始化成三个空文件夹Files、Headers、Documents,如图3-17所示。
图3-16 新建一个工程项目
图3-17 自动初始化成三个空文件夹Files、Headers、Documents 3.4.3 输入C源文件 单击File菜单,在下拉菜单中选择New,随后在出现的Untitled-0文本文件编辑窗口中输入以下的源程序(如图3-18)。
图3-18 输入源程序
#include void delay(void) { unsigned int i,j; for(i=0;i<1000;i++) { for(j=0;j<500;j++) ; } } //============================= void main(void) { DDRB=0xff; PORTB=0xff; while(1) { PORTB=0x00; delay(); PORTB=0xff; delay(); } }
程序输入完成后,选择File,在下拉菜单中选中Save as,保存在ac3-1文件夹中,源文件名为ac3-1.c,保存后可看到源文件名由Untitled-0变为ac3-1.c。
3.4.4 向工程项目中添加源文件
选中工程项目区的File文件夹右击。在出现的下拉窗口中选择Add Files,如图3-19所示。在添加文件窗口中选择ac3-1.c源文件,鼠标单击打开按钮,这时ac3-1.c文件便加入到工程项目中(图3-20)。
图3-19 向工程项目中添加源文件
图3-20 源文件加入到工程项目中
3.4.5 编译文件
选择主菜单栏中的Project,在下拉菜单中选中Make Project,这时编译输出窗口出现源程序的编译信息,如图3-21所示。如果编译出错,会在编译输出窗口中显示出来。用户可以在源程序编辑窗口重新输入、修改源程序文件,并再次编译,直到编译通过并生成用户所需的文件。
图3-21 编译输出窗口出现源程序的编译信息
3.4.6 软件模拟仿真
打开AVR Studio集成开发环境,这时出现一个欢迎进入AVR Studio的界面(图3-22)。
图3-22 出现一个欢迎进入AVR Studio的界面
单击Open按钮,选中ac3-1.cof文件后点击打开,出现生成AVR Studio工程项目文件的界面后点保存(图3-23),然后出现选择仿真平台的界面(图3-24)。这里我们进行软件模拟仿真,Debug Platform栏中选择AVR Simulator,Device栏选择Atmega16芯片(图3-25)。点击Finish后进入仿真界面(图3-26)。
图3-23 出现生成AVR Studio工程项目文件的界面后点保存
图3-24 出现选择仿真平台的界面
图3-25 Device栏选择Atmega16芯片
图3-26 点击Finish后进入仿真界面
在主菜单中打开Debug,从Debug的下拉菜单中可看到常用的仿真快捷键,这里我们选择F10(Step Over)进行调试。
选择Debug →AVR Simulator Options,出现图3-27所示的仿真选项,我们将Frequency一项中的仿真频率改为8.00MHz,使其与试验板上的实际工作频率相符。
图3-27 选择Debug →AVR Simulator Options 在左侧Workspace窗口中,存放着ATMeag16的各种寄存器的状态值,我们将I/O ATMEGA16前的加号展开,再将PORTB前的加号展开,将PORTB输出口打开(图3-28)。鼠标在程序的光标箭头上点一下,随后按动F10,可发现PORTB口的各寄存器会发生变化,DDRB全部为黑色(0xFF),说明方向寄存器的设置为输出方式,而随着继续按动F10,PORTB与PINB则一会儿变黑(0xFF),一会儿变白(0x00)。将Workspace窗口中的Processor前的加号展开,最下面有个Stop Watch项,该项就是AVR Studio在选定时钟频率下计算出的运行时间(图3-29)。我们可发现,PORTB输出低电平到高电平的时间间隔约0.439秒,反复循环。仿真调试通过后,关闭AVR Studio开发环境。
图3-28 将PORTB输出口打开
图3-29 AVR Studio在选定时钟频率下计算出的运行时间
3.4.7 将HEX文件下载到单片机中
将并口下载器插电脑的并口,下载线的另一端插AVR DEMO单片机综合试验板的ISP口。
将试验板上标示PB0-PB7的双排针上8个短路块拔下,插到标有LED的双排针上,使PB口与LED接通。试验板通电工作,注意,5V稳压电源接DC5V插座;若使用9V-15V电源时,插9V-15V的插座。插错电源会损坏芯片!
第一次使用PonyProg2000下载程序时,需对PonyProg2000进行设置,选择合适的下载接口方式,并对端口进行校正。PonyProg2000支持串口及并口下载,这里我们采用并口SPI方式下载程序。
双击桌面上的PonyProg2000快捷图标运行软件(图3-30),出现小马头图标后点确认。
程序下载前先进行端口设置及校正。选择设置→接口设置,出现图3-31对话框。如果我们的电脑使用的操作系统是Windows 95/98/ME,单击并行,选择Avr ISP API,并选择LPT1;如果我们的电脑使用的操作系统是Windows NT/2000/XP,则单击并行,选择Avr ISP I/O,并选择LPT1。
图3-30 运行PonyProg2000软件
图3-31 进行端口设置及校正
下来选择设置→校正,对端口进行校正,出现图3-32的窗口。单击Yes开始校正,校正完成后会有提示(图3-33),点OK即可。
图3-32 单击Yes开始校正
图3-33 校正完成
选择器件→AVR micro→Atmega16(图3-34)。
图3-34 选择器件→AVR micro→Atmega16 选择文件→打开程序(FLASH)文件,文件类型选*HEX,装载编程文件(图3-35)。
图3-35 装载编程文件
选择命令→擦除,先擦除器件(图3-36)。
图3-36 选择命令→擦除
选择命令→Security and Configuration Bits„,按图3-37配置熔丝位。单击写入,写入熔丝位配置。
图3-37 写入熔丝位配置
选择命令→写入所有,开始下载烧写文件(图3-38)。
图3-38 选择命令→写入所有
在下载文件时,ISP旁的发光二极管D0会点亮。 3.4.8 应用
下载烧写完成时,我们即可看到PB口驱动的8个发光二极管开始闪亮,周期约0.8秒,即点亮0.4秒、熄灭0.4秒,反复进行。
恭喜您,您已经踏入了AVR高速单片机的大门,请您继续行动起来,掌握AVR单片机的高效设计。
第4章 AVR DEMO单片机综合试验板原理介绍及使用
4.1 AVR DEMO单片机综合试验板
AVR DEMO单片机综合试验板为多功能实验板,对入门实习及学成后开发产品特别有帮助,图4-1为AVR DEMO单片机综合试验板电路原理图(作者注:使用Protel99se打开)。
图4-1 AVR DEMO单片机综合试验板电路原理图
U1为单片机ATMEAG16L。 JP
1、JP2为双排针,便于单片机外扩其它器件。
D1-D8为8个发光二极管,通过LED双排针与PB0-PB7连接,可作开关量输出的指示。
ISP为在线下载程序的接口。 JTAG为在线JTAG仿真接口。
LCD128_64为驱动128*64图型液晶的接口,可做128*64液晶驱动实验。 LCD16_2为驱动16*2液晶的接口,可做16*2液晶驱动实验。 JTAG_R双排针连接R2-R5这4个10K的上拉电阻,这是进行JTAG仿真所需的,一般情况下用短路块将JTAG_R双排针短接。
U2为232通信芯片,通过UART双排针与单片机ATMEAG16L的PD0、PD1连接,方便与PC机连接做RS232通信实验。
SW_DIP4为4位拔码开关,它通过SW_DIP短路块与PD4-PD7连接,可做状态转换的实验。
RV1为多圈电位器,所取得的模拟电压通过排针AD后送单片机的PA7,可做A/D实验。
Q1及蜂鸣器BZ组成音响电路,通过排针BEEP与单片机的PD5连接,可做音响实验。
S1-S4为4个轻触式按键开关,通过KEY双排针与PD4-PD7连接,可做开关量的输入实验。
INT0、INT1为2个轻触式按键开关,通过INT双排针与PD
2、PD3连接,可进行AVR单片机的外部中断实验。
LEDMOD
1、LEDMOD2为8位数码管显示器,其中字段码经LEDMOD_DATA双排针后由单片机的PA0-PA7送出,位选码经LEDMOD_COM双排针后由单片机的PC0-PC7送出,可做8位数码管动态扫描输出及驱动。
U4为IIC总线实验器件24C01,通过IIC双排针与PC0、PC1连接,可做IIC总线实验。
U5为SPI总线实验器件93C46,通过SPI双排针与PB4-PB7连接,可做SPI总线实验。
U7为测温器件,通过排针18B20与PC7连接,能进行测温及控温实验。 U8为38KHz的红外接收器,通过排针IR与PD6连接,可做红外遥控实验。
U6A、U6B及外围器件组成有源滤波电路,通过双排针PWM_IN与单片机的PB
3、PD
4、PD
5、PD7连接,可做PWM(D/A)实验。
J
1、J2为外接电源插口,其中J1输入9-15V直流电压,供U6运放使用,同时经U3稳压获得的5V供其它部分使用。若实验中不需从PWM_OUT
1、PWM_OUT2端口取得PWM的模拟量,那么直接从J2口输入5V稳压电源即可,而不用J1口。
4.2ATMEAG16L单片机的主要特点与内部组成
ATMEAG16L是AVR单片机家族中的高档产品,其包含的功能较为齐全,非常适合于学习及开发实践。选择ATMEAG16L进行学习的另一个主要原因是该芯片支持JTAG调试,这样大大降低了我们在学习、开发过程中的调试难度及成本。
ATMEAG16L的主要特点为:
●内部Flash程序存储器内部含有16K字节的Flash存储器,支持ISP(在系统编程)和IAP(在应用编程),可被重复擦写10000次。
●内部数据存储器SRAM达1K字节。
●内部EEPROM达512字节,可擦写100000次,可以在系统掉电时保存一些用户信息。
●32个I/O口,分PA、PB、PC、PD共4组,每组8位。每个I/O口可负载20~40mA的电流,芯片的总电流不超过200mA。
●有两个可分频的8位定时器/计数器和一个可分频的16位定时器/计数器,带输入捕获、比较输出功能。有4个通道的PWM,可作DAC转换器。 ●中断单元有20个中断源,每个中断有独立的中断向量入口地址,所有的中断事件都有各自的使能位,可以根据需要使能或屏蔽。
●Atmega16L支持多种时钟方式, 有外部晶振、外部RC振荡、外部时钟和内部RC振荡等。Atmega16L内置上电复位电路、可编程低电压检测(BOD)复位电路和带独立振荡器的看门狗,支持上电复位、外部复位、看门狗复位和低电压检测复位等复位源。
●内置8通道10位精度的逐次逼近式模/数转换器(ADC),支持单端和双端差分信号输入,内含增益可编程运算放大器。 ●SPI同步接口。 ●全双工的USART。 ●
片内模拟比较器。 ●
二线总线(TWI)等。
图4-2为ATMEAG16L的引脚排列。图4-3为ATMEAG16L的内部组成结构。
图4-2 ATMEAG16L的引脚排列 图4-3 ATMEAG16L的内部组成结构
4.3使用JTAGICE仿真器(JTAG ICE)调试AVR DEMO单片机综合试验板
JTAG ICE与AVR DEMO单片机综合试验板连接的电路图见图4-4,图4-4中虚线的部分是可选连接。
图4-4 JTAG ICE与AVR单片机综合试验板连接的电路
当JTAGICE与用户板和个人电脑均连接上之后,就可以开始调试。 下面以第3章中所作的第一个程序ac3-1.c为例,使用JTAG ICE进行实际调试。
前5步的操作与第3章中介绍的完全相同,即: 1.设置ICCAVR。 2.建立一个工程项目。 3.输入C源文件。 4.向工程项目中添加源文件。
5.编译文件,编译通过后生成COFF/HEX文件。 仅第6步的操作不同,下面将第6步介绍一下:
需要说明的是,进行JTAG仿真前,应确定单片机的JTAGEN熔丝位已被编程,这可以用下载软件PonyProg2000进行熔丝位检查。
6.使用JTAG仿真器进行实时在线仿真
将JTAG仿真器通过串口线与PC机的串口连接,另一端的10PlN扁平电缆则插入AVR DEMO单片机综合试验板上的JTAG插口。AVR DEMO单片机综合试验板通上5V电压,然后打开AVR Studio集成开发环境,这时出现一个欢迎进入AVR Studio的界面(图4-5)。
图4-5 进入AVR Studio的界面
单击Open按钮,选中ac3-1.cof文件后点击打开,出现生成AVR Studio工程项目文件的界面后点保存,然后出现选择仿真平台的界面(图4-6)。这里我们在Debug Platform栏中选择JTAG ICE,Device栏选择Atmega16芯片(图4-7)。点击Finish后JTAG ICE会与PC机建立通信连接,进入在线仿真界面(图4-8)。
图4-6 出现选择仿真平台的界面
图4-7 Device栏选择Atmega16芯片
图4-8 进入在线仿真界面
在主菜单中打开Debug,从Debug的下拉菜单中可看到常用的仿真快捷键,这里我们选择F10(Step Over)进行调试。
在左侧Workspace窗口中,存放着ATMeag16的各种寄存器的状态值,我们将I/O ATMEGA16前的加号展开,再将PORTB前的加号展开,将PORTB输出口打开。鼠标在程序的光标箭头上点一下,随后按动F10,可发现PORTB口的各寄存器会发生变化,DDRB全部为黑色(0xFF),说明方向寄存器的设置为输出方式,而随着继续按动F10,PORTB与PINB则一会儿变黑(0xFF),一会儿变白(0x00),对应的,实验板上的发光二极管也亮、灭闪烁。当按动F5快捷键(Run)后,程序全速运行,这时实验板上的发光二极管自动闪烁。