查看: 13790|回复: 27

补充一些IAR AVR常用的H和CPP文件

[复制链接]
发表于 2009-4-2 23:29:17 | 显示全部楼层 |阅读模式
关键词: AVR , CPP , IAR , 文件
hotpower 发表于 8/21/2007 12:23:08 AM AVR 单片机 ←返回版面

IAR AVR不错~~~

估计外星人和粉丝同志都很气愤~~~

先得罪了~~~

哈哈~~~忘了声明一下:

转帖必须注明在21ic双龙处."作者是倒塌的菜农"

这是俺做IAR AVR菜鸟的第1篇作文~~~

望各位大侠指教~~~
 楼主| 发表于 2009-4-2 23:29:48 | 显示全部楼层

Wdt.h

本帖最后由 hotpower 于 2009-4-2 23:31 编辑

wdt.h
hotpower 发表于 2007-8-21 00:23 AVR 单片机 ←返回版面 举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __IARAVR_WDT_H
#define __IARAVR_WDT_H

#ifdef __cplusplus
extern "C"
{
#endif

enum enum_WdTimeOut
{
    WDTO_15MS  =  (0 << WDP2) | (0 << WDP1) | (0 << WDP0),
    WDTO_30MS  =  (0 << WDP2) | (0 << WDP1) | (1 << WDP0),
    WDTO_60MS  =  (0 << WDP2) | (1 << WDP1) | (0 << WDP0),
    WDTO_120MS =  (0 << WDP2) | (1 << WDP1) | (1 << WDP0),
    WDTO_250MS =  (1 << WDP2) | (0 << WDP1) | (0 << WDP0),
    WDTO_500MS =  (1 << WDP2) | (0 << WDP1) | (1 << WDP0),
    WDTO_1S    =  (1 << WDP2) | (1 << WDP1) | (0 << WDP0),
    WDTO_2S    =  (1 << WDP2) | (1 << WDP1) | (1 << WDP0)
};

extern "C"  void __watchdog_enable(const char timeout);

extern "C" void __watchdog_disable(void);


#ifdef __cplusplus
}
#endif

#endif//__IARAVR_WDT_H

 楼主| 发表于 2009-4-2 23:30:48 | 显示全部楼层

wdt.cpp

本帖最后由 hotpower 于 2009-4-2 23:33 编辑

wdt.cpp
hotpower 发表于 2007-8-21 00:24 AVR 单片机 ←返回版面 举报该贴

#include "wdt.h"

extern "C" void __watchdog_write(const char value)
{
unsigned char temp;
    temp = __save_interrupt ();
    __watchdog_reset ();

    WDTCR = (1 << WDTOE) | (0 << WDE) | value;//M16
//    WDTCSR = (1 << WDCE) | (0 << WDE) | value;//M48
    __restore_interrupt (temp);
}

extern "C" void __watchdog_enable(const char timeout)
{
    __watchdog_write (timeout | (1 << WDE));
}

extern "C" void __watchdog_disable(void)
{
    __watchdog_write (0);
}
 楼主| 发表于 2009-4-2 23:33:47 | 显示全部楼层
sleep.h
hotpower 发表于 2007-8-21 00:25 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __IARAVR_SLEEP_H
#define __IARAVR_SLEEP_H

#ifdef __cplusplus
extern "C"
{
#endif

enum enum_SleepMode
{
    SLEEP_MODE_IDLE         =  (0 << SM2) | (0 << SM1) | (0 << SM0),
    SLEEP_MODE_ADC          =  (0 << SM2) | (0 << SM1) | (1 << SM0),
    SLEEP_MODE_PWR_DOWN     =  (0 << SM2) | (1 << SM1) | (0 << SM0),
    SLEEP_MODE_PWR_SAVE     =  (0 << SM2) | (1 << SM1) | (1 << SM0),
    SLEEP_MODE_STANDBY      =  (1 << SM2) | (1 << SM1) | (0 << SM0),
    SLEEP_MODE_EXT_STANDBY  =  (1 << SM2) | (1 << SM1) | (1 << SM0)
};

extern "C"  void __sleep_mode (void);
extern "C"  void __set_sleep_mode(const char sleepmode);


#ifdef __cplusplus
}
#endif

#endif//__IARAVR_SLEEP_H
 楼主| 发表于 2009-4-2 23:34:13 | 显示全部楼层
sleep.cpp
hotpower 发表于 2007-8-21 00:25 AVR 单片机 ←返回版面   举报该贴

#include "sleep.h"
extern "C"  void __set_sleep_mode(const char sleepmode)
{
    MCUCR &= ~((1 << SE) | (1 << SM2) | (1 << SM1) | (1 << SM0));
    MCUCR |= sleepmode | (1 << SE);
}

extern "C"  void __sleep_mode (void)
{
    MCUCR |= (1 << SE);
    __sleep ();
    MCUCR &= ~(1 << SE);
}
 楼主| 发表于 2009-4-2 23:34:36 | 显示全部楼层
uart.h
hotpower 发表于 2007-8-21 00:27 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __M16_UART_H
#define __M16_UART_H

#ifdef __cplusplus
extern "C"
{
#endif

class UartObj;

class UartObj {//系统串口类
public:
    UartObj(void);
    char Receive(void);
    void Transmit(const char);
    void Flush(void);
    void putchar(const char);
    void puthex(unsigned int);
    void putint(unsigned int);
    void putint(unsigned int, signed char);
    void putstr(const char []);
    void puts(const char []);
    void Exec(void);
private:
    void Init(void);
public:
//缓冲区选用最好是8的倍数,256为最偷懒最简洁最高效的做法~~~
    char ReceiveBuffer[256];
    char SendBuffer[256];
//    bool ReceiveBusy;
    unsigned char ReceiveWritePtr;
    unsigned char ReceiveReadPtr;
//    bool SendBusy;
    unsigned char SendWritePtr;
    unsigned char SendReadPtr;
};

#define Fosc 11059200 //晶振8MHZ
#define Baud 9600     //波特率

#define DDR_RXD   DDRD_Bit0
#define RXD       PORTD_Bit0
#define DDR_TXD   DDRD_Bit1
#define TXD       PORTD_Bit1

#ifdef __cplusplus
}
#endif

#endif//__M16_UART_H
 楼主| 发表于 2009-4-2 23:35:04 | 显示全部楼层
uart.cpp
hotpower 发表于 2007-8-21 00:29 AVR 单片机 ←返回版面   举报该贴

#include "uart.h"


UartObj::UartObj(void)
{
    Init();
}

void UartObj::Init(void)
{
unsigned int i;
    for (i = 0; i < sizeof(ReceiveBuffer); i ++) {
        ReceiveBuffer[i] = 0;
        SendBuffer[i] = 0;
    }
    ReceiveWritePtr = 0;
    ReceiveReadPtr = 0;
    SendWritePtr = 0;
    SendReadPtr = 0;
    DDR_TXD = 1;
    DDR_RXD = 0;
    TXD = 1;
    RXD = 1;
    UCSRA &= ~(1 << U2X);
    UCSRB = (1 << RXCIE)
          | (1 << TXCIE)
          | (0 << UDRIE)//数据寄存器空中断使能
          | (1 << RXEN) | (1 << TXEN);//允许发送和接收(中断)//
    /* 设置波特率*/
    UBRRL = ((Fosc / 16 / (Baud + 1)) % 256);//9600
    UBRRH = ((Fosc / 16 / (Baud + 1)) / 256);
//    UBRRL = 71;//9600
//    UBRRH = 0;
    UCSRC = (1 << URSEL)
          | (0 << UPM1) | (0 << UPM0)//无校验
          | (1 << USBS)//1位STOP位
          | (0 << UCSZ2) | (1 << UCSZ1) | (1 << UCSZ0);//8位数据
}

void UartObj::Transmit(const char data)
{
    /* USART 数据寄存器空,UDRE标志指出发送缓冲器(UDR)是否准备好接收新数据*/
    while (!(UCSRA & (1 << UDRE)));/* 将数据放入缓冲器,发送数据 */
    UDR = data;
}

char UartObj::Receive(void)
{
    while (!(UCSRA & (1 << RXC)));
    return UDR;
}


void UartObj::Flush(void)
{
volatile unsigned char dummy;
    while (UCSRA & (1<     {
        dummy = UDR;//读UDR会使RXC清零
    }
}


void UartObj::putchar(const char dat)
{
char ch;
/*
static char crc = 0, len = 0;
*/
    UCSRB &= ~(1 << TXCIE);
    ch = dat;
/*
    if (ch == '$')
    {
        crc = 0;//强行开始
        len = 0;
    }
    else if (ch == 0x0d)//拦截0x0d
    {
        crc ^= 0x80;//防止数据错误
        ch = crc;
    }
    else if (ch >= 0x20)//放过0x0a
    {
        crc ^= crctab[len & 0x07];//len应该小于128
        crc ^= ch;
        ch ^= passtab[len & 0x07] & 0x0f;
        len ++;
    }
*/
    SendBuffer[SendWritePtr ++] = ch;//写入发送缓冲区(并非FIFO!!!)
//    if ((!SendBusy) && (SendWritePtr == SendReadPtr) && (dat == 0x0a))
    if ((dat == 0x0a) && (!(UCSRB & (1 << UDRIE))))
    {
        UCSRB |= (1 << UDRIE);//自动触发
    }
    UCSRB |= (1 << TXCIE);
}

void UartObj::putstr(const char str[])
{
    while (*str) {
        putchar(*str);
        str++;
    }
}

void UartObj::puts(const char str[])
{
    while (*str) {
        putchar(*str);
        str++;
    }
    putchar(0x0d);
    putchar(0x0a);//回车换行
}

void UartObj::puthex(unsigned int data)
{
signed char i;
char str[5];
unsigned char val;
    for (i = 3; i >= 0; i --)
    {
        val = data & 0x0f;
        data >>= 4;
        if (val <= 9)
        {
            val += '0';
        }
        else
        {
            val += 'A' - 10;
        }
        str[i] = val;
    }
    str[4] = 0;
    putstr (str);
}

void UartObj::putint(unsigned int data)
{
signed char i;
char str[6];
unsigned char val;
    for (i = 4; i >= 0; i --)
    {
        val = data % 10;
        data /= 10;
        if ((i < 4) && (val == 0) && (data == 0))
        {
            val = ' ';
        }
        else
        {
            val += '0';
        }
        str[i] = val;
    }
    str[5] = 0;
    putstr (str);
}

void UartObj::putint(unsigned int data, signed char size)
{
signed char i;
static char str[7];
unsigned char val;
    size = 5 - size;
    for (i = 5; i >= 0; i --)
    {
        if (i == size)
        {
            if (size == 5)
            {
                val = 0;
            }
            else
            {
                val = '.';
            }
        }
        else
        {
            val = data % 10;
            data /= 10;
            if ((i < size - 1) && (val == 0) && (data == 0))
            {
                val = ' ';
            }
            else
            {
                val += '0';
            }
        }
        str[i] = val;
    }
    str[6] = '\0';
    putstr (str);
}

void UartObj::Exec(void)
{

}
 楼主| 发表于 2009-4-2 23:35:36 | 显示全部楼层
twi.h(自己参考,删了许多,否则暴露我军目标~~~)
hotpower 发表于 2007-8-21 00:33 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __IARAVR_TWI_H
#define __IARAVR_TWI_H

#ifdef __cplusplus
extern "C"
{
#endif

enum enum_TWIState
{
/* Master */
    TW_START =                0x08,
    TW_REP_START=        0x10,
/* Master Transmitter */
    TW_MT_SLA_ACK=        0x18,
    TW_MT_SLA_NACK=        0x20,
    TW_MT_DATA_ACK=        0x28,
    TW_MT_DATA_NACK=        0x30,
    TW_MT_ARB_LOST=        0x38,
/* Master Receiver */
    TW_MR_ARB_LOST=        0x38,
    TW_MR_SLA_ACK=        0x40,
    TW_MR_SLA_NACK=        0x48,
    TW_MR_DATA_ACK=        0x50,
    TW_MR_DATA_NACK=        0x58,
/* Slave Transmitter */
    TW_ST_SLA_ACK=        0xA8,
    TW_ST_ARB_LOST_SLA_ACK=    0xB0,
    TW_ST_DATA_ACK=        0xB8,
    TW_ST_DATA_NACK=        0xC0,
    TW_ST_LAST_DATA=        0xC8,
/* Slave Receiver */
    TW_SR_SLA_ACK=        0x60,
    TW_SR_ARB_LOST_SLA_ACK=    0x68,
    TW_SR_GCALL_ACK=        0x70,
    TW_SR_ARB_LOST_GCALL_ACK=   0x78,
    TW_SR_DATA_ACK=        0x80,
    TW_SR_DATA_NACK=        0x88,
    TW_SR_GCALL_DATA_ACK=    0x90,
    TW_SR_GCALL_DATA_NACK=    0x98,
    TW_SR_STOP=                0xA0,
/* Misc */
    TW_NO_INFO=                0xF8,
    TW_BUS_ERROR=        0x00,
    TW_READ=                1,
    TW_WRITE=                    0
};

#define TW_STATUS_MASK        ((1 << TWS7) | (1 << TWS6) | (1 << TWS5) | (1 << TWS4) | (1 << TWS3))
#define TW_STATUS        (TWSR & TW_STATUS_MASK)

#define DDR_SDA  DDRC_Bit0
#define DDR_SCL  DDRC_Bit1

#define SDA      PORTC_Bit0
#define SCL      PORTC_Bit1

#define UsiSlaveAddrWr    0xa0
#define UsiSlaveAddrRd    0xa1



class TwiObj;
class TwiObj {//系统通讯类
public:
    TwiObj(void);
    void Start(void);
    void RepStart(void);
    void Stop(void);
    void Exec(void);
    void WorkExec(void);
private:
    void Init(void);
    void Exit(void);
    void SetDataBuff(void);
    void SendCommand(void);
public:
    bool Succeed;
    volatile unsigned char MainCount, SubCount;
    unsigned char SubAddr, SubComm;
    unsigned int DataBuffer[8];
private:
    volatile bool Busy;
    volatile unsigned char Status;
    unsigned char Count;
    unsigned char TxBuffer[4], RxBuffer[4];
};

#ifdef __cplusplus
}
#endif

#endif//__IARAVR_TWI_H
 楼主| 发表于 2009-4-2 23:36:06 | 显示全部楼层
twi.cpp(自己参考,删了许多,否则暴露我军目标~~~)
hotpower 发表于 2007-8-21 00:39 AVR 单片机 ←返回版面   举报该贴

//注意这个例子的地址是随机加密的~~~主要是对付阶级敌人~~~

#include "twi.h"

TwiObj::TwiObj(void)
{
    Init ();
}

void TwiObj::Init(void)
{
    DDR_SDA = 0;
    DDR_SCL = 0;
    SCL = 1;//内部上拉电阻
    SDA = 1;//内部上拉电阻
    TWBR = 180;
    TWSR = 0;
    TWCR = 0;
    for (int i = 0; i < 4; i ++)
    {
        TxBuffer[i] = 0;
        RxBuffer[i] = 0;
    }
    for (int i = 0; i < 8; i ++)
    {
        DataBuffer[i] = 0;
    }
    Stop();
    Succeed = false;
}

void TwiObj::Start(void)
{
    Busy = true;
    Status = 0;//主机准备发送启始位
    Count = 0;//发送数据个数
    TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
}

void TwiObj::RepStart(void)
{
    Busy = true;
    Status = 0x55;//主机准备发送启始位
    SubAddr ^= SubComm;
    SubAddr |= 0x01;
    Count = 0;//接收数据个数
    TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
}

void TwiObj::Stop(void)
{
    Busy = false;
    Status = 0x88;//通讯成功
    TWCR = (1 << TWINT) | (1 << TWSTO);//关闭TWIE//pwy
}

void TwiObj::Exit(void)
{
    Busy = false;
    TWCR = (1 << TWINT) | (1 << TWSTO);//关闭TWIE//pwy
}

void TwiObj::Exec(void)
{
    switch(TW_STATUS)
    {
        case TW_START://主机收到自己发送的开始信号
         if (Status == 0)//本次中断应该接收TW_START信号
             {
            TWDR = SubAddr & 0xfe;//发送子机地址(写)
        Status = 1;//Status下次主发为1,主收为2
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去
         }
             else//通讯失败
             {
                Exit();
             }
         break;
    case TW_REP_START://主机收到自己发送的重新开始信号
         if (Status == 0x55)//本次中断应该接收TW_REPSTART信号
             {
            TWDR = SubAddr | 1;//发送子机地址(读)
        Status = 2;//Status下次主发为1,主收为2
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去
         }
         else//通讯失败
             {
                Exit();
             }
         break;
    case TW_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令
         if (Status == 1)//本次中断应该接收TW_MT_SLA_ACK信号
             {
            Status = 3;//Status下次应该收TW_MT_DATA_ACK
                TWDR = SubComm ^ (SubAddr & 0xfe);//发送子机命令
/*-----------------------------------------------------------------------------
            以后可以复杂些
-----------------------------------------------------------------------------*/
        TxBuffer[0] = SubComm;//简单命令校验
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去
         }
         else//通讯失败
             {
                Exit();
             }
         break;
    case TW_MR_SLA_ACK://主收机接收到从机的地址应答信号
         if (SubCount && (Status == 2))//本次中断应该接收TW_MR_SLA_ACK信号
             {
            Status = 4;//Status下次应该收TW_MR_DATA_ACK
                TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);//主机转入接收状态
         }
         else//通讯失败
             {
                Exit();
             }
         break;
    case TW_MT_DATA_ACK:
         if ((Count < MainCount) && (Status == 3))//本次中断应该接收TW_MT_DATA_ACK信号
             {
            TWDR = TxBuffer[Count ++] ^ (SubAddr & 0xfe);//发送子机数据
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去
         }
         else if ((Count == MainCount) && (Status == 3) && (SubAddr & 1))//本次中断应该接收TW_MT_DATA_ACK信号
             {
            RepStart();//
         }
         else//通讯失败
             {
                Exit();
             }
         break;
    case TW_MT_DATA_NACK://数据发送结束
         break;
    case TW_MR_DATA_ACK:
         if ((Count < SubCount) && (Status == 4))
             {
            RxBuffer[Count ++] = TWDR ^ (SubAddr | 0x01);//接收子机数据
        if (Count < SubCount)
                {
                    TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);//主机转入接收状态
                }
        else
                {
                    TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//主机转入接收状态
            Status = 6;//下次进入I2C_MR_DATA_NACK,接收数据准备完成
                }
         }
         else//通讯失败
             {
                Exit();
             }
         break;
    case TW_MR_DATA_NACK://数据接收结束
         if ((Count == SubCount) && (Status == 6))
             {
                if (((RxBuffer[0] ^ RxBuffer[2]) == 0xff) && ((RxBuffer[1] ^ RxBuffer[3]) == 0xff))
                {
                if ((RxBuffer[0] & 0xf0) == (SubComm & 0xf0))
                    {
                        Succeed = true;//数据通讯成功
            SetDataBuff();//取出接收字节
                }
                    Stop();//通讯成功
            }
         }
         else//通讯失败
             {
                Exit();
             }
             break;
    default:
         Exit();
         break;
    }
}

void TwiObj::SendCommand(void)
{
}

void TwiObj::SetDataBuff(void)
{
//         DataBuffer[num] = ;
}

void TwiObj::WorkExec(void)
{
static unsigned char chnum = 0;
    DDR_SDA = 0;
    DDR_SCL = 0;
    TWCR &= ~(1 << TWEN);
    SCL = 1;//内部上拉电阻
    SDA = 1;//内部上拉电阻
    if (Busy)
    {
      Exit();
    }
    else
    {
        SubAddr = DataBuffer[Test_CdA1] | 0x01;
    SubCount = 4;//接收4个数据
        MainCount = 0;//10;//发送0个数据
    SubComm = ...;//
    Start();
    }
}
 楼主| 发表于 2009-4-2 23:36:36 | 显示全部楼层
pwm.h
hotpower 发表于 2007-8-21 00:45 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __M16_PWM_H
#define __M16_PWM_H

#ifdef __cplusplus
extern "C"
{
#endif

class PwmObj;

class PwmObj {
public:
  PwmObj(void);
  void Open(void);
  void Close(void);
  void Inc(void);
  void Dec(void);
  void FastDec(void);
private:
  void Init(void);
};

#define DDR_PWM   DDRD_Bit5
#define PWM       PORTD_Bit5

#define PWMWORKMAXSIZE   588//PWM工作周期16KHz
#define PWMWORKSTOPSIZE   388//238
#define PWMWORKSTARTSIZE 323;
#define PWMWORKBEGINSIZE 323;

#ifdef __cplusplus
}
#endif

#endif//__M16_PWM_H
 楼主| 发表于 2009-4-2 23:37:02 | 显示全部楼层
pwm.cpp
hotpower 发表于 2007-8-21 00:46 AVR 单片机 ←返回版面   举报该贴

#include "pwm.h"
PwmObj:wmObj(void)
{
    Init();//PWM初始化
}

//inline
void PwmObj::Init(void)
{
    PWM = 0;
    DDR_PWM = 0;//设置PWM输入管脚
    ICR1   = PWMWORKMAXSIZE;//288
    OCR1A  = 0;//PWM不输出
    TCCR1A = 0;
    TCCR1B = 0;
    DDR_PWM = 1;//设置PWM输出管脚
}

//inline
void PwmObj::Open(void)
{
    PWM = 0;
    if (Adc.AdcVal[3] >= EndPowerVoltage)
    {
        OCR1A  = PWMWORKSTARTSIZE;//PWM1输出
    }
    else
    {
        OCR1A  = PWMWORKBEGINSIZE;//PWM1输出(激活)
    }
    TCCR1A = (1 << COM1A1)
           | (0 << COM1A0)//比较匹配时清零OC1A/OC1B( 输出低电平)
           | (0 << WGM10)
           | (1 << WGM11);
    TCCR1B = (1 << WGM12)
           | (1 << WGM13)//快速PWM
           | (0 << CS12)
           | (0 << CS11)
           | (1 << CS10);//不分频
    DDR_PWM = 1;//设置PWM输出管脚
}

//inline
void PwmObj::Close(void)
{
    PWM = 0;
    DDR_PWM = 1;//设置PWM输入管脚
    OCR1A  = 0;//PWM1不输出
    TCCR1A = 0;
    TCCR1B = 0;
}

//inline
void PwmObj::Inc(void)
{
    if (OCR1A < PWMWORKSTOPSIZE)
    {
        OCR1A ++;
    }
}

//inline
void PwmObj:ec(void)
{
    if (OCR1A > 0)
    {
        OCR1A --;
    }
}

void PwmObj::FastDec(void)
{
    if (OCR1A > 10)
    {
        OCR1A -= 10;
    }
}
 楼主| 发表于 2009-4-2 23:37:35 | 显示全部楼层
main.h
hotpower 发表于 2007-8-21 00:56 AVR 单片机 ←返回版面   举报该贴

#include
#include
#include
#include
#include

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __M16_MAIN_H
#define __M16_MAIN_H
/*------------------------------------
本系统定义的头文件应该放入此处
------------------------------------*/
#include "class.h"
#include "timer.h"
#include "interrupt.h"
#include "uart.h"
#include "pwm.h"
#include "adc.h"
#include "wdt.h"
#include "sleep.h"
#include "twi.h"
#include "cstring.h"

#ifdef __cplusplus
extern "C"
{
#endif

enum enum_SystemFlag
{
    MainExecFlag,
    EInt0ExecFlag, EInt1ExecFlag,
    Timer0ExecFlag, Timer1ExecFlag, Timer2ExecFlag,
    UsartTxExecFlag, UsartRxExecFlag
};


enum enum_SystemPort
{
    Output   = 1,//IO为输出方式
    Input    = 0,//IO为输入方式
    LedOn    = 1,//LED亮
    LedOff   = 0,//LED灭
    PowerOn  = 1,//打开电源
    PowerOff = 0, //关闭电源
    BeepOn   = 1,
    BeepOff  = 0,
};


enum enum_SystemBeep
{
    Beep_Sound1   = 0x01,//0  0000001 单声
    Beep_Sound2   = 0x05,//0  0000101 2声
    Beep_Sound3   = 0x15,//0  0010101 3声
    Beep_Sound4   = 0x55//0  1010101 4声
};


#define DDR_LEDR DDRB_Bit0
#define DDR_LEDG DDRB_Bit1
#define DDR_LED  DDRD_Bit7
#define DDR_KEY  DDRD_Bit2

#define DDR_WdtBack DDRD_Bit3
#define DDR_Wdt   DDRB_Bit7
#define DDR_Power DDRD_Bit6
#define DDR_Beep  DDRD_Bit4

#define LEDR PORTB_Bit0
#define LEDG PORTB_Bit1
#define LED  PORTD_Bit7

#define WdtBack PORTD_Bit3
#define Wdt    PORTB_Bit7
#define Power  PORTD_Bit6
#define KeyOut PORTD_Bit2

#define Beep   PORTD_Bit4
#define Key    PIND_Bit2

extern SystemObj System;
extern TimerObj  Timer;
extern UartObj   Uart;
extern PwmObj    Pwm;
extern AdcObj    Adc;
extern TwiObj    Twi;

extern __no_init volatile unsigned int RamTest;


#ifdef __cplusplus
}
#endif

#endif//__M16_MAIN_H
 楼主| 发表于 2009-4-2 23:38:01 | 显示全部楼层
main.cpp
hotpower 发表于 2007-8-21 00:58 AVR 单片机 ←返回版面   举报该贴

#include "main.h"
//#include
/*-----------------------------------------------
IAR的变量定位很不错。
#pragma location = 0x00
__eeprom unsigned char DataTbl0[] = {1, 2};
#pragma location = 0x10
__eeprom unsigned char DataTbl1[] = {2, 3};

__flash unsigned char DataTbl2[] @ 0x1ff = {2, 3};

__no_init unsigned char test[10] @ 0x8ff;
-----------------------------------------------*/

/*------------------------------------------
在*.XCL文件尾部加入以下3句(M16为iom16.xcl)
// Output
-Ointel-extended,(CODE)=.hex//输出hex文件
-Ointel-extended,(XDATA)=.eep//输出eep文件
-------------------------------------------*/
/*------------------------------------------
IAR AVR C++程序运行顺序
1. __low_level_init()
   System.Init()
2. Timer.Init()
   Uart.Init()
   Pwm.Init()
   Adc.Init()
   Twi.Init()
3. main()
-------------------------------------------*/

extern "C" __root char __low_level_init (void)
{
    __disable_interrupt ();//关闭总中断
    __watchdog_enable (WDTO_2S);
    DDRA  = 0x00;
    DDRB  = 0x00;
    DDRC  = 0x00;
    DDRD  = 0x00;
    TIMSK = 0;
    __delay_cycles(500000);//等待系统稳定
//    __set_sleep_mode (SLEEP_MODE_ADC);
    __set_sleep_mode (SLEEP_MODE_IDLE);
    System.Init ();
    return 1;//0-不初始化,1-初始化
}

__no_init SystemObj System;
TimerObj  Timer;
UartObj   Uart;
PwmObj    Pwm;
AdcObj    Adc;
TwiObj    Twi;

int main(void)
{
    __enable_interrupt ();//开中断
    while (1)//主循环,也可认为是OS的空闲任务
    {
        System.MainExecFlag = 1;//软件看门狗(主循环)复位,条件定时器要工作
        __sleep ();//进入低功耗休眠状态
    }
}
 楼主| 发表于 2009-4-2 23:38:31 | 显示全部楼层
可恨的__no_init和救命的__low_level_init()
hotpower 发表于 2007-8-21 01:10 AVR 单片机 ←返回版面   举报该贴

在IAR AVR中__no_init真不如gccavr

想用:
__no_init SystemObj System;

它倒塌地不执行System的构造函数!!!
导致System.Init()无法运行!!!

虽然可以用返回0的__low_level_init()彻底放弃对全局变量的初始化.
但是有好些入口是字符串的函数无法正常运行!!!

可能俺是IAR菜鸟的缘故吧~~~

还好,__low_level_init()救了命~~~才出现了main.cpp中倒塌的代码!!!

extern "C" __root char __low_level_init (void)
{
    __disable_interrupt ();//关闭总中断
    __watchdog_enable (WDTO_2S);
    DDRA  = 0x00;
    DDRB  = 0x00;
    DDRC  = 0x00;
    DDRD  = 0x00;
    TIMSK = 0;
    __delay_cycles(500000);//等待系统稳定
//    __set_sleep_mode (SLEEP_MODE_ADC);
    __set_sleep_mode (SLEEP_MODE_IDLE);
    System.Init ();//真倒塌了~~~注意:类申请后要先main()执行!!!
    return 1;//0-不初始化,1-初始化
}

__no_init SystemObj System;//不执行构造函数
TimerObj  Timer;//构造函数比main()先执行!!!
UartObj   Uart;//构造函数比main()先执行!!!
PwmObj    Pwm;//构造函数比main()先执行!!!
AdcObj    Adc;//构造函数比main()先执行!!!
TwiObj    Twi;//构造函数比main()先执行!!!
 楼主| 发表于 2009-4-2 23:38:54 | 显示全部楼层
IAR AVR中可爱的位~~
hotpower 发表于 2007-8-21 01:16 AVR 单片机 ←返回版面   举报该贴

#define DDR_LED  DDRD_Bit7
#define LED      PORTD_Bit7


操作:

DDR_LED = 1;
DDR_LED = 0;
DDR_LED ^= 1;

LED = 1;
LED = 0;
LED ^= 1;
 楼主| 发表于 2009-4-2 23:39:15 | 显示全部楼层
interrupt.h
hotpower 发表于 2007-8-21 01:30 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __M16_INTERRUPT_H
#define __M16_INTERRUPT_H

#ifdef __cplusplus
extern "C"
{
#endif



#ifdef __cplusplus
}
#endif

#endif//__M16_INTERRUPT_H
 楼主| 发表于 2009-4-2 23:39:35 | 显示全部楼层
interrupt.cpp(一部分)
hotpower 发表于 2007-8-21 01:34 AVR 单片机 ←返回版面   举报该贴

#include "interrupt.h"

#pragma vector=INT0_vect
extern "C" __interrupt void Int0ISR(void)
{
    System.EInt0ExecFlag = 1;
}

#pragma vector=INT1_vect
extern "C" __interrupt void Int1ISR(void)
{
    System.EInt1ExecFlag = 1;
}

#pragma vector=USART_UDRE_vect
extern "C" __interrupt void UartTxUDREISR(void)
{
    if (Uart.SendWritePtr != Uart.SendReadPtr) {
        UDR = Uart.SendBuffer[Uart.SendReadPtr ++];
        UCSRB |= (1 << UDRIE);
    }
    else
    {
        UCSRB &= ~(1 << UDRIE);
    }
}

#pragma vector=USART_TXC_vect
extern "C" __interrupt void UartTxISR(void)
{
    if (Uart.SendWritePtr != Uart.SendReadPtr) {
        UDR = Uart.SendBuffer[Uart.SendReadPtr ++];
        UCSRB |= (1 << UDRIE);
    }
}

#pragma vector=ADC_vect
extern "C" __interrupt void AdcISR(void)
{
    Adc.Exec ();
}


#pragma vector=TWI_vect
extern "C" __interrupt void TwiISR(void)
{
    Twi.Exec ();
}
 楼主| 发表于 2009-4-2 23:40:05 | 显示全部楼层
timer.h
hotpower 发表于 2007-8-21 01:49 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __IARAVR_TIMER_H
#define __IARAVR_TIMER_H

#ifdef __cplusplus
extern "C"
{
#endif

class TimerObj;
class TimerObj
{
private:
public:
    TimerObj(void);
    void Init(void);
    void Timer0Init(void);
    void Timer1Init(void);
    void Timer2Init(void);
public:
    unsigned int Count0;
    unsigned int Count1;
    unsigned int Count2;
};
#ifdef __cplusplus
}
#endif

#endif//__IARAVR_TIMER_H
 楼主| 发表于 2009-4-2 23:40:28 | 显示全部楼层
timer.cpp
hotpower 发表于 2007-8-21 01:51 AVR 单片机 ←返回版面   举报该贴

#include "timer.h"

TimerObj::TimerObj (void)
{
    Init ();
}

//inline
void TimerObj::Init(void)
{
    Timer0Init ();
    Timer1Init ();
    SFIOR |= (1 << PSR10);//
    Timer2Init ();
}

//inline
void TimerObj::Timer0Init(void)
{
    Count0 = 0;
    TCNT0 = (unsigned char)(0 - 78); // T/C0 开始值
    TCCR0 = (1 << CS02) | (1 << CS00); // 预分频 ck/1024 ,计数允许
    TIMSK |= (1 << TOIE0);//开中断
}

//inline
void TimerObj::Timer1Init(void)
{
    Count1 = 0;
    TIMSK &= ~(1 << TOIE1);//开中断
}

//inline
void TimerObj::Timer2Init(void)
{
    Count2 = 0;
    TCCR2 = (1 << CS22) | (0 << CS21)  | (1 << CS20); //分频比128,0x05,TCNT2=0
    TCNT2 = 0;
    ASSR  = 1 << AS2; //异步时钟
    TIMSK |= (1 << TOIE2);//开中断
}
 楼主| 发表于 2009-4-2 23:41:32 | 显示全部楼层
adc.h
hotpower 发表于 2007-8-23 02:19 AVR 单片机 ←返回版面   举报该贴

#include "main.h"

#ifdef  __IAR_SYSTEMS_ICC__
#ifndef _SYSTEM_BUILD
#pragma system_include
#endif
#endif

#ifndef __M16_ADC_H
#define __M16_ADC_H

#ifdef __cplusplus
extern "C"
{
#endif
class AdcObj;

class AdcObj {//系统采集类
public:
    AdcObj(void);
    void Exec(void);
private:
    void Init(void);
    void SetAdcChNum(unsigned char);//设置ADC通道变换号
    unsigned char GetAdcChNum(unsigned char);//取ADC通道变换号
public:
    unsigned char AdcChNum;
    unsigned char AdcCount[4];
    unsigned int AdcVal[4];
    unsigned int AdcAkVal[4];
    unsigned int AdcSum[4];
    unsigned int AdcMax[4], AdcMin[4];
};

#ifdef __cplusplus
}
#endif

#endif//__M16_ADC_H
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表