当前位置:首页 > 单片机 > 单片机
[导读] mega162具有以下特性:1.双USART;2.低能耗,工作电压低;3.多个I/O可以当作外部中断,相比之下M16只有3个外部中断可用。当初选型mega162的时候是看中了它的双USART的功能;但是它却没集成A/D,当想要

mega162具有以下特性:1.双USART;2.低能耗,工作电压低;3.多个I/O可以当作外部中断,相比之下M16只有3个外部中断可用。

当初选型mega162的时候是看中了它的双USART的功能;但是它却没集成A/D,当想要扩展A/D功能的时候,只有外部挂接A/D芯片了;这本不是AV先生的初衷,因为许多AVR单片机集成了A/D、EEPROM。


外部A/D芯片选用TI公司的TLC1543,这是一个11通道、10位的A/D,速度38ksps,应用非常广泛,下面是根据51BBS龙版主的C源码转嫁过来的。设计主要注意以下几个方面:

1。AVR具有1指令/时钟周期的特性,同时又可以预取指令,提高了指令执行速度(1Mips/MHz);传统51是每1指令/6个时钟周期。使在同样外部晶振的条件下,ADD和DEC的执行时间,AVR比51快了6倍(这个可能不太严格,由于内核构架的不同),所以在用nop或者i++/i--做芯片时序延时的时候,要考虑时间是否够。

2。AVR的端口是可设置方向的,相对于TLC为进的端口,AVR要设置为出,反之亦然。

3。AVR的端口逻辑有专门的寄存器,比如PINA是PA口的寄存器,这个寄存器只读,当判断AVR的端口电平高低的时候,只能访问它。

下面是我的代码:由于网页原因,格式总靠左。本来我是参照“华为编程规范”做的。

/*----------------------------------------------------------------
*FileName:UPSSpyMain_AD.c-
*Description:从TLC1543读取采样值,形参port是采样的通道号-
*Project:-
*MCUtype:Mega1627.3728mhz-
-
*Company:WY-
*Compiler:ICCAVR6.30-
*MODIFY:郭准06.3.19-
-----------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
//-----------------
#defineucharunsignedchar
#defineuintunsignedint
#defineulintunsignedlongint


#definenop()NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();

//-----------------TLC1543端口定义
#defineCLOCK0//PORTC的0位
#defineD_IN1//PORTC的1位
#defineD_OUT2//PORTC的2位
#define_CS3//PORTC的3位
//-----------------端口电平变化的定义
#defineCLOCK_0PORTC&=~(1<#defineCLOCK_1PORTC|=(1<
#defineD_IN_0PORTC&=~(1<#defineD_IN_1PORTC|=(1<
#defineD_OUT_0PORTC&=~(1<#defineD_OUT_1PORTC|=(1<
#define_CS_0PORTC&=~(1<<_CS)
#define_CS_1PORTC|=(1<<_CS)

//------------------------------------------------------
//功能:从TLC1543读取采样值
//入口:channel=通道号.0:0通道;1:1通道。。。。。。。
//出口:
//设计:郭准,伟业,2006/3/19
//------------------------------------------------------
uintread1543(ucharchannel)
{
uintad;
uinti;
ucharal=0;
ucharah=0;
//----------------端口方向
PORTC=0xFF;//PC0,PC1,PC3推挽1输出;PC2I/O带上拉电阻输入
DDRC=0xFB;//

CLOCK_0;//时钟源初始为低
_CS_0;//片选为低,选中芯片
//---------------等待一个设置时间+两个内部系统时钟的下降沿
for(i=0;i<21;i++)
{;}
//---------------把通道号打入1543
channel<<=4;//左移4位的作用是为了,下面高位比较方便
al=0;ah=0;
for(i=0;i<4;i++)
{
if((channel&0x80))
{
D_IN_1;
nop();
}
else
{
D_IN_0;
nop();
}
CLOCK_1;//时钟的下降沿锁存数据,地址移入
nop();
CLOCK_0;
channel<<=1;
}

//---------------//填充6个CLOCK
for(i=0;i<6;i++)//采样一直持续6个I/OCLOCK周期
{
CLOCK_1;
nop();
CLOCK_0;
nop();
}
nop();
//---------------//等待AD转换
_CS_1;
for(i=0;i<12;i++)//多个单周期延时nop,微秒级延时
{
nop();
}
_CS_0;
nop();
//---------------//取D9,D8
for(i=0;i<2;i++)
{
//D_OUT_1;
ah<<=1;
CLOCK_1;

if(PINC&(1<{
ah|=0x01;
}

CLOCK_0;
}
//---------------//取D7--D0
for(i=0;i<8;i++)
{
al<<=1;
CLOCK_1;

if(PINC&(1<{
al|=0x01;
}
CLOCK_0;
}

_CS_1;//关闭1543
//---------------//得到AD值
ad=(uint)ah;
ad<<=8;
ad|=al;

return(ad);
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭