AVR工程模板,今天写的
点击此处下载armok01103846.rar 讓一部分貼子先頂起來!! 有没有GCC的模板啊 其实是通用的。我只不过是定义接口。函数内容还是需要自己写的
这样便于所有工程的风格统一
-----此内容被ilan2003于2006-02-24,18:31:42编辑过 刚才下载了大作,并浏览了一下,老实说,没有多少价值。因为你写的这个模板,给我的感觉,架构搭得很差。
个人推荐我自己的架构,我使用了分层的概念,一般单片机嵌入式系统分为3层或者4层(我手头的项目就分为四层)就足够了,越往上层就越脱离硬件,也就是对于同样的项目,越能移植到别的芯片上,越往下就越接近硬件,也就是对于不同的项目,越能移植到同系列的单片机。
原则上某一层的函数只能调用直接的下层和本层且尽量减少调用本层。 楼上的快上传你的来看看,好让我学习学习 我自己不写这些模板的,因为这些架构已经在我脑海中,没有必要,不过我觉得还是可以简单讲一下我的架构:
我系统分为4层,从底往上分别是:驱动层(Driver),解析层(Parser),系统层(System)和应用层(Application)。 在我系统中,我认为Driver层和Parser层是底层程序,System层和Application层是上层程序。原则上,Application只能调用System层和Application的函数和变量;System层只能调用Parser层和System层的函数和变量;Parser层只能调用Driver层和Parser层的函数和变量;Driver层只能调用Diver层的函数和变量;且尽量避免调用本层函数和变量。当然,有些函数和和变量(主要是函数,变量基本没有机会被别的模块调用的)会要求整个项目的文件都能调用,比如串口函数,EEPROM函数等。
另外一个重要原则是底层程序的函数命名尽量是动宾结构,上层程序的函数命名最好是主谓结构。有一个C文件一定有一个对应的H文件。 先说Application层,这一层相对有些特殊,首先一定会有一个config.h和define.h的文件,config.h来根据实际的要求来配置某些程序模块等等,define.h用来定义一些整个项目用得着的宏什么的。大家不妨看看我手头项目的两个文件:
config.h:
#ifndef_CONFIG_H_
#define_CONFIG_H_
#define ICC_AVR 0
#define GCC_AVR 1
#define IAR_AVR 2
#define COMPILER ICC_AVR
// #define FOSC 16000000
// #define FOSC 12000000
// #define FOSC 10000000
// #define FOSC 11059200
#define FOSC 8000000
// #define FOSC 6000000
// #define FOSC 4000000
#ifndef FOSC
#define USE_RC_CLOCK
// #define FOSC 1000000 // use internal RC default
#define FOSC 8000000 // use internal RC default
#endif
#define MOTOR_ANGLE 0.9
#define STEP 72
// Protocol Support
#define SUPPORT_PELCO_P
#define SUPPORT_PELCO_D
#define SUPPORT_MINGRI
// #define SUPPORT_WATCHDOG
#define DECT_ZERO
#ifdef DECT_ZERO
#define ZERO_PIN POSI
// #define DECT_ZERO_USE_INT
#define DECT_ZERO_USE_PIN
#endif
#define FUNC_TEST
#ifdefFUNC_TEST
// #define TEST_COMM
// #define TEST_MOTOR
// #define TEST_CAMERA
// #define TEST_REMOTE
#endif
#define _ASSERT_
#define _DEBUG_ // Use USART to Debug for default
#ifdef_DEBUG_
// #define _DEBUG_COMM_
// #define _DEBUG_MOTOR_
// #define _DEBUG_CAMERA_
// #define _DEBUG_REMOTE_
// #define _DEBUG_ZERO_
#define RS232_LOG
#define RS232_LOG_UI // User Interface
#endif
#ifdef _DEBUG_
#define STATIC
#else
#define STATICstatic
#endif
#ifdefRS232_LOG
#define RS232_LOG_EEPROM
#ifdef RS232_LOG_EEPROM
#define RS232_LOG_EEPROM_WR
#define RS232_LOG_EEPROM_RD
#endif
#define RS232_LOG_FLASH
#ifdef RS232_LOG_FLASH
// #define RS232_LOG_FLASH_WR
#define RS232_LOG_FLASH_RD
#endif
#define RS232_LOG_SRAM
#ifdef RS232_LOG_SRAM
#define RS232_LOG_SRAM_WR
#define RS232_LOG_SRAM_RD
#endif
#endif
#define EEPROM_MAGIC "UV80MAGIC" // <= 15
#define LAST_DATE "20060211"// <= 16
#define MAIN_VERSION "UV8009" // <= 8
#define SUB_VERSION "Ver001" // <= 8
#define SUPER_PASSWORD"800101" // <= 8
#define USER_PASSWORD "888888" // <= 8
#endif
define.h:
#ifndef _DEFINE_H_
#define _DEFINE_H_
#if (COMPILER == ICC_AVR)
#include <iom128v.h>
#include <macros.h>
#include <string.h>
#include <limits.h>
#elif (COMPILER == GCC_AVR)
#elif (COMPILER == IAR_AVR)
#endif
#define U8 unsigned char
#define U16 unsigned int
#define U32 unsigned long
#define BOOL unsigned char
#define BYTE unsigned char
#define WORD unsigned int
#define DWRD unsigned long
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define S8 signed char
#define S16 signed int
#define S32 signed long
#define CHAR signed char
#define SINT signed int
#define SLNG signed long
#define TRUE 1
#define FALSE 0
#define POSI 1
#define NEGA 0
#define ENABLE 1
#define DISABLE 0
#define HIGH 1
#define LOW 0
#define LAG_NUL 0
#define LAG_MIN 1
#define LAG_MID 2
#define LAG_MAX 3
#define RET_SUCCESS 0x00
#define RET_FAILURE 0x01
#define RET_ERROR 0x02
#define RET_BUSY 0x04
#define RET_ABORT 0x08
#define FULL_BIT (~0)
#define bLoByte(wTemp) (BYTE)((wTemp) & 0xFF)
#define bHiByte(wTemp) (BYTE)(((wTemp) >> 8) & 0xFF)
#define wLoWord(dwTemp) (WORD)((dwTemp) & 0xFFFF)
#define wHiWord(dwTemp) (WORD)(((dwTemp) >> 16) & 0xFFFF)
#define bByte0(dwTemp) (BYTE)((dwTemp) & 0xFF)
#define bByte1(dwTemp) (BYTE)(((dwTemp) >> 8) & 0xFF)
#define bByte2(dwTemp) (BYTE)(((dwTemp) >> 16) & 0xFF)
#define bByte3(dwTemp) (BYTE)(((dwTemp) >> 24) & 0xFF)
#if (COMPILER == ICC_AVR)
#define LOW_BYTE(wTemp) (*(BYTE *)(&wTemp))
#define HIG_BYTE(wTemp) (*((BYTE *)(&wTemp) + 1))
#define LOW_WORD(dwTemp) (*(WORD *)(&dwTemp))
#define HIG_WORD(dwTemp) (*((WORD *)(&dwTemp) + 1))
#define BYTE0(dwTemp) (*(BYTE *)(&dwTemp))
#define BYTE1(dwTemp) (*((BYTE *)(&dwTemp) + 1))
#define BYTE2(dwTemp) (*((BYTE *)(&dwTemp) + 2))
#define BYTE3(dwTemp) (*((BYTE *)(&dwTemp) + 3))
#endif
#ifndef BIT
#define BIT(x)(1 << (x))
#endif
#define TBL_SIZE(tbl) (sizeof(tbl) / sizeof(tbl))
#ifdef _ASSERT_
#define ASSERT(fgAssert) \
do\
{ \
if(!(fgAssert)) \
{ \
bCommSendString("Assert Error!"); \
bCommSendString(#fgAssert); \
} \
}while(0)
#else
#define ASSERT(fgAssert)
#endif
#ifdef RS232_LOG_UI
#define DBGLogB(bData) while(bCommSendData(bData))
#define DBGLognB(pbData, N) while(bCommSendnData(pbData, N))
#define DBGLogS(Str) while(bCommSendString(Str))
#define DBGLogW(wData) \
do \
{ \
DBGLogB(HIG_BYTE(wData)); \
DBGLogB(LOW_BYTE(wData)); \
}while(0)
#define DBGLogDw(dwData) \
do \
{ \
DBGLogB(BYTE3(dwData)); \
DBGLogB(BYTE2(dwData)); \
DBGLogB(BYTE1(dwData)); \
DBGLogB(BYTE0(dwData)); \
}while(0)
#else
#define DBGLogB(bData)
#define DBGLognB(pb, N)
#define DBGLogS(Str)
#define DBGLogW(wData)
#define DBGLogDw(dwData)
#endif
#if (COMPILER == ICC_AVR)
#define NOT_USE_ENUM
#endif
typedef BOOL (* ServiceFun)(void);
#endif 然后这一层就是以App为开头命名的其它文件,比如肯定有一个Appmain.c,这一层大都是一些只要懂C不必懂硬件就可以看懂应用程序。 对了,忘了说,我会把源文件放到一个SourceCode的文件夹,与SourceCode文件夹并行的有SourceInsight,这是放编辑器的项目文件,有Output文件夹,放输出文件,有ICC/GCC/IAR文件夹,放AVR编译器项目的文件夹,然后有一个Docement的文件夹放文档,CAD文档放我PC机为这个Project写的计算机辅助文件。
SourceCode文件夹下只有一个Application的文件夹(没有其它文件夹和文件),Application文件夹下有config.h,define.h,AppMain.c/AppMain.h,App.....c/h和一个System的文件夹;System文件夹下有一个System.c/System.h,然后是这一层以Sys开头命名的C/H文件,当然还有一个Parser文件夹,Parser文件夹下有一个Parser.c/Parser.h,其它以Par开头命名的C/H文件以及一个Driver的文件夹;Driver文件夹下有一个Driver.c/Driver.h以及其它以Drv开头命名的C/H文件。 每个模块的初始化函数都写在对应的模块,这里建议大家在写Driver层的东西时,一个模块写一个C/H函数,比如DrvTimer0.c/DrvTimer0.h,当你要找代码时非常方便结构也非常清晰。至于这个定时器是干什么的,你到程序中去看。还有一些模块,比如DrvUsart0.c/DrvUsart0.h,我另外的兄弟拿过去,只改了485输出引脚的定义,放到程序中就OK了。 打字打得好累啊,今天就到这里吧,如果以后有更多的XDJM有兴趣我再多梦游几句。 太好了,要认真学习。谢谢! 谢谢 ,我好好的去理解了解 好帖,是要好好学习一下!
这位“来自地狱的天使”真的是“天使”? 好 Louis Bright 幽游梦蝶是个真正的高手,无论是在技术方面还是在诲人不倦方面,实在佩服! 研究
受益
感谢
!! 虽然看不懂,顶下 的确写得很好,总结很透。
不过:我有些小建议想提一下,仅供参考。
有些宏定义不妨多加几个字母,比如说:U8,U16———UINT8,UINT16。这样会更有意义些 Louis Bright 幽游梦蝶
能否搞个包含以上四层的小程序出来啊.我们初学如果要自己做的话一时做不出来.
你就做个出来给我们参考一下嘛. 我也觉得是呀,虽然说看了上面得解释有一个轮廓了,但是要自己再写出来,还是会花很多时间(不是不想写),而且觉得Louis Bright 幽游梦蝶的这种编程方式还是有很大的可学之处。
我也建议Louis Bright 幽游梦蝶把一个没有任何公司资料的工程文件夹打包传上来,那样让更多的人受益。 幽游梦讲的很详细,赞成分层的概念,这样利于工程管理,而且底层的很多东西在其它工程可以重用,不知道还有没有更好的结构,大虾都出来讲两句啊 受益匪浅 to 20楼 yc985055:
我以前是用U8 / S8 /U16 / S16 / U32 / S32的定义的,这个是华为的定义方式,但我最近发现绝大部分程序都定义是BYTE / WORD / DWRD,所以改过来了,其实我改过来还有两个原因:
1.在C51中有bit的定义,我以前还定义了U1的,华为的规范里面,U表示unsigned, S表示signed,但U1不适合移植,而定义BOOL比较恰当
2.个人是个完美主义者,BOOL/BYTE/WORD/DWRD/void都是四个字节,写程序时容易对齐,所以现在都改为这一组了。 对于一些初学的XDJM,我建议你还是先弄懂我一些细节上的小东西再看结构为好,就像建一栋楼房,结构是最重要的,其实每块砖头也很重要,虽然没有结构重要,但要知道,砖头往往是同一个机器做出来的,所以每个文件的写法,要尽量吸取好的东西,其实就是每一个小文件,你也可以先组织好架构啊。
冰冻三尺,非一日之寒。做技术终究是厚积而薄发的过程。
也许这个回帖有点高姿态,你可以对我嗤之以鼻,但最要紧的是你自己真的能进步才好。 to 21楼gongcsf & 22楼kinsey:
首先告诉大家,我其实是去年开始学AVR的,然后花了一年的业余时间才把那个项目做得像模像样,我主要参考的是ISO七层协议合TCP/IP四层协议的一些做法,然后再听过前一家公司一个高人的半个小时的教导才慢慢做成这个样子的。
我是因为这几天出差才有点时间在论坛上梦游几句的,以前更加没有时间;所以要我写个例程,恐怕心有余而力不足。
事实上我是很不喜欢给别人完整的东西的,这有点像“书非借不能读也”;因为我发现一旦有完整的东西,下载以后,反而没有那个认真去研究了(我自己也一样,呵呵)。我自己最有意思的是去年公司的老员工给新员工培训,每个人讲一部分,就我在开始时声明不会把讲义release(事实上最后也只有我的讲义没有release),但最后我的效果最好,哈哈哈哈。 我之前公布过一个写EEPROM读写的源码,有兴趣的可以搜一下,最近几天我更新了代码,事实上,看懂我的那个模块(很简单的)你就能明白我整个架构的很多东西。
这个帖子前面我公布的两个文件,config.h合define.h,你要是看懂了config.h了,正思维基本就可以把握了。 不过话又说回来,我其实还是很乐意写一个这种架构性的东西的;一来可以和大家很好的交流,二来也是验证一下我自己的架构是不是经得起考验,有哪些地方可以改进;众人拾柴火焰高嘛。但这里有三个问题:
一、我们应该基于一个什么样的平台来构建这个例程?(阿莫的Demo板不知道够不够强悍?)
二、我时间可能成问题。
三、我暂时还只会ICC,本网址使用GCC的,要搞懂GCC也需要一个过程,老实说,我学东西比较慢。 还有一点就是我现在的软件按实时性分一种前/后台的结构,早先有大虾说要在这里搞一个实时操作系统,其实我是蛮赞成的,我觉得大家如果投入到这个共同的实时操作系统的编写中,水平会有很大的提高,现在很多现成的操作系统肯定比我们的好,但人家要银子啊,而且有些移植起来未必很合适(ARM倒是没有问题,但像8位机,真正用所谓的操作系统的,我还真没有见识过)。 To Louis Bright 幽游梦蝶:
“因为我发现一旦有完整的东西,下载以后,反而没有那个认真去研究了(我自己也一样,呵呵)”
这个我赞同你的说法,你这样做是有道理的,谢谢你!
“我其实是去年开始学AVR的,然后花了一年的业余时间才把那个项目做得像模像样,我主要参考的是ISO七层协议合TCP/IP四层协议的一些做法”
你那个项目看来很大吧?我也看到了一点“TCP/IP四层协议”的味道。 刚刚我去看了那个EEPROM的程序.
我是刚学的.我发现我看得懂Gorgon Meducer 傻孩子写的程序.
可是我看你的程序我就有点晕了.不知道怎么下手. 我觉得象AVR寄存器比较少,我喜欢用功能模块来归类,uarteepromi2c adc timer0 timer1 timer2 ... 作为新手我也只能暂时留个脚印了 好东西,保存 gongcsf BH7JRE
那个读EPROM网址是多少?
能贴一下吗? MARK You are Great! 新手只能mark mark! mark 谢谢,下来看看 好东西,好好看看 顶 mark 学习 学习 看来楼主的主要作用是抛砖,引来个玉啊 这个是必须顶的。。。。授人以渔哦。。。 mark 爪子先留下 不错啊,受益了。 学习了 mark 作为在校学生,受益了,谢了。 Mark一下,AVR新人 回复【25楼】Louis Bright 幽游梦蝶
to 20楼 yc985055:
我以前是用u8 / s8 /u16 / s16 / u32 / s32的定义的,这个是华为的定义方式,但我最近发现绝大部分程序都定义是byte / word / dwrd,所以改过来了,其实我改过来还有两个原因:
1.在c51中有bit的定义,我以前还定义了u1的,华为的规范里面,u表示unsigned, s表示signed,但u1不适合移植,而定义bool比较恰当
2.个人是个完美主义者,bool/byte/word/dwrd/void都是四个字节,写程序时容易对齐,所以现在都改为这一组了。
-----------------------------------------------------------------------
与你一样,我也是用这一组。不过我是dword而不是dwrd,我认为dword比较直观容易理解,
个人喜好不同。。。 努力学习! 回复【33楼】ilan2003 小松工程
-----------------------------------------------------------------------
我觉得的确像AVR用模块分类方便些。但天使哥的方式值得好好深思。 没有细看,有时间研究,感觉是个好帖 这个得mark一下。 jihao ~后面的才是有价值的。。。 Louis Bright 幽游梦蝶 You Are Great~! Louis_Bright 发表于 2006-2-27 20:41 static/image/common/back.gif
to 21楼gongcsf & 22楼kinsey:
首先告诉大家,我其实是去年开始学AVR的,然后花了一年的业余时间才把那 ...
说的非常好,硬盘中塞满了资料,塞的时候很愉快,塞完了就不管了....估计你发个模板,下载后又保存在e盘download中的资料文件夹中,然后又去论坛找资料去了...........
哎~~是自己太浮躁吗?听君一席话,胜塞100g资料。 有用的东西啊! 留个印,mark过 学习ing
页:
[1]