本帖最后由 Ryanhsiung 于 2011-11-29 07:49 编辑
模 块 化 编 程
本文献给单片机新手,老手也可以看一下。
我是一个下载族,有空就到21IC CSDN各各电工网站逛逛,下下资料!其实我也是一个菜鸟(只有半只脚踏进来了)。
前天看到PLC_AVR的FLASH代码烈火-M0 4K DATAFLASH当做1K 32Bit EEPROM用,非常方便!,觉得这个功能很实用就下载下来保存了。今天正好要用要用到EEPROM存储几个参数。就想起了PLC_AVR的代码,想直接抄过来,省时省力啊!但是一打开代码傻了眼。MAIN函数写在了DATAFLASH功能函数中了,也只写了两个简单的函数。
注:我这里并没有说PLC_AVR的任何意思,PLC_AVR也只是测试这个功能,没有义务写出各个功能函数。
烈火的代码让我想起了,大多新手的代码都是杂乱无章的,故写此**分享给各位和我一样的菜鸟、新手。
这一篇**不写注释及其他编程风格、原则。
模块化编程概念
当解决一个比较复杂的问题时,如果把问题分解成若干个易于求解的子问题,每个子问题都用一个相对独立的程序段来处理,最后再把所有的程序段结合在一起,形成完整程序,这就是模块化程序设计的方法。
注:语文从小就在及格边缘,这个是从网上抄来的。
为什么要模块化
1、
可以使你的程序清晰明了,便于查看,修改。
即使是你自己写的代码,过了半年你自己再看就变成看天书了!
2、减少BUG的出现,良好的编程风格可以减少BUG的出现,这个地球人都知道。
2、
便于移植
一些在校生,会问为什么一直强调可移植性,再现实工作中,工作量大,且有很多重复的代码,你若没次有很好的移植性的话,等待你的就是无休止的加班。
怎样模块化
以下为我个人的意见,如有错误,或则不完善请多指教。
核心思想:高内聚低耦合、高移植性
1、
每个模块使用一个.C .H文件
2、
在.H文件中留出对外的接口
3、
编写思想:模块尽量高内聚低耦合
4、
某些常量使用用宏定义定义,不建议将所有的常量都定义成宏,有些设定为CONST更佳。
#define MACRO_LENTH
10
uint8_t a_Array[MACRO_LENTH]
5、
将模块的各个功能细分成各个函数,即使只有一条语句
void DrvSYS_ResetChip(void)
{
SYS->IPRSTC1.CHIP_RST = 1;
}
注:若函数被调用的少或者只有一条语句,建议将函数定义成内联函数。
6、
将函数中一些关键的指针、变量设置为宏
例如下例语句将UART_PORT1定义为D_ONE_LINE_UART_PORT ,若要移植只需在头文件中修改 UART_PORT1,而不用去.C文件中每个修改。
#define D_ONE_LINE_UART_PORT
UART_PORT1
DrvUART_Open(D_ONE_LINE_UART_PORT, ¶m);
7、程序中一些块的大小,取余模数要定义成宏
例如:(u32addr/PAGE_32BIT_SIZE)*PAGE_SIZE
(u32addr/128)*512
8、
宏定义,申明都要写在.H文件中,便于查看修改
9、
函数尽量用传参,尽量不要用全局函数传递
一时只能写这么多了,以后想起来再补啊!
大家可以对比一比一下模块化编程与非模块编程的不同,
模块化:
void DataFlash_ModifyOneWord(uint32_t u32addr,uint32_t u32data)
{
uint32_t a_DataFlash_Buffer[128];
DataFlash_ReadOnePage(u32addr,a_DataFlash_Buffer);
DataFlash_EraseOnePage(u32addr);
a_DataFlash_Buffer[u32addr%PAGE_32BIT_SIZE]= u32data
;
DataFlash_WriteOnePage(u32addr,a_DataFlash_Buffer);
}
非模块化:
void DATA_FLASH_Write(uint32_t u32addr,uint32_t u32data)
{
uint32_t data_buff[128]={0};
uint32_t i=0;
__set_PRIMASK(1);
UNLOCKREG();
DrvFMC_EnableISP();
for(i=0;i<;PAGE_SIZE;i++)
DrvFMC_Read(DATA_Flash_Start_ADD+i*4+u32addr/128*512, &data_buff);
DrvFMC_Erase(DATA_Flash_Start_ADD+u32addr/128*512);//擦除一页
data_buff[u32addr%128]=u32data;
//修改要写入的数据
for(i=0; i<;PAGE_SIZE; i++)
//写入数据
DrvFMC_Write(DATA_Flash_Start_ADD+i*4+u32addr/128*512, data_buff);
DrvFMC_DisableISP();
LOCKREG();
__set_PRIMASK(0);//打开全局中断
}
模块化的清晰明了,易于阅读,里面的子程序也便于重复利用。 |