《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > 基于单片机的BSMA法在求取农历节气中的应用研究

基于单片机的BSMA法在求取农历节气中的应用研究

2009-08-14
作者:曾庆化1, 刘建业1, 林雪原1

  摘  要: 基于农历节气的内在规律提出了一种新型实用列表算法——按位列表法(BSMA),利用单片机Tm8706实现了电子万年历的研究和开发。
  关键词: 节气  列表法  微处理器  单片机  算法

 

  农历24节气是我国民间传统节令,对于农事活动有广泛的应用价值。因而带有24节气的电子万年历在农村有广泛的市场。

本文通过分析24节气,找出了其中内在的隐含规律,并且根据这种规律提出了一种最新的查表方法。由于这种查表方法是基于位查询的,所以称之为按位列表法(Bit Schedule Method Arithmetic,BSMA)。

1  阴历节气的隐含规律

  为了便于考察50年中无规律的阴历节气分布时间,本文利用C语言在计算机中实现了50年(2000~2049年)的阳历和阴历节气分布时间表。由于数据庞大,所以仅列出其中部分阳历年对应的前6个节气日期,见表1。

 

  表1中,每年的节气具体日期虽然都在一定的范围内变动,但是变动的趋势毫无规律可寻,每个月的具体节气日期有时候推前一、二天,有时候推后一、二天。但是,从这张复杂表格中的众多数据中可以发现一个规律:虽然,无法获得这些节气变化的具体日期,但是,这些日期的变化总是在3天之内发生。例如:每年的第1个节气(小寒)出现在1月的5日、6日2天中的某一天;每年的第2个节气(大寒)出现在1月的19日、20日、21日3天中的某一天。这样,只要固定每个节气的基本日期,然后专门针对这二、三天编制一个相对日期的表格就可以了。考虑到最多变化范围是3天,所以这个相对日期可以取值为1、0和-1。

  选定的基本日期是:1月到3月的节气基本日期:6/20、4/19、6/21;4月到6月的节气基本日期:5/20、6/21、6/21;6月到9月的节气基本日期:7/23、8/23、8/23;10月到12月的节气基本日期:8/24、8/22、7/22。

  根据以上的思路,可得到表2所示的相对值表。

  仔细观察表2,可以得到以下关于节气日期相对值的规律性结论:

  (1)只有4个节气(大寒、夏至、寒露、小雪)是3个相对值(1,-1和0)同时出现。

  (2)其他的20个节气中仅仅出现了0和-1这2个相对值。

  (3)在有3个相对值的4个节气(大寒、夏至、寒露、小雪)中,2044年以前,出现的非零相对值都是1;而2044年以及2044年以后,出现的非零相对值都是-1;

 

  也就是说在50年内,大寒(2)、夏至(12)、寒露(19)和小雪(22)这4个节气日期变化相对较多,一共有3天,它们的日期相对值可能需要使用3个状态值来表示。

  图1是以上4条农历节气日期规律的相对值分布简图。

 

  根据表2和图1所示的农历节气日期排布规律和形式,就可以构造一个表格,并且结合相应的算法来计算某个阳历日期所对应的阴历节气了。

2 按位列表法(BSMA)及其编码方法

  利用上节分析结果,设想使用最少的字节来编制1个表格,使其包含了50年内的所有相对值分布信息。由于1年包含农历的24个节气,也就是说共有24个日期相对值状态量。

  为了能够尽量减少存储空间,可以使用1个位来代表1个农历的节气日期相对值。这样一年的24个节气就可以用24个位来表示,也就是3个字节(每个字节8个位)表示。这就是所说的按位列表法。

  由于农历节气日期相对值最多有3种状态:-1、0和1,而1个位仅仅有2种状态:0和1。为了能够把3种状态融合进2种状态中,本文根据上节中节气日期相对值的规律性结论,采取了具有条件的二值状态来表示三值状态,制定了如表3所示的编码规则。

 

  利用以上的规则就可对50年的24个节气进行编码,得到如表4所示的编码表。

 

  由此看出,使用这种按位编码的方式对农历日期相对值进行编码时,一年24个节气的日期只需要3个字节就可以明确表示了。50年的节气表,只需要150个字节的存储空间。年份越多,这种编码发方式能够节约的存储空间越大,优势越明显。

3 BSMA法在单片机中的实现

  本文使用的单片机是十速公司的4位机,型号为Tm8706。这种单片机的结构与8位机类似,但是功能远逊于8位计算机。选此机型的原因是它具有结构简单成本低的优势,同时还包括了普通单片机的基本功能。它包含了256个字节的RAM、2KB的ROM、定时器、外部中断、内部中断,此外,还有省电功能和驱动LED的功能。

  由于其他的功能程序已经占用了较大的存储空间。所以能够用于农历节气查询的程序的空间不大,仅仅有0.5KB的容量。也就是说表格和查表程序一共只有0.5KB的空间。表格占用的空间越大,可写程序的空间就越小。

  如果使用表1所示的50年农历24节气日期表,仅仅表格就需要使用50×24个字节=1200个字节的存储空间,其要求空间远远超出了0.5KB的容量。而使用LBA编码方法得到的表格,只需要150个字节,存储空间仅仅是表1所需存储空间的1/8,其余部分可以供查表程序使用。

  在单片机中,查表程序是使用汇编程序完成的,实现起来也很容易。为了便于理解,这里把查表程序用C语言实现的部分介绍如下:

  输入参数是阳历的年月日:day、month、year,要求查表寻找它附近的农历节气和农历节气的日期。

  if(day>=15) half_mon=1;     //判断是否是上半月

  else half_mon=0;

  col=(month-1)*2+half_mon;    //获得节气顺序标号(0~23)

  kc_byte=col/8;          //获得节气日期的相对值所在的

                   //字节位置(0~2)

  kc_bit=col%8;          //获得节气日期的相对值在字节中的

                   //位位置(0~7)

  tmp_modi=modi_datas[year-2000][kc_byte];

                  //获得节气日期相对值所在字节

  value=( (tmp_modi<

                      //日期相对值状态

  if(value!=0){          //判断年份,以决定节气相对值1代表1

                   //还是-1。

  if( (col==1 || col==11 || col==18 || col==21) &&

  year<2044)

              J_qi=days[col]+1;   //年份<2044的4个特定

                   //月份中,取+1。

  else

              J_qi=days[col]-1;    //其他情况下,取-1。

  }

  else

  J_qi=days[col];        //状态为0,节气日期相对值

                  //为节气基本日期值。

  由此程序即可获得所输入阳历日期(年、月、日)附近的农历节气准确日期值。

  通过上面的BSMA列表编码和查询的方法,实现了基于四位单片机的万年历的研制和实现。它用汇编程序方便地实现了阴历24节气功能,同时还可以方便地算出某年的某天距离下一个节气的天数。

  从上面可以看出,按位列表法(BSMA)思路清晰明了,实现起来非常方便,同时节省了大量的ROM空间。所做万年历的时间跨度越大,LBA算法在节省ROM空间的优势就越明显。

 

参考文献

1  李勇,许邦信.太阳黄经和节气时间的近似推算与Newcomb太阳表.南京大学学报,1995;31(3)

2  张培瑜,黄洪峰.中历及二十四节气时刻计算.广西科学,1994;1(3)

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。