补充一些IAR AVR常用的H和CPP文件
2009年04月02日 23:29 发布者:hotpower
hotpower 发表于 8/21/2007 12:23:08 AM AVR 单片机 ←返回版面 IAR AVR不错~~~
估计外星人和粉丝同志都很气愤~~~
先得罪了~~~
哈哈~~~忘了声明一下:
转帖必须注明在21ic双龙处."作者是倒塌的菜农"
这是俺做IAR AVR菜鸟的第1篇作文~~~
望各位大侠指教~~~
网友评论
hotpower 2009年04月02日
本帖最后由 hotpower 于 2009-4-2 23:33 编辑
wdt.cpphttp://bbs.21ic.com/club/bbs/images/emote/mood.gif hotpower 发表于 2007-8-21 00:24 AVR 单片机 ←返回版面 http://bbs.21ic.com/club/bbs/images/profile.gif http://bbs.21ic.com/club/bbs/images/fav.gif http://bbs.21ic.com/club/bbs/images/edit.gif举报该贴
#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);
}
本帖最后由 hotpower 于 2009-4-2 23:33 编辑
wdt.cpphttp://bbs.21ic.com/club/bbs/images/emote/mood.gif hotpower 发表于 2007-8-21 00:24 AVR 单片机 ←返回版面 http://bbs.21ic.com/club/bbs/images/profile.gif http://bbs.21ic.com/club/bbs/images/fav.gif http://bbs.21ic.com/club/bbs/images/edit.gif举报该贴
#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);
}
hotpower 2009年04月02日
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
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
hotpower 2009年04月02日
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);
}
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);
}
hotpower 2009年04月02日
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;
char SendBuffer;
// 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
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;
char SendBuffer;
// 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
hotpower 2009年04月02日
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 = 0;
SendBuffer = 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应该小于128
crc ^= ch;
ch ^= passtab & 0x0f;
len ++;
}
*/
SendBuffer = 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;
unsigned char val;
for (i = 3; i >= 0; i --)
{
val = data & 0x0f;
data >>= 4;
if (val <= 9)
{
val += '0';
}
else
{
val += 'A' - 10;
}
str = val;
}
str = 0;
putstr (str);
}
void UartObj::putint(unsigned int data)
{
signed char i;
char str;
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 = val;
}
str = 0;
putstr (str);
}
void UartObj::putint(unsigned int data, signed char size)
{
signed char i;
static char str;
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 = val;
}
str = '\0';
putstr (str);
}
void UartObj::Exec(void)
{
}
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 = 0;
SendBuffer = 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应该小于128
crc ^= ch;
ch ^= passtab & 0x0f;
len ++;
}
*/
SendBuffer = 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;
unsigned char val;
for (i = 3; i >= 0; i --)
{
val = data & 0x0f;
data >>= 4;
if (val <= 9)
{
val += '0';
}
else
{
val += 'A' - 10;
}
str = val;
}
str = 0;
putstr (str);
}
void UartObj::putint(unsigned int data)
{
signed char i;
char str;
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 = val;
}
str = 0;
putstr (str);
}
void UartObj::putint(unsigned int data, signed char size)
{
signed char i;
static char str;
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 = val;
}
str = '\0';
putstr (str);
}
void UartObj::Exec(void)
{
}
hotpower 2009年04月02日
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;
private:
volatile bool Busy;
volatile unsigned char Status;
unsigned char Count;
unsigned char TxBuffer, RxBuffer;
};
#ifdef __cplusplus
}
#endif
#endif//__IARAVR_TWI_H
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;
private:
volatile bool Busy;
volatile unsigned char Status;
unsigned char Count;
unsigned char TxBuffer, RxBuffer;
};
#ifdef __cplusplus
}
#endif
#endif//__IARAVR_TWI_H
hotpower 2009年04月02日
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 = 0;
RxBuffer = 0;
}
for (int i = 0; i < 8; i ++)
{
DataBuffer = 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 = 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 ^ (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 = 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 ^ RxBuffer) == 0xff) && ((RxBuffer ^ RxBuffer) == 0xff))
{
if ((RxBuffer & 0xf0) == (SubComm & 0xf0))
{
Succeed = true;//数据通讯成功
SetDataBuff();//取出接收字节
}
Stop();//通讯成功
}
}
else//通讯失败
{
Exit();
}
break;
default:
Exit();
break;
}
}
void TwiObj::SendCommand(void)
{
}
void TwiObj::SetDataBuff(void)
{
// DataBuffer = ;
}
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 | 0x01;
SubCount = 4;//接收4个数据
MainCount = 0;//10;//发送0个数据
SubComm = ...;//
Start();
}
}
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 = 0;
RxBuffer = 0;
}
for (int i = 0; i < 8; i ++)
{
DataBuffer = 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 = 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 ^ (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 = 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 ^ RxBuffer) == 0xff) && ((RxBuffer ^ RxBuffer) == 0xff))
{
if ((RxBuffer & 0xf0) == (SubComm & 0xf0))
{
Succeed = true;//数据通讯成功
SetDataBuff();//取出接收字节
}
Stop();//通讯成功
}
}
else//通讯失败
{
Exit();
}
break;
default:
Exit();
break;
}
}
void TwiObj::SendCommand(void)
{
}
void TwiObj::SetDataBuff(void)
{
// DataBuffer = ;
}
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 | 0x01;
SubCount = 4;//接收4个数据
MainCount = 0;//10;//发送0个数据
SubComm = ...;//
Start();
}
}
hotpower 2009年04月02日
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
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
hotpower 2009年04月02日
pwm.cpp
hotpower 发表于 2007-8-21 00:46 AVR 单片机 ←返回版面 举报该贴
#include "pwm.h"
PwmObj::PwmObj(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 >= 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::Dec(void)
{
if (OCR1A > 0)
{
OCR1A --;
}
}
void PwmObj::FastDec(void)
{
if (OCR1A > 10)
{
OCR1A -= 10;
}
}
pwm.cpp
hotpower 发表于 2007-8-21 00:46 AVR 单片机 ←返回版面 举报该贴
#include "pwm.h"
PwmObj::PwmObj(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 >= 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::Dec(void)
{
if (OCR1A > 0)
{
OCR1A --;
}
}
void PwmObj::FastDec(void)
{
if (OCR1A > 10)
{
OCR1A -= 10;
}
}
hotpower 2009年04月02日
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
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
hotpower 2009年04月02日
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 @ 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 ();//进入低功耗休眠状态
}
}
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 @ 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 ();//进入低功耗休眠状态
}
}
hotpower 2009年04月02日
可恨的__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()先执行!!!
可恨的__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()先执行!!!
hotpower 2009年04月02日
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;
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;
hotpower 2009年04月02日
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
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
hotpower 2009年04月02日
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;
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;
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 ();
}
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;
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;
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 ();
}
hotpower 2009年04月02日
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
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
hotpower 2009年04月02日
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);//开中断
}
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);//开中断
}
hotpower 2009年04月02日
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;
unsigned int AdcVal;
unsigned int AdcAkVal;
unsigned int AdcSum;
unsigned int AdcMax, AdcMin;
};
#ifdef __cplusplus
}
#endif
#endif//__M16_ADC_H
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;
unsigned int AdcVal;
unsigned int AdcAkVal;
unsigned int AdcSum;
unsigned int AdcMax, AdcMin;
};
#ifdef __cplusplus
}
#endif
#endif//__M16_ADC_H
hotpower 2009年04月02日
adc.cpp(略)
hotpower 发表于 2007-8-23 02:26 AVR 单片机 ←返回版面 举报该贴
#include "adc.h"
AdcObj::AdcObj(void)
{
Init();
}
/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V
公式:Vx = Vref * (R0 + R1) / R0
V0 =2.5*(61/10)=15.25V
V1 =2.5*(61/10)=15.25V
V23=2.5*(85/10)=21.25V
Ak = Vx / 1024
-----------------------------------------------------*/
void AdcObj::Init(void)
{
unsigned char i;
AdcChNum = 0;
ADCSRA = 0x00;
ADMUX = 0;//选择外部2.50为基准
ACSR = (1 << ACD);//关闭模拟比较器
SetAdcChNum(AdcChNum);//设置新通道
for (i = 0; i < 4; i ++) {
AdcVal = 0;
AdcCount = 0;
}
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x1ff;//9位ADC
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x3ff;//10位ADC
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x3ff;//10位ADC
/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V, Vk = 10, N = 9, 10
公式:Vx = Vref * (R0 + R1) / R0
Ak = Vx * / 2 ^ n
Ak0 = 15250 / 512 (N = 9)
= 30500 / 1024
Ak1 = 15250 / 1024
Ak2 = 21250 / 1024
Ak3 = 21250 / 1024
-----------------------------------------------------*/
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频,启动AD转换
}
inline
unsigned char AdcObj::GetAdcChNum(unsigned char ChNum)
{
__root __flash static const unsigned char AdcChNumTab =
{//ADC通道变换表
0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
0x02,//0b00000010,//单端测试,*1,ADC2
0x00//0b00000000,//单端测试,*1,ADC0
// 0x03//0b00000011,//电压,单端测试,*1,ADC3
};
return AdcChNumTab;//返回ADC通道变换号
}
inline
void AdcObj::SetAdcChNum(unsigned char ChNum)//设置ADC通道变换号
{
// ADMUX = (1 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择内部2.56为基准
ADMUX = (0 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择外部2.50为基准
}
void AdcObj::Exec(void)
{
//volatile
unsigned int AdcResult;
//volatile
unsigned long val;
AdcResult = ADC & 0x3ff;//取ADC转换电压,并保存
SetAdcChNum(AdcChNum + 1);//设置新通道
if (AdcChNum > 0)
{
/*-----------------------------------------------------------
求累加和
------------------------------------------------------------*/
AdcSum += AdcResult;//存累加和
/*-----------------------------------------------------------
求最大值
------------------------------------------------------------*/
if (AdcResult > AdcMax)
{
AdcMax = AdcResult;//最大值
}
/*-----------------------------------------------------------
求最小值
------------------------------------------------------------*/
if (AdcResult <= AdcMin)
{
AdcMin = AdcResult;//存最小值
}
AdcCount ++;
if (AdcCount >= 18)//每点测试18次,滤波
{
/*-----------------------------------------------------------
求平均值
------------------------------------------------------------*/
/*----------------------------------------------------
V0 =2.5*(61/10)=15.25V
V1 =2.5*(61/10)=15.25V
V23=2.5*(85/10)=21.25V
-----------------------------------------------------*/
val = AdcSum - AdcMax - AdcMin;
val *= AdcAkVal;
val >>= 14;//18中取16后除以1024
AdcVal = val;
/*-----------------------------------------------------------
初始化
------------------------------------------------------------*/
AdcSum = 0;
AdcMax = 0;
if (AdcChNum == 1)
{
AdcMin = 0x1ff;//9位ADC
}
else
{
AdcMin = 0x3ff;//10位ADC
}
AdcCount = 0;
}
AdcChNum ++;//准备下个通道
AdcChNum &= 3;
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频
}
adc.cpp(略)
hotpower 发表于 2007-8-23 02:26 AVR 单片机 ←返回版面 举报该贴
#include "adc.h"
AdcObj::AdcObj(void)
{
Init();
}
/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V
公式:Vx = Vref * (R0 + R1) / R0
V0 =2.5*(61/10)=15.25V
V1 =2.5*(61/10)=15.25V
V23=2.5*(85/10)=21.25V
Ak = Vx / 1024
-----------------------------------------------------*/
void AdcObj::Init(void)
{
unsigned char i;
AdcChNum = 0;
ADCSRA = 0x00;
ADMUX = 0;//选择外部2.50为基准
ACSR = (1 << ACD);//关闭模拟比较器
SetAdcChNum(AdcChNum);//设置新通道
for (i = 0; i < 4; i ++) {
AdcVal = 0;
AdcCount = 0;
}
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x1ff;//9位ADC
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x3ff;//10位ADC
AdcSum = 0;
AdcMax = 0;
AdcMin = 0x3ff;//10位ADC
/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V, Vk = 10, N = 9, 10
公式:Vx = Vref * (R0 + R1) / R0
Ak = Vx * / 2 ^ n
Ak0 = 15250 / 512 (N = 9)
= 30500 / 1024
Ak1 = 15250 / 1024
Ak2 = 21250 / 1024
Ak3 = 21250 / 1024
-----------------------------------------------------*/
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频,启动AD转换
}
inline
unsigned char AdcObj::GetAdcChNum(unsigned char ChNum)
{
__root __flash static const unsigned char AdcChNumTab =
{//ADC通道变换表
0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
0x02,//0b00000010,//单端测试,*1,ADC2
0x00//0b00000000,//单端测试,*1,ADC0
// 0x03//0b00000011,//电压,单端测试,*1,ADC3
};
return AdcChNumTab;//返回ADC通道变换号
}
inline
void AdcObj::SetAdcChNum(unsigned char ChNum)//设置ADC通道变换号
{
// ADMUX = (1 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择内部2.56为基准
ADMUX = (0 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择外部2.50为基准
}
void AdcObj::Exec(void)
{
//volatile
unsigned int AdcResult;
//volatile
unsigned long val;
AdcResult = ADC & 0x3ff;//取ADC转换电压,并保存
SetAdcChNum(AdcChNum + 1);//设置新通道
if (AdcChNum > 0)
{
/*-----------------------------------------------------------
求累加和
------------------------------------------------------------*/
AdcSum += AdcResult;//存累加和
/*-----------------------------------------------------------
求最大值
------------------------------------------------------------*/
if (AdcResult > AdcMax)
{
AdcMax = AdcResult;//最大值
}
/*-----------------------------------------------------------
求最小值
------------------------------------------------------------*/
if (AdcResult <= AdcMin)
{
AdcMin = AdcResult;//存最小值
}
AdcCount ++;
if (AdcCount >= 18)//每点测试18次,滤波
{
/*-----------------------------------------------------------
求平均值
------------------------------------------------------------*/
/*----------------------------------------------------
V0 =2.5*(61/10)=15.25V
V1 =2.5*(61/10)=15.25V
V23=2.5*(85/10)=21.25V
-----------------------------------------------------*/
val = AdcSum - AdcMax - AdcMin;
val *= AdcAkVal;
val >>= 14;//18中取16后除以1024
AdcVal = val;
/*-----------------------------------------------------------
初始化
------------------------------------------------------------*/
AdcSum = 0;
AdcMax = 0;
if (AdcChNum == 1)
{
AdcMin = 0x1ff;//9位ADC
}
else
{
AdcMin = 0x3ff;//10位ADC
}
AdcCount = 0;
}
AdcChNum ++;//准备下个通道
AdcChNum &= 3;
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频
}
hotpower 2009年04月02日
本帖最后由 hotpower 于 2009-4-2 23:44 编辑
注意楼上的"跳水"滤波算法
hotpower 发表于 2007-8-23 02:51 AVR 单片机 ←返回版面 举报该贴
hotpower 发表于 2007-8-13 21:07 PIC 单片机 ←返回版面 http://bbs.21ic.com/club/bbs/images/profile.gif http://bbs.21ic.com/club/bbs/images/fav.gif http://bbs.21ic.com/club/bbs/images/edit.gif
8楼: 这种算法的优点是点数无限~~~(附"跳水算法")
当然N>=3.而且最好N>3为好.在N很大时就见其优点了.
例如: 3中取1,4中取2,5中取3...10中取8...252中取"二百五"~~~
全部只用这4个寄存器~~~,当然要考虑累加越界类型选择的问题.
注意: N最好取4, 6, 10, 34, 66, 130等等~~~!!!!!!!!!!!!!!
/*-----------------------------------------------------------
取ADC转换电压
------------------------------------------------------------*/
AdcResult = ADC & 0x3ff;//取ADC转换电压结果
/*-----------------------------------------------------------
求累加和
------------------------------------------------------------*/
AdcSum += AdcResult;//存累加和
/*-----------------------------------------------------------
求最大值
------------------------------------------------------------*/
if (AdcResult > AdcMax)
{
AdcMax = AdcResult;//最大值
}
/*-----------------------------------------------------------
求最小值
------------------------------------------------------------*/
if (AdcResult < AdcMin)//注意:千万不敢写成else if ()...
{
AdcMin = AdcResult;//存最小值
}
AdcCount ++;//计数1次
/*-----------------------------------------------------------
10中取8("跳水评分算法---去掉一个最高分,去掉...最后得分...")
------------------------------------------------------------*/
if (AdcCount >= 10)//每次滤波10点
{
/*-----------------------------------------------------------
求平均值
------------------------------------------------------------*/
val = AdcSum - AdcMax - AdcMin;//自然做到了N-2,以下除法变移位
val *= AdcGain;//乘增益(一定要先乘后除!!!否则精度丢失!!!)
val >>= 13;//10中取8后除以1024.(直接得到10进制的mV值)
AdcVal = val;//得到跳水队员分数~~~
/*-----------------------------------------------------------
下一轮初始化(也是ADC的初始化,这里原本是调用函数的~~~)
------------------------------------------------------------*/
AdcSum = 0;//一定清0
AdcMax = 0;//一定取最小值
AdcMin = 0x3ff;//10位ADC,一定取最大值
AdcCount = 0;//重新开始
}
哈哈~~~有时间再灌灌它与排序的不同和优缺点~~~
本帖最后由 hotpower 于 2009-4-2 23:44 编辑
注意楼上的"跳水"滤波算法
hotpower 发表于 2007-8-23 02:51 AVR 单片机 ←返回版面 举报该贴
hotpower 发表于 2007-8-13 21:07 PIC 单片机 ←返回版面 http://bbs.21ic.com/club/bbs/images/profile.gif http://bbs.21ic.com/club/bbs/images/fav.gif http://bbs.21ic.com/club/bbs/images/edit.gif
8楼: 这种算法的优点是点数无限~~~(附"跳水算法")
当然N>=3.而且最好N>3为好.在N很大时就见其优点了.
例如: 3中取1,4中取2,5中取3...10中取8...252中取"二百五"~~~
全部只用这4个寄存器~~~,当然要考虑累加越界类型选择的问题.
注意: N最好取4, 6, 10, 34, 66, 130等等~~~!!!!!!!!!!!!!!
/*-----------------------------------------------------------
取ADC转换电压
------------------------------------------------------------*/
AdcResult = ADC & 0x3ff;//取ADC转换电压结果
/*-----------------------------------------------------------
求累加和
------------------------------------------------------------*/
AdcSum += AdcResult;//存累加和
/*-----------------------------------------------------------
求最大值
------------------------------------------------------------*/
if (AdcResult > AdcMax)
{
AdcMax = AdcResult;//最大值
}
/*-----------------------------------------------------------
求最小值
------------------------------------------------------------*/
if (AdcResult < AdcMin)//注意:千万不敢写成else if ()...
{
AdcMin = AdcResult;//存最小值
}
AdcCount ++;//计数1次
/*-----------------------------------------------------------
10中取8("跳水评分算法---去掉一个最高分,去掉...最后得分...")
------------------------------------------------------------*/
if (AdcCount >= 10)//每次滤波10点
{
/*-----------------------------------------------------------
求平均值
------------------------------------------------------------*/
val = AdcSum - AdcMax - AdcMin;//自然做到了N-2,以下除法变移位
val *= AdcGain;//乘增益(一定要先乘后除!!!否则精度丢失!!!)
val >>= 13;//10中取8后除以1024.(直接得到10进制的mV值)
AdcVal = val;//得到跳水队员分数~~~
/*-----------------------------------------------------------
下一轮初始化(也是ADC的初始化,这里原本是调用函数的~~~)
------------------------------------------------------------*/
AdcSum = 0;//一定清0
AdcMax = 0;//一定取最小值
AdcMin = 0x3ff;//10位ADC,一定取最大值
AdcCount = 0;//重新开始
}
哈哈~~~有时间再灌灌它与排序的不同和优缺点~~~
阿南 2009年04月06日
大叔讲课,俺认识听讲,做好学生
大叔讲课,俺认识听讲,做好学生
mxh0506 2009年06月14日
好!hotpower玩C++就是牛!
好!hotpower玩C++就是牛!
卖西瓜 2009年06月18日
顶
顶
程疗匠人 2009年06月18日
老HOT实在是强 啊~~
老HOT实在是强 啊~~
wolaikankan 2010年09月26日
学习了
学习了
lzy89c55 2011年02月14日
不错
不错
本帖最后由 hotpower 于 2009-4-2 23:31 编辑
wdt.hhttp://bbs.21ic.com/club/bbs/images/emote/mood.gif hotpower 发表于 2007-8-21 00:23 AVR 单片机 ←返回版面 http://bbs.21ic.com/club/bbs/images/profile.gif http://bbs.21ic.com/club/bbs/images/fav.gif http://bbs.21ic.com/club/bbs/images/edit.gif举报该贴
#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