Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1955416
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: C/C++

2014-01-20 19:11:37

用的样片,首次在热转印印制电路板中使用贴片元器件。一版成功。
由于用138做片选,所以要用共阴数码管,共阳的没办法动态扫描。
好了,程序如下:
/*
硬件:STC89C52RC+数码管+DS3232
软件:Keil3
创建时间:        2014.1.18
最后修改时间:    2014.1.20
*/

#include "reg52.h"
#define uchar unsigned char
#define uint  unsigned int

#define ADDRTC  0xd0    /* DS3232地址 (write) */
#define ACK     0
#define NACK    1
#define  PD   P0
#define  PW      P2


sbit    scl = P2^6;             /* I2C SCK */
sbit    sda = P2^7;                /* I2C SDA */

sbit    key1=P3^3;
sbit    key2=P3^4;
sbit    key3=P3^5;

sbit    JDQ= P3^6;// 继电器,低电平有效           
sbit    RING = P3^7;//蜂鸣器,低电平有效
sbit    LE=P2^5;  //LE所存端,始终给高电平即可    
sbit    PW0=P2^0;
sbit    PW1=P2^1;
sbit    PW2=P2^2;
sbit    DS18B20=P2^3;



uchar code duan[10] ={0x03,0x3f,0x91,0xc1,0x65,0x49,0x09,0xe3,0x01,0x41};
uchar code wei[4]={0,4,2,6};


void uart_printf(unsigned char *buff);
void    start();
void    stop();
uchar   i2cwrite(uchar d);
uchar   i2cread(char);
void    hex2asc(uchar);
void    writebyte();
void    initialize_DS3232();
void    rd_temp();
void    frq_out_tog();
void    init_alrm();

 
uchar bcd2hex(uchar x)
{
    return ( ((x&0xf0)>>4)*10 + (x&0x0f) );
}


unsigned char hex2bcd(unsigned char byBCDVal)
{
    return (unsigned char)(byBCDVal/10*16 + byBCDVal%10);
}

/************************* Global Variables ***************************/
xdata   uchar   sec, min, hr, dy, dt, mn, yr;
/**************************** functions ******************************/
void start()          
{
        sda = 1;  scl = 1;
        sda = 0;
}
void stop()           
{
        sda = 0;  sda = 0;
        scl = 1;  scl = 1;  sda = 1;
}
uchar i2cwrite(uchar d)         
{
    uchar i;

    scl = 0;
    for (i = 0;i < 8; i++)
    {
            if (d & 0x80)
                    sda = 1; /* Send the msbits first */
            else
                    sda = 0;
            scl = 0;
            scl = 1;
            d = d << 1;     /* do shift here to increase scl high time */
            scl = 0;
    }
    sda = 1;        /* Release the sda line */
    scl = 0;
    scl = 1;
    i = sda;
    if (i)
    {
        //printf("Ack bit missing  %02X\n",(unsigned int)d);
    }
    scl = 0;
    return(i);
}
uchar i2cread(char b)   /* ----------------------------------- */
{
    uchar i, d;

    d = 0;
    sda = 1;             /* Let go of sda line */
    scl = 0;
    for (i = 0; i < 8; i++) /* read the msb first */
    {
            scl = 1;
            d = d << 1;
            d = d | (unsigned char)sda;
            scl = 0;
    }
    sda = b;          /* low for ack, high for nack */
    scl = 1;
    scl = 0;

    sda = 1;          /* Release the sda line */
    return d;
}


void    initialize_DS3232()     /* ----- set time & date; user data entry ------ */
/* Note: NO error checking is done on the user entries! */
{
    
    yr=14;
    mn=1;
    dt=19;


    dy=7;
    hr=20;
    min=25;
    sec=10;

      
    yr=hex2bcd(yr);
    mn=hex2bcd(mn);
    dt=hex2bcd(dt);
    dy=hex2bcd(dy);

    hr=hex2bcd(hr);
    min=hex2bcd(min);
    sec=hex2bcd(sec);

    start();
    i2cwrite(ADDRTC);       /* write slave address, write 1339 */
    i2cwrite(0x00); /* write register address, 1st clock register */
    i2cwrite(sec);
    i2cwrite(min);
    i2cwrite(hr);
    i2cwrite(dy);
    i2cwrite(dt);
    i2cwrite(mn);
    i2cwrite(yr);
    i2cwrite(0x10); /* enable sqw, 1hz output */
    stop();
}
void    disp_regs()     /* --- display date/time on LCD display --- */
{
    uchar str[24];
    uchar i=0;
    start();
    i2cwrite(ADDRTC);
    i2cwrite(0x0f);
    i2cwrite(0);            /* clear alarm flags */
    stop();

    start();
    i2cwrite(ADDRTC);
    i2cwrite(0);
    start();
    i2cwrite(ADDRTC | 1);
    sec = i2cread(ACK);
    min = i2cread(ACK);
    hr = i2cread(ACK);
    dy = i2cread(ACK);
    dt = i2cread(ACK);
    mn = i2cread(ACK);
    yr = i2cread(NACK);

    sec=bcd2hex(sec);
    min=bcd2hex(min);
    hr=bcd2hex(hr);
    dy=bcd2hex(dy);
    dt=bcd2hex(dt);
    mn=bcd2hex(mn);
    yr=bcd2hex(yr);
    

    stop();

    str[i++]=yr/10+'0';
    str[i++]=yr%10+'0';
    str[i++]='-';
    str[i++]=mn/10+'0';
    str[i++]=mn%10+'0';
    str[i++]='-';
    str[i++]=dt/10+'0';
    str[i++]=dt%10+'0';



    str[i++]=' ';
    str[i++]=hr/10+'0';
    str[i++]=hr%10+'0';
    str[i++]=':';
    str[i++]=min/10+'0';
    str[i++]=min%10+'0';
    str[i++]=':';
    str[i++]=sec/10+'0';
    str[i++]=sec%10+'0';

    str[i++]=' ';
    str[i++]=' ';
    str[i++]=dy%10+'0';

    str[i++]='\r';
    str[i]='\n';
    //uart_printf(str);

}
void    rd_temp()       /* -------- display temperature -------- */
{
    char    str[22];
    int     itemp;
    float   ftemp;

    do
    {
        start();
        i2cwrite(ADDRTC);
        i2cwrite(0x0e);         /* address of control register */
        start();
        i2cwrite(ADDRTC + 1);   /* send the device address for read */
        itemp = i2cread(NACK);  /* get the control register value */
        stop();
    }       
    while(itemp & 0x20);            /* wait until CNVT bit goes inactive */

    start();
    i2cwrite(ADDRTC);
    i2cwrite(0x11);                 /* address of temperature MSB */
    start();
    i2cwrite(ADDRTC + 1);           /* send the device address for read */
    itemp = ( (int) i2cread(ACK) << 2 );
    itemp += ( i2cread(NACK) >> 6);
    stop();
    if(itemp & 0x1000)      itemp += 0xe000;        /* if sign bit set, make 16 bit 2's comp */

    itemp=itemp>>2;

    str[0]=itemp/100+'0';
    str[1]=itemp%100/10+'0';
    str[2]=itemp%10+'0';


    uart_printf(str);
    uart_printf("\r\n");

    ftemp = 0.03125 * (float) itemp;        /* convert to degrees C */
}
void    frq_out_tog()   /* --- toggle en32khz bit to enable/disable sqw --- */
{
uchar   val;

        start();
        i2cwrite(ADDRTC);
        i2cwrite(0x0f);                 /* control/status reg address */
        start();
        i2cwrite(ADDRTC + 1);           /* send the device address for read */
        val = i2cread(NACK);
        stop();
        val ^= 0x08;    /* toggle en32khz bit */
        start();
        i2cwrite(ADDRTC);
        i2cwrite(0x0f);                 /* control/status reg address */
        i2cwrite(val);
        stop();
}
void    init_alrm()     /* --- enable alarm 1 for once-per-second --- */
{
        start();
        i2cwrite(ADDRTC);
        i2cwrite(7);            /* 1st alarm 1 reg address */
        i2cwrite(0x80); /* mask alarm register */
        i2cwrite(0x80);
        i2cwrite(0x80);
        i2cwrite(0x80);
        stop();

        start();
        i2cwrite(ADDRTC);
        i2cwrite(0x0e); /* control/status reg address */
        i2cwrite(0x05); /* enable interrupts, alarm 1 output */
}
void    comm_init()     /* ------ reset DS3232 comm interface ------ */
{
    do      /* because the DS3232 I2C interface is active for both supplies */
    {       /*  after a micro reset, we must get the comm into a known state */
        sda = 1;        /* make sure master has released SDA */
        scl = 1;
        if(sda) /* if sda is high, generate a start */
        {
                sda = 0;        /* The DS3232 will recognize a valid start */
                sda = 1;        /*  condition anywhere in a I2C data transfer */
        }
        scl = 0;
    }       
    while(sda == 0);        /* if the DS3232 is holding sda low, try again */
}
void uart_init()
{
   TMOD|=0x20;     //TMOD=0
   TH1=0xf3;      //12MHZ   ,BPS:4800,N,8,1,0xf3=243
   TL1=0xf3;
   
   TR1=1;

   PCON=0x80;     //SMOD=1,方式一,8位数据位,一位起始位和一位结束位
            //
   SCON=0x50;     //串口通信控制寄存器  模式一

   EA=1;
  // ES=1;  //打开串口中断
   //REN=1;
 
}

void uart_putchar(unsigned char dat)
{
    SBUF=dat; //把数据送给sbuf缓存器中
    while(TI!=1);//发送标志位 TI如果发送了为1,没发送为0,没发送等待,到了退出循环
    TI=0;  //到了,TI清为0

}
void uart_printf(unsigned char *buff)
{

    while(*buff)
       uart_putchar(*buff++);
}
void delay(unsigned int k)    
{    
    unsigned int i,j;    
    for(i=0;i
    {    
    for(j=0;j<121;j++)    
    {;}
    }    
}
 void Seg_DisPlay(uint x)
 {
     uchar i,j;
    LE=1;

    PW0=0;
    PW1=0;
    PW2=0;
    PD=0xff-duan[x/1000];
    delay(5);

    PW0=0;
    PW1=0;
    PW2=1;
    PD=0xff-duan[x%1000/100];
    delay(5);

    PW0=0;
    PW1=1;
    PW2=0;
    PD=0xff-duan[x%100/10];
    delay(5);

    PW0=0;
    PW1=1;
    PW2=1;
    PD=0xff-duan[x%10];
    delay(5);


    
 }

void  Led_Test()
{
      char i,j;
    
     for(j=0;j<4;j++)
     {
         PW=wei[j] |(1<<5) ;
         for(i=0;i<10;i++)
         {
             PD= 0xff-duan[i];
            delay(200);
         }
     }
}
void   main    (void)  /* ------------------------------------------------ */
{
    comm_init();
    uart_init();
    //initialize_DS3232();
    //init_alrm();            /* enable alarm */
 
    while(1)
    {
        P1=0xFf-sec;
          //rd_temp();
        
          disp_regs();
          JDQ=1;
          RING=1;
          if(key1==0)
          {
                  Seg_DisPlay( (mn*100+dt) );
          }
          else if(key2==0)
          {
                  Seg_DisPlay( (sec) );
          }
          else if(key3==0)
          {
                Seg_DisPlay( (dy) );
          }
          else
          {
                  Seg_DisPlay( (hr*100+min) );
          }
        
           //delay(3000);
          
    }

}
原理图如下:

pcb图如下:

实物图如下:





总共做了两块,由于内置晶振并带有温度补偿,所以精度很高。跑了两天时间1秒不差!


最新版本程序:
main.c

点击(此处)折叠或打开

  1. /*
  2. 硬件:STC89C52RC+数码管(共阴,高电平亮)+DS3232
  3. 软件:Keil3
  4. 创建时间:        2014.1.18
  5. 最后修改时间:    2014.11.14        添加按键修改年月日时分秒星期的功能,添加DS18B20温度显示

  6. 管脚描述:

  7. 继电器输出:P36
  8. 蜂鸣器输出:P37
  9. 按键1-按键3:P33,P34,P35
  10. 红外线输入:P32
  11. LED1-LED8: P10-P17
  12. 数码管段选:P0
  13. 数码管位选:P20,P21,P22
  14. 74HC573-LE: P25
  15. DS18B20:    P23
  16. IIC_SCL:     P26
  17. IIC_SDA:    P27

  18. */
  19. #define CMD_RING_TMP         8
  20. #define CMD_RING_DATE        9
  21. #define CMD_RING_TIME        10

  22. #include "config.h"

  23. #define ADDRTC 0xd0 /* DS3232地址 (write) */
  24. #define ACK 0
  25. #define NACK 1
  26. #define PD P0
  27. #define PW     P2
  28. #define CHECK_BIT(value,x)     (value &( (1<<x) ) )?0:1

  29. uchar code     g_uchLedTab[]=
  30. {0,1,2,4,8,4,2,1,0,9,6,0,6,9,15,9,6,0,12,6,3,0,3,6,12,10,5,0,5,10};

  31. #define TAB_NUM            sizeof(g_uchLedTab)/sizeof(char)

  32. sbit scl = P2^6; /* I2C SCK */
  33. sbit sda = P2^7;                /* I2C SDA */

  34. sbit key1=P3^3;
  35. sbit key2=P3^4;
  36. sbit key3=P3^5;

  37. sbit JDQ= P3^6;// 继电器,低电平有效
  38. sbit RING = P3^7;//蜂鸣器,低电平有效
  39. sbit LE=P2^5; //LE所存端,始终给高电平即可    
  40. sbit PW0=P2^0;
  41. sbit PW1=P2^1;
  42. sbit PW2=P2^2;
  43. sbit DS18B20=P2^3;


  44. sbit     LED1=P1^0;
  45. sbit     LED2=P1^1;
  46. sbit     LED3=P1^2;
  47. sbit     LED4=P1^3;
  48. sbit     LED5=P1^4;

  49. sbit    yy_rst=P1^7;
  50. sbit yy_dat=P1^6;
  51. sbit yy_busy=P1^5;



  52. uchar code duan[10] ={0x03,0x3f,0x91,0xc1,0x65,0x49,0x09,0xe3,0x01,0x41};
  53. uchar code wei[4]={0,4,2,6};
  54. uchar g_bNotDisSeg=0;

  55. void uart_printf(unsigned char *buff);
  56. void start();
  57. void stop();
  58. uchar i2cwrite(uchar d);
  59. uchar i2cread(char);
  60. void hex2asc(uchar);
  61. void writebyte();
  62. void initialize_DS3232();
  63. void rd_temp();
  64. void frq_out_tog();
  65. void init_alrm();

  66. void delay(unsigned int k);    
  67. uchar bcd2hex(uchar x)
  68. {
  69.     return ( ((x&0xf0)>>4)*10 + (x&0x0f) );
  70. }


  71. unsigned char hex2bcd(unsigned char byBCDVal)
  72. {
  73.     return (unsigned char)(byBCDVal/10*16 + byBCDVal%10);
  74. }

  75. /************************* Global Variables ***************************/
  76. uchar xdata sec, min, hr, dy, dt, mn, yr;
  77. /**************************** functions ******************************/
  78. void start()
  79. {
  80.         sda = 1; scl = 1;
  81.         sda = 0;
  82. }
  83. void stop()
  84. {
  85.         sda = 0; sda = 0;
  86.         scl = 1; scl = 1; sda = 1;
  87. }
  88. uchar i2cwrite(uchar d)
  89. {
  90.     uchar i;

  91.     scl = 0;
  92.     for (i = 0;i < 8; i++)
  93.     {
  94.      if (d & 0x80)
  95.      sda = 1; /* Send the msbits first */
  96.      else
  97.      sda = 0;
  98.      scl = 0;
  99.      scl = 1;
  100.      d = d << 1; /* do shift here to increase scl high time */
  101.      scl = 0;
  102.     }
  103.     sda = 1; /* Release the sda line */
  104.     scl = 0;
  105.     scl = 1;
  106.     i = sda;
  107.     if (i)
  108.     {
  109.         //printf("Ack bit missing %02X\n",(unsigned int)d);
  110.     }
  111.     scl = 0;
  112.     return(i);
  113. }
  114. uchar i2cread(char b) /* ----------------------------------- */
  115. {
  116.     uchar i, d;

  117.     d = 0;
  118.     sda = 1; /* Let go of sda line */
  119.     scl = 0;
  120.     for (i = 0; i < 8; i++) /* read the msb first */
  121.     {
  122.             scl = 1;
  123.             d = d << 1;
  124.             d = d | (unsigned char)sda;
  125.             scl = 0;
  126.     }
  127.     sda = b; /* low for ack, high for nack */
  128.     scl = 1;
  129.     scl = 0;

  130.     sda = 1; /* Release the sda line */
  131.     return d;
  132. }


  133. void initialize_DS3232() /* ----- set time & date; user data entry ------ */
  134. /* Note: NO error checking is done on the user */
  135. {
  136.     
  137.     yr=14;//year
  138.     mn=6;//month
  139.     dt=29;//day


  140.     dy=7;
  141.     hr=11;//hour
  142.     min=48;//minute
  143.     sec=30;//second

  144.     
  145.     yr=hex2bcd(yr);
  146.     mn=hex2bcd(mn);
  147.     dt=hex2bcd(dt);
  148.     dy=hex2bcd(dy);

  149.     hr=hex2bcd(hr);
  150.     min=hex2bcd(min);
  151.     sec=hex2bcd(sec);

  152.     start();
  153.     i2cwrite(ADDRTC); /* write slave address, write 1339 */
  154.     i2cwrite(0x00); /* write register address, 1st clock register */
  155.     i2cwrite(sec);
  156.     i2cwrite(min);
  157.     i2cwrite(hr);
  158.     i2cwrite(dy);
  159.     i2cwrite(dt);
  160.     i2cwrite(mn);
  161.     i2cwrite(yr);
  162.     i2cwrite(0x10); /* enable sqw, 1hz output */
  163.     stop();
  164. }

  165. void ReInitialDS3232(void)
  166. {
  167.         
  168.     yr=hex2bcd(yr);
  169.     mn=hex2bcd(mn);
  170.     dt=hex2bcd(dt);
  171.     dy=hex2bcd(dy);

  172.     hr=hex2bcd(hr);
  173.     min=hex2bcd(min);
  174.     sec=hex2bcd(sec);

  175.     start();
  176.     i2cwrite(ADDRTC); /* write slave address, write 1339 */
  177.     i2cwrite(0x00); /* write register address, 1st clock register */
  178.     i2cwrite(sec);
  179.     i2cwrite(min);
  180.     i2cwrite(hr);
  181.     i2cwrite(dy);
  182.     i2cwrite(dt);
  183.     i2cwrite(mn);
  184.     i2cwrite(yr);
  185.     i2cwrite(0x10); /* enable sqw, 1hz output */
  186.     stop();
  187. }
  188. void disp_regs() /* --- display date/time on LCD display --- */
  189. {
  190.     uchar str[24];
  191.     uchar i=0;
  192.     start();
  193.     i2cwrite(ADDRTC);
  194.     i2cwrite(0x0f);
  195.     i2cwrite(0); /* clear alarm flags */
  196.     stop();

  197.     start();
  198.     i2cwrite(ADDRTC);
  199.     i2cwrite(0);
  200.     start();
  201.     i2cwrite(ADDRTC | 1);
  202.     sec = i2cread(ACK);
  203.     min = i2cread(ACK);
  204.     hr = i2cread(ACK);
  205.     dy = i2cread(ACK);
  206.     dt = i2cread(ACK);
  207.     mn = i2cread(ACK);
  208.     yr = i2cread(NACK);

  209.     sec=bcd2hex(sec);
  210.     min=bcd2hex(min);
  211.     hr=bcd2hex(hr);
  212.     dy=bcd2hex(dy);
  213.     dt=bcd2hex(dt);
  214.     mn=bcd2hex(mn);
  215.     yr=bcd2hex(yr);
  216.     

  217.     stop();

  218.     str[i++]=yr/10+'0';
  219.     str[i++]=yr%10+'0';
  220.     str[i++]='-';
  221.     str[i++]=mn/10+'0';
  222.     str[i++]=mn%10+'0';
  223.     str[i++]='-';
  224.     str[i++]=dt/10+'0';
  225.     str[i++]=dt%10+'0';



  226.     str[i++]=' ';
  227.     str[i++]=hr/10+'0';
  228.     str[i++]=hr%10+'0';
  229.     str[i++]=':';
  230.     str[i++]=min/10+'0';
  231.     str[i++]=min%10+'0';
  232.     str[i++]=':';
  233.     str[i++]=sec/10+'0';
  234.     str[i++]=sec%10+'0';

  235.     str[i++]=' ';
  236.     str[i++]=' ';
  237.     str[i++]=dy%10+'0';

  238.     str[i++]='\r';
  239.     str[i]='\n';
  240.     //uart_printf(str);

  241. }
  242. void rd_temp() /* -------- display temperature -------- */
  243. {
  244.     char xdata str[22];
  245.     int xdata itemp;
  246.     float xdata ftemp;

  247.     do
  248.     {
  249.         start();
  250.         i2cwrite(ADDRTC);
  251.         i2cwrite(0x0e); /* address of control register */
  252.         start();
  253.         i2cwrite(ADDRTC + 1); /* send the device address for read */
  254.         itemp = i2cread(NACK); /* get the control register value */
  255.         stop();
  256.     }
  257.     while(itemp & 0x20); /* wait until CNVT bit goes inactive */

  258.     start();
  259.     i2cwrite(ADDRTC);
  260.     i2cwrite(0x11); /* address of temperature MSB */
  261.     start();
  262.     i2cwrite(ADDRTC + 1); /* send the device address for read */
  263.     itemp = ( (int) i2cread(ACK) << 2 );
  264.     itemp += ( i2cread(NACK) >> 6);
  265.     stop();
  266.     if(itemp & 0x1000) itemp += 0xe000; /* if sign bit set, make 16 bit 2's comp */

  267.     itemp=itemp>>2;

  268.     str[0]=itemp/100+'0';
  269.     str[1]=itemp%100/10+'0';
  270.     str[2]=itemp%10+'0';


  271.     uart_printf(str);
  272.     uart_printf("\r\n");

  273.     ftemp = 0.03125 * (float) itemp; /* convert to degrees C */
  274. }
  275. void frq_out_tog() /* --- toggle en32khz bit to enable/disable sqw --- */
  276. {
  277. uchar val;

  278.         start();
  279.         i2cwrite(ADDRTC);
  280.         i2cwrite(0x0f); /* control/status reg address */
  281.         start();
  282.         i2cwrite(ADDRTC + 1); /* send the device address for read */
  283.         val = i2cread(NACK);
  284.         stop();
  285.         val ^= 0x08; /* toggle en32khz bit */
  286.         start();
  287.         i2cwrite(ADDRTC);
  288.         i2cwrite(0x0f); /* control/status reg address */
  289.         i2cwrite(val);
  290.         stop();
  291. }
  292. void init_alrm() /* --- enable alarm 1 for once-per-second --- */
  293. {
  294.         uchar ahour=13;
  295.         uchar amin=43;
  296.         uchar asec=0;

  297.         ahour=hex2bcd(ahour);
  298.         amin= hex2bcd(amin);
  299.         asec= hex2bcd(asec);

  300.         start();
  301.         i2cwrite(ADDRTC);
  302.         i2cwrite(7); /* 1st alarm 1 reg address */

  303.         i2cwrite(asec); /* mask alarm register */
  304.         i2cwrite(amin);
  305.         i2cwrite(ahour|0x80);
  306.         i2cwrite(0x80);

  307.         i2cwrite(0x80); /* mask alarm register */
  308.         i2cwrite(0x80);
  309.         i2cwrite(0x80);
  310.         i2cwrite(0x80);
  311.   
  312.         //i2cwrite(0x0e); /* control/status reg address */
  313.         i2cwrite(0x05); /* enable interrupts, alarm 1 output */
  314.         ///i2cwrite(0);
  315.         stop();
  316. }
  317. void comm_init() /* ------ reset DS3232 comm interface ------ */
  318. {
  319.     do /* because the DS3232 I2C interface is active for both supplies */
  320.     { /* after a micro reset, we must get the comm into a known state */
  321.         sda = 1; /* make sure master has released SDA */
  322.         scl = 1;
  323.         if(sda) /* if sda is high, generate a start */
  324.         {
  325.                 sda = 0; /* The DS3232 will recognize a valid start */
  326.                 sda = 1; /* condition anywhere in a I2C data transfer */
  327.         }
  328.         scl = 0;
  329.     }
  330.     while(sda == 0); /* if the DS3232 is holding sda low, try again */
  331. }
  332. void uart_init()
  333. {
  334.    TMOD|=0x20; //TMOD=0
  335.    TH1=0xf3; //12MHZ ,BPS:4800,N,8,1,0xf3=243
  336.    TL1=0xf3;
  337.    
  338.    TR1=1;

  339.    PCON=0x80; //SMOD=1,方式一,8位数据位,一位起始位和一位结束位
  340.             //
  341.    SCON=0x50; //串口通信控制寄存器 模式一

  342.    EA=1;
  343.    ES=1; //打开串口中断
  344.    REN=1;
  345.   
  346. }

  347. void uart_putchar(unsigned char dat)
  348. {
  349.     SBUF=dat; //把数据送给sbuf缓存器中
  350.     while(TI!=1);//发送标志位 TI如果发送了为1,没发送为0,没发送等待,到了退出循环
  351.     TI=0; //到了,TI清为0

  352. }
  353. void uart_printf(unsigned char *buff)
  354. {

  355.     while(*buff)
  356.        uart_putchar(*buff++);
  357. }

  358. typedef struct
  359. {
  360.     BYTE hour;
  361.     BYTE minute;
  362.     BYTE second;
  363.     BYTE week;
  364. }mtime_t;
  365. typedef struct
  366. {
  367.     //WORD rsv[2];
  368.     WORD year;
  369.     BYTE month;
  370.     BYTE day;
  371. }mdate_t;
  372. typedef struct
  373. {
  374.     mdate_t date;
  375.     mtime_t time;
  376. }date_time_t;
  377. typedef struct
  378. {
  379.     uchar     byIntFlag;
  380.     uchar byWritePoint;
  381.     uint    dwOutCnt;
  382.     uchar    byRxBuf[16];
  383. }serial_t;
  384. serial_t g_rx; ////////////////////////////////////////////////////////
  385. void uart() interrupt 4
  386. {
  387.     if(RI == 1) // RI = 0;
  388.     {
  389.         g_rx.byIntFlag=1;
  390.         if(g_rx.byWritePoint<16)
  391.         {     
  392.             g_rx.byRxBuf[g_rx.byWritePoint]=SBUF;
  393.             g_rx.byWritePoint++;
  394.         }
  395.         RI=0;
  396.     }
  397.     ///if(TI == 1) {SBUF = txt[i++]; TI = 0;}
  398. }
  399. /*
  400. BYTE GetWeekday(int year,BYTE mon,BYTE day)
  401. {
  402. //    BYTE TAB_X[12]={6,2,2,5,0,3,5,1,4,6,2,4}, ucWeekDay;
  403. //    return ((year + year/4 - ( (mon<3)&&(year%4==0) ) + TAB_X[mon] + day )%7+4)%7;
  404.     int xdata r[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};
  405.     year %= 400;
  406.     if((year==0||year%4==0&&year%100!=0)&&mon<3)
  407.         return ((year+year/4-year/100+r[mon]+day+5)%7);
  408.     else
  409.         return ((year+year/4-year/100+r[mon]+day+6)%7);
  410. }    */


  411. void delay(unsigned int k)    
  412. {    
  413.     unsigned int i,j;    
  414.     for(i=0;i<k;i++)
  415.     {    
  416.     for(j=0;j<50;j++)    
  417.     {;}
  418.     }    
  419. }
  420.  void Seg_DisPlay(uint x)
  421.  {
  422.      uint tmp;

  423.     if(!g_bNotDisSeg)
  424.     {
  425.         tmp=x/1000;
  426.         LE=1;
  427.     
  428.         PW0=0;
  429.         PW1=0;
  430.         PW2=0;
  431.         PD=(!tmp)?(0):(0xff-duan[tmp]);
  432.         delay(5);
  433.     
  434.         PW0=0;
  435.         PW1=0;
  436.         PW2=1;
  437.         PD=0xff-duan[x%1000/100];
  438.         delay(5);
  439.     
  440.         PW0=0;
  441.         PW1=1;
  442.         PW2=0;
  443.         PD=0xff-duan[x%100/10];
  444.         delay(5);
  445.     
  446.         PW0=0;
  447.         PW1=1;
  448.         PW2=1;
  449.         PD=0xff-duan[x%10];
  450.         delay(5);
  451.     }
  452.     else
  453.     {
  454.         LE=1;
  455.         PW0=0;
  456.         PW1=0;
  457.         PW2=0;
  458.         PD=0;
  459.         delay(5);
  460.     
  461.         PW0=0;
  462.         PW1=0;
  463.         PW2=1;
  464.         PD=0;
  465.         delay(5);
  466.     
  467.         PW0=0;
  468.         PW1=1;
  469.         PW2=0;
  470.         PD=0;
  471.         delay(5);
  472.     
  473.         PW0=0;
  474.         PW1=1;
  475.         PW2=1;
  476.         PD=0;
  477.         delay(5);    
  478.     }    
  479.  }
  480.  void ReadTime(void)
  481.  {
  482.       start();
  483.     i2cwrite(ADDRTC);
  484.     i2cwrite(0x0f);
  485.     i2cwrite(0); /* clear alarm flags */
  486.     stop();

  487.     start();
  488.     i2cwrite(ADDRTC);
  489.     i2cwrite(0);
  490.     start();
  491.     i2cwrite(ADDRTC | 1);
  492.     sec = i2cread(ACK);
  493.     min = i2cread(ACK);
  494.     hr = i2cread(ACK);
  495.     dy = i2cread(ACK);
  496.     dt = i2cread(ACK);
  497.     mn = i2cread(ACK);
  498.     yr = i2cread(NACK);

  499.     sec=bcd2hex(sec);
  500.     min=bcd2hex(min);
  501.     hr=bcd2hex(hr);
  502.     dy=bcd2hex(dy);
  503.     dt=bcd2hex(dt);
  504.     mn=bcd2hex(mn);
  505.     yr=bcd2hex(yr);
  506.     
  507.     stop();
  508.  }
  509.  void Set_SegDis(uchar mode,uint setdata)
  510.  {
  511.      
  512.     LE=1;

  513.     PW0=0;
  514.     PW1=0;
  515.     PW2=0;
  516.     PD=0xff-duan[mode];
  517.     delay(5);

  518.     PW0=0;
  519.     PW1=0;
  520.     PW2=1;
  521.     PD=0; //高电平显示,低电平不亮,共阴数码管
  522.     delay(5);

  523.     PW0=0;
  524.     PW1=1;
  525.     PW2=0;
  526.     PD=0xff-duan[setdata%100/10];
  527.     delay(5);

  528.     PW0=0;
  529.     PW1=1;
  530.     PW2=1;
  531.     PD=0xff-duan[setdata%10];
  532.     delay(5);    
  533.  }

  534. void Led_Test()
  535. {
  536.      char i,j;
  537.     
  538.      for(j=0;j<4;j++)
  539.      {
  540.      PW=wei[j] |(1<<5) ;
  541.          for(i=0;i<10;i++)
  542.          {
  543.              PD= 0xff-duan[i];
  544.             delay(200);
  545.          }
  546.      }
  547. }
  548. void MusicBase(uchar z)
  549. {
  550.     yy_rst=1;
  551.     delay(4);
  552.     yy_rst=0;
  553.     delay(4);
  554.     while(z>0)
  555.     {
  556.         yy_dat=1;
  557.         delay(4);
  558.         yy_dat=0;
  559.         delay(4);
  560.         z--;
  561.     }
  562.     while(!yy_busy);
  563.     //delay(100);
  564.     yy_rst=1;
  565.     delay(4);
  566.     yy_rst=0;
  567.     delay(4);
  568. }
  569. void MusicNumber(uchar z)
  570. {
  571.     if(z>10)
  572.     {
  573.         MusicBase(z/10+1);
  574.         MusicBase(z%10+1);
  575.     }
  576.     else
  577.     {
  578.          MusicBase(z+1);
  579.     }
  580. }
  581. void MusicHave10Number(uchar z)
  582. {


  583.     if(z<=10)
  584.     {
  585.         
  586.         MusicBase(z+1);
  587.     }
  588.     else if(z<=19)//19-11
  589.     {
  590.         MusicBase(11);//10
  591.         MusicBase(z%10+1);    
  592.     }
  593.     else if( z<100 )//20-99
  594.     {
  595.         MusicBase(z/10+1);
  596.         MusicBase(11);//10
  597.         if( z%10 !=0 )
  598.             MusicBase(z%10+1);
  599.     }


  600. }
  601. void MusicRingHead(void)
  602. {
  603.     MusicBase(25);
  604.     MusicBase(22);
  605. }
  606. void MusicDate(uchar year,uchar mon,uchar day)
  607. {    
  608.     MusicBase(3);
  609.     MusicBase(1);
  610.     MusicBase(year/10+1);
  611.     MusicBase(year%10+1);
  612.     MusicBase(16);

  613.     MusicHave10Number(mon);
  614.     MusicBase(17);
  615.     MusicHave10Number(day);
  616.     MusicBase(18);
  617. }
  618. void MusicTime(uchar hour,uchar min)
  619. {
  620.     
  621.     MusicHave10Number(hour);
  622.     MusicBase(13);
  623.     MusicHave10Number(min);
  624.     MusicBase(14);
  625. }
  626. void MusicRingInit(void)
  627. {

  628.     yy_rst=0;
  629.     
  630. }
  631. void MusicSayTime(uchar hour)
  632. {
  633.     MusicHave10Number(hour);
  634.     MusicBase(13);
  635. }

  636.  void MusicTemprature(float t)
  637.  {
  638.      uchar point_1;
  639.     if(t==85.0)
  640.         return;
  641.      MusicBase(23);// 现在温度是

  642.      if(t==0.0)
  643.     {
  644.         //MusicBase(1);//0 度
  645.         //MusicBase(20);
  646.         return;    
  647.     }
  648.     if(t<0)
  649.     {
  650.         t=-t;
  651.         MusicBase(31);    //
  652.     }
  653.     if(t<10)
  654.     {
  655.         point_1=((uint)(t*10))%10;

  656.         MusicBase( (uint)(t)/10);
  657.         if(point_1!=0)
  658.         {
  659.         MusicBase(13);//"."
  660.         MusicBase( ((uint)(t*10))%10 +1 );
  661.         }
  662.         MusicBase(20);
  663.         return;
  664.     }
  665.     if(t<100)
  666.     {
  667.         MusicHave10Number( (uint)(t) );
  668.         
  669.         point_1= ((uint)(t*10))%10;
  670.         if(point_1!=0)
  671.         {
  672.             MusicBase(13);//"."
  673.             MusicBase( ((uint)(t*10))%10 +1 );
  674.         }
  675.         MusicBase(20);    
  676.         return;
  677.     }
  678.  }
  679.  
  680. void MusciWeek(uchar week)
  681. {
  682.     MusicBase(19);
  683.     MusicBase(week+1);
  684. }
  685. void LedShine(uint sec)
  686. {
  687.     LED1=CHECK_BIT(sec,0);
  688.     LED2=CHECK_BIT(sec,1);
  689.     LED3=CHECK_BIT(sec,2);
  690.     LED4=CHECK_BIT(sec,3);
  691.     LED5=CHECK_BIT(sec,4);
  692. }
  693. uchar KeyScan_SetDS3232(uchar settmp)
  694. {
  695.          if( (key2==0) &&(key1))
  696.         {
  697.             delay(300);
  698.             if(key2==0)
  699.             {
  700.             settmp++;
  701.             if(settmp>99)
  702.                 settmp=0;
  703.             }
  704.         }
  705.     
  706.         if( (key3==0) && (key1) )
  707.         {
  708.             delay(300);
  709.             if(key3==0)
  710.             {
  711.             settmp--;
  712.             if(settmp<=0)
  713.                 settmp=99;
  714.             }
  715.         }
  716.         return settmp;
  717. }
  718. void HardTestCmd(uchar uch_Cmd)
  719. {    
  720.     switch(uch_Cmd)
  721.     {
  722.         case CMD_RING_TMP:
  723.         
  724.         ;
  725.         case CMD_RING_TIME:
  726.          //    MusicRingHead();
  727.             MusicTime(hr,min);
  728.         ;break;
  729.         case CMD_RING_DATE:
  730.         //    MusicRingHead();
  731.             MusicDate(yr,mn,dt);
  732.         ;break;
  733.     }
  734. }
  735. void ComParse(void)
  736. {
  737.     date_time_t *pdt;
  738.     int ilp;
  739.     if(g_rx.byIntFlag==1)
  740.     {
  741.         g_rx.dwOutCnt++;
  742.         if(    g_rx.dwOutCnt>10)
  743.         {
  744.              g_rx.dwOutCnt=0;
  745.              if(g_rx.byWritePoint==8)
  746.              {
  747.                   pdt=(date_time_t *)g_rx.byRxBuf;

  748.                 if(pdt->time.week>7)
  749.                 {
  750.                     HardTestCmd(pdt->time.week);
  751.                     pdt->time.week = 7;
  752.                 }
  753.                 else
  754.                 {
  755.                     for(ilp=0;ilp<8;ilp++)
  756.                     {
  757.                         //delay(100);lz20150801
  758.                         uart_putchar(g_rx.byRxBuf[ilp]);
  759.                     }
  760.                     pdt->date.year=g_rx.byRxBuf[0]+g_rx.byRxBuf[1]*256-2000;
  761.                     yr=    pdt->date.year;
  762.                     mn= pdt->date.month;
  763.                     dt= pdt->date.day;
  764.     
  765.                     dy= pdt->time.week;
  766.                     hr= pdt->time.hour;
  767.                     min=pdt->time.minute;
  768.                     sec=pdt->time.second;
  769.     
  770.                     ReInitialDS3232();
  771.                     g_rx.byIntFlag=0;
  772.                     g_rx.byWritePoint=0;
  773.                      g_rx.dwOutCnt=0;
  774.                 }
  775.             
  776.              }
  777.              else
  778.              {
  779.                  g_rx.byIntFlag=0;
  780.                 g_rx.byWritePoint=0;
  781.                  g_rx.dwOutCnt=0;
  782.              }
  783.         }
  784.     }
  785. }
  786. void SetDS3232(void)
  787. {
  788.     uchar settmp;
  789.     uchar mode=1;
  790.     uint tick;
  791.     while( !key1 ) //key1 pressed
  792.     {
  793.          Seg_DisPlay(tick);
  794.         if(tick++>200)
  795.         {
  796.             while(key1)//等待key1松掉
  797.             {
  798.                 Seg_DisPlay(tick);    
  799.             }
  800.             
  801.             delay(2000);
  802.             ReadTime();
  803.             while(1)//main loop
  804.             {
  805.                 if(key1==0)
  806.                 {
  807.                     delay(300);
  808.                     if(key1==0)
  809.                     {
  810.                             mode++;
  811.                             if(mode>7)
  812.                             mode=1;    
  813.                     }
  814.                 }
  815.             
  816.                 switch(mode)
  817.                 {
  818.                     case 1:settmp=yr;break;
  819.                     case 2:settmp=mn;break;
  820.                     case 3:settmp=dt;break;
  821.                     case 4:settmp=hr;break;
  822.                     case 5:settmp=min;break;
  823.                     case 6:settmp=sec;break;
  824.                     case 7:settmp=dy;break;//星期
  825.                 }
  826.                 settmp=KeyScan_SetDS3232(settmp);
  827.                 switch(mode) //write
  828.                 {
  829.                     case 1:yr=settmp;break;
  830.                     case 2:mn=settmp;break;
  831.                     case 3:dt=settmp;break;
  832.                     case 4:hr=settmp;break;
  833.                     case 5:min=settmp;break;
  834.                     case 6:sec=settmp;break;
  835.                     case 7:dy=settmp;break;//星期    
  836.                 }
  837.                 if( (key1==0) && (key2==0) )
  838.                 {
  839.                 
  840.                     delay(600);
  841.                     if( (key1==0) && (key2==0) )
  842.                     {
  843.                          ReInitialDS3232();
  844.                          tick=600;
  845.                          while(tick-->0)
  846.                          {
  847.                               Seg_DisPlay(tick);
  848.                          }
  849.                         
  850.                          goto out;
  851.                     }
  852.                 }
  853.                 Set_SegDis(mode,settmp);

  854.             }//end of main loop
  855.         }
  856.     }
  857.     out:;
  858. }
  859. ////xdata uchar sec, min, hr, dy, dt, mn, yr;
  860. void main (void) /* ------------------------------------------------ */
  861. {
  862.     uint tick=0;
  863.     uint ul_systick=0;
  864.     float ftmp;
  865.     uint xdata dwtmp,dwTickPressedKey=0;
  866.     uchar secset=0;

  867.     uchar bflag=0;
  868.     unsigned char xdata yl_month,yl_day;
  869.     unsigned short xdata yl_year;

  870.     comm_init();
  871.     uart_init();
  872.     MusicRingInit();
  873.     //initialize_DS3232();
  874.     //init_alrm(); /* enable alarm */
  875.       SetDS3232();

  876.     while(1)
  877.     {

  878.      ComParse();
  879.         //P1=0xFf-sec;
  880.          // rd_temp();
  881.          ul_systick++;
  882.         
  883.          disp_regs();
  884.          if( (hr>=7) && (hr<=21) )
  885.          {
  886.              g_bNotDisSeg=0;//早上7点到晚上8点之间,数码管可以由关闭状态自动恢复
  887.          }
  888.          if( (hr>=8) && (hr<=21)) //早上8点到晚上24点led闪烁,其他时间不闪烁,影响睡眠
  889.          {
  890.                  if(!g_bNotDisSeg)
  891.                      LedShine(g_uchLedTab[ ul_systick/30%TAB_NUM ] );
  892.                 else
  893.                     LedShine(0);
  894.          }
  895.          else
  896.          {
  897.               LedShine(0);
  898.          }
  899.               if( (!key2)&&(!key3)==1)
  900.              {
  901.                      MusicRingHead();
  902.                     MusicTime(hr,min);
  903.                 
  904.                      Seg_DisPlay( (mn*100+dt) );
  905.              }
  906.              if( (!key1)&&(!key3) )
  907.              {
  908.                       MusicRingHead();
  909.                     MusicDate(yr,mn,dt);
  910.                     MusicTime(hr,min);
  911.                      Seg_DisPlay( (mn*100+dt) );
  912.              }
  913.              if(key1==0)
  914.              {
  915.                  if(key2==0)
  916.                      tick++;
  917.                     bflag=0;

  918.                  Seg_DisPlay( (mn*100+dt) );
  919.                  g_bNotDisSeg=0;//恢复数码管显示
  920.             
  921.              }
  922.              else if(key2==0)
  923.              {
  924.                      GetLunar(2000+yr,mn,dt,&yl_year,&yl_month,&yl_day);
  925.                      Seg_DisPlay( (yl_month*100) + yl_day );
  926.                     //Seg_DisPlay(yr );
  927.                     if( (key1!=0) && (key3!=0) )
  928.                         dwTickPressedKey++;
  929.                     else
  930.                         dwTickPressedKey=0;
  931.                         
  932.                     if(dwTickPressedKey>=350)//长按5s
  933.                     {
  934.                         dwTickPressedKey=0;
  935.                         g_bNotDisSeg=1;    //关闭数码管显示
  936.                     }
  937.              }
  938.              else if(key3==0)//显示温度和星期2314-->23.1摄氏度,星期4
  939.              {
  940.                      g_bNotDisSeg=0;//恢复数码管显示
  941.                      ftmp=ReadTemperature();
  942.                     if (ftmp == 85.0)
  943.                             ftmp=ReadTemperature();
  944.                     if( (ftmp>=0) && (ftmp<100) )
  945.                     {
  946.                      dwtmp=ftmp*10;
  947.                      Seg_DisPlay( (dwtmp*10+dy) );
  948.                     
  949.                     }
  950.                     else
  951.                     {
  952.                         Seg_DisPlay( (dy) );
  953.                     }                    
  954.                     MusicTemprature(ftmp);
  955.                     MusciWeek(dy);
  956.              }
  957.              else
  958.              {
  959.                      Seg_DisPlay( (hr*100+min) );
  960.              }
  961.     
  962.              if ( (min==30) && (hr==7) &&(sec<2) )
  963.              {
  964.                       MusicTime(hr,min);;
  965.              }
  966.              if(min==0)
  967.              {
  968.                       if(hr>=8 && hr<=23 && sec<1)
  969.                     {    
  970.                          MusicSayTime(hr);
  971.                     }
  972.                      if(hr!=12 && sec<3)
  973.                      {
  974.                         RING=0;
  975.                         JDQ=0;
  976.                     }
  977.                     else if(hr==12 && sec<5)
  978.                     {
  979.                         RING=0;
  980.                         JDQ=0;
  981.                     }
  982.              }
  983.             
  984.                 else
  985.                 {
  986.                   RING=1;
  987.                     JDQ=1;
  988.                  }
  989.          
  990.               if(tick>300)
  991.              {
  992.                      tick=0;
  993.                     secset=sec;
  994.                      while(1)
  995.                     {
  996.                         Seg_DisPlay(secset);
  997.                         
  998.                         if(key2==0 && key1!=0)
  999.                         {
  1000.                             
  1001.                             if(secset<59)
  1002.                             {secset++;;}
  1003.                             bflag=1    ;
  1004.                             tick=0;
  1005.                             delay(100);
  1006.                         }    
  1007.                         else if(key3==0)
  1008.                         {
  1009.                             if(secset>0)
  1010.                             {
  1011.                                 secset--;
  1012.                             
  1013.                             }
  1014.                                 bflag=1;
  1015.                                 tick=0;
  1016.                                 delay(100);
  1017.                         }
  1018.                         if( (key1==0) && (bflag==1) )
  1019.                         {
  1020.                             tick++;
  1021.                         }
  1022.                         if(tick>2)
  1023.                         {
  1024.                             tick=0;
  1025.                             bflag=0;
  1026.                             min=hex2bcd(min);
  1027.                             secset=hex2bcd(secset);
  1028.                             start();
  1029.                             i2cwrite(ADDRTC); /* write slave address, write 1339 */
  1030.                          i2cwrite(0x00); /* write register address, 1st clock register */
  1031.                          i2cwrite(secset);
  1032.                             i2cwrite(min);
  1033.                          stop();    
  1034.                             delay(10);
  1035.                             break;
  1036.                         }
  1037.                     }
  1038.              }
  1039.         
  1040.         
  1041.          //delay(3000);
  1042.         
  1043.     }

  1044. }
calender.c

点击(此处)折叠或打开

  1. /*
  2. 文件名:    calender.c
  3. 作者:        
  4. 创建日期:    2014.5.27
  5. 功能:        将公历转换成农历
  6. */
  7. #include "config.h"


  8. UINT8 code year_code[597]={
  9. 0x04,0xAe,0x53,0x0A,0x57,0x48,0x55,0x26,0xBd, // 1901-1903
  10. 0x0d,0x26,0x50,0x0d,0x95,0x44,0x46,0xAA,0xB9, // 1904-1906
  11. 0x05,0x6A,0x4d,0x09,0xAd,0x42,0x24,0xAe,0xB6, // 1907-1909
  12. 0x04,0xAe,0x4A,0x6A,0x4d,0xBe,0x0A,0x4d,0x52, // 1910-1912
  13. 0x0d,0x25,0x46,0x5d,0x52,0xBA,0x0B,0x54,0x4e, // 1913-1915
  14. 0x0d,0x6A,0x43,0x29,0x6d,0x37,0x09,0x5B,0x4B, // 1916-1918
  15. 0x74,0x9B,0xC1,0x04,0x97,0x54,0x0A,0x4B,0x48, // 1919-1921
  16. 0x5B,0x25,0xBC,0x06,0xA5,0x50,0x06,0xd4,0x45, // 1922-1924
  17. 0x4A,0xdA,0xB8,0x02,0xB6,0x4d,0x09,0x57,0x42, // 1925-1927
  18. 0x24,0x97,0xB7,0x04,0x97,0x4A,0x66,0x4B,0x3e, // 1928-1930
  19. 0x0d,0x4A,0x51,0x0e,0xA5,0x46,0x56,0xd4,0xBA, // 1931-1933
  20. 0x05,0xAd,0x4e,0x02,0xB6,0x44,0x39,0x37,0x38, // 1934-1936
  21. 0x09,0x2e,0x4B,0x7C,0x96,0xBf,0x0C,0x95,0x53, // 1937-1939
  22. 0x0d,0x4A,0x48,0x6d,0xA5,0x3B,0x0B,0x55,0x4f, // 1940-1942
  23. 0x05,0x6A,0x45,0x4A,0xAd,0xB9,0x02,0x5d,0x4d, // 1943-1945
  24. 0x09,0x2d,0x42,0x2C,0x95,0xB6,0x0A,0x95,0x4A, // 1946-1948
  25. 0x7B,0x4A,0xBd,0x06,0xCA,0x51,0x0B,0x55,0x46, // 1949-1951
  26. 0x55,0x5A,0xBB,0x04,0xdA,0x4e,0x0A,0x5B,0x43, // 1952-1954
  27. 0x35,0x2B,0xB8,0x05,0x2B,0x4C,0x8A,0x95,0x3f, // 1955-1957
  28. 0x0e,0x95,0x52,0x06,0xAA,0x48,0x7A,0xd5,0x3C, // 1958-1960
  29. 0x0A,0xB5,0x4f,0x04,0xB6,0x45,0x4A,0x57,0x39, // 1961-1963
  30. 0x0A,0x57,0x4d,0x05,0x26,0x42,0x3e,0x93,0x35, // 1964-1966
  31. 0x0d,0x95,0x49,0x75,0xAA,0xBe,0x05,0x6A,0x51, // 1967-1969
  32. 0x09,0x6d,0x46,0x54,0xAe,0xBB,0x04,0xAd,0x4f, // 1970-1972
  33. 0x0A,0x4d,0x43,0x4d,0x26,0xB7,0x0d,0x25,0x4B, // 1973-1975
  34. 0x8d,0x52,0xBf,0x0B,0x54,0x52,0x0B,0x6A,0x47, // 1976-1978
  35. 0x69,0x6d,0x3C,0x09,0x5B,0x50,0x04,0x9B,0x45, // 1979-1981
  36. 0x4A,0x4B,0xB9,0x0A,0x4B,0x4d,0xAB,0x25,0xC2, // 1982-1984
  37. 0x06,0xA5,0x54,0x06,0xd4,0x49,0x6A,0xdA,0x3d, // 1985-1987
  38. 0x0A,0xB6,0x51,0x09,0x37,0x46,0x54,0x97,0xBB, // 1988-1990
  39. 0x04,0x97,0x4f,0x06,0x4B,0x44,0x36,0xA5,0x37, // 1991-1993
  40. 0x0e,0xA5,0x4A,0x86,0xB2,0xBf,0x05,0xAC,0x53, // 1994-1996
  41. 0x0A,0xB6,0x47,0x59,0x36,0xBC,0x09,0x2e,0x50, // 1997-1999
  42. 0x0C,0x96,0x45,0x4d,0x4A,0xB8,0x0d,0x4A,0x4C, // 2000-2002
  43. 0x0d,0xA5,0x41,0x25,0xAA,0xB6,0x05,0x6A,0x49, // 2003-2005
  44. 0x7A,0xAd,0xBd,0x02,0x5d,0x52,0x09,0x2d,0x47, // 2006-2008
  45. 0x5C,0x95,0xBA,0x0A,0x95,0x4e,0x0B,0x4A,0x43, // 2009-2011
  46. 0x4B,0x55,0x37,0x0A,0xd5,0x4A,0x95,0x5A,0xBf, // 2012-2014
  47. 0x04,0xBA,0x53,0x0A,0x5B,0x48,0x65,0x2B,0xBC, // 2015-2017
  48. 0x05,0x2B,0x50,0x0A,0x93,0x45,0x47,0x4A,0xB9, // 2018-2020
  49. 0x06,0xAA,0x4C,0x0A,0xd5,0x41,0x24,0xdA,0xB6, // 2021-2023
  50. 0x04,0xB6,0x4A,0x69,0x57,0x3d,0x0A,0x4e,0x51, // 2024-2026
  51. 0x0d,0x26,0x46,0x5e,0x93,0x3A,0x0d,0x53,0x4d, // 2027-2029
  52. 0x05,0xAA,0x43,0x36,0xB5,0x37,0x09,0x6d,0x4B, // 2030-2032
  53. 0xB4,0xAe,0xBf,0x04,0xAd,0x53,0x0A,0x4d,0x48, // 2033-2035
  54. 0x6d,0x25,0xBC,0x0d,0x25,0x4f,0x0d,0x52,0x44, // 2036-2038
  55. 0x5d,0xAA,0x38,0x0B,0x5A,0x4C,0x05,0x6d,0x41, // 2039-2041
  56. 0x24,0xAd,0xB6,0x04,0x9B,0x4A,0x7A,0x4B,0xBe, // 2042-2044
  57. 0x0A,0x4B,0x51,0x0A,0xA5,0x46,0x5B,0x52,0xBA, // 2045-2047
  58. 0x06,0xd2,0x4e,0x0A,0xdA,0x42,0x35,0x5B,0x37, // 2048-2050
  59. 0x09,0x37,0x4B,0x84,0x97,0xC1,0x04,0x97,0x53, // 2051-2053
  60. 0x06,0x4B,0x48,0x66,0xA5,0x3C,0x0e,0xA5,0x4f, // 2054-2056
  61. 0x06,0xB2,0x44,0x4A,0xB6,0x38,0x0A,0xAe,0x4C, // 2057-2059
  62. 0x09,0x2e,0x42,0x3C,0x97,0x35,0x0C,0x96,0x49, // 2060-2062
  63. 0x7d,0x4A,0xBd,0x0d,0x4A,0x51,0x0d,0xA5,0x45, // 2063-2065
  64. 0x55,0xAA,0xBA,0x05,0x6A,0x4e,0x0A,0x6d,0x43, // 2066-2068
  65. 0x45,0x2e,0xB7,0x05,0x2d,0x4B,0x8A,0x95,0xBf, // 2069-2071
  66. 0x0A,0x95,0x53,0x0B,0x4A,0x47,0x6B,0x55,0x3B, // 2072-2074
  67. 0x0A,0xd5,0x4f,0x05,0x5A,0x45,0x4A,0x5d,0x38, // 2075-2077
  68. 0x0A,0x5B,0x4C,0x05,0x2B,0x42,0x3A,0x93,0xB6, // 2078-2080
  69. 0x06,0x93,0x49,0x77,0x29,0xBd,0x06,0xAA,0x51, // 2081-2083
  70. 0x0A,0xd5,0x46,0x54,0xdA,0xBA,0x04,0xB6,0x4e, // 2084-2086
  71. 0x0A,0x57,0x43,0x45,0x27,0x38,0x0d,0x26,0x4A, // 2087-2089
  72. 0x8e,0x93,0x3e,0x0d,0x52,0x52,0x0d,0xAA,0x47, // 2090-2092
  73. 0x66,0xB5,0x3B,0x05,0x6d,0x4f,0x04,0xAe,0x45, // 2093-2095
  74. 0x4A,0x4e,0xB9,0x0A,0x4d,0x4C,0x0d,0x15,0x41, // 2096-2098
  75. 0x2d,0x92,0xB5, // 2099
  76. };
  77. //月份天数数据表
  78. static code UINT8 day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
  79. static code UINT16 day_code2[3]={0x111,0x130,0x14e};



  80. static bit Get_Moon_Day(UINT8 month_p,UINT16 code_addr) //读取数据表中农历月的大月或小月,如果该月大返回1,小返回0*/
  81. {
  82.     UINT8 temp,temp1;
  83.     temp1=(month_p+3)/8;
  84.     temp=0x80>>((month_p+3)%8);
  85.     temp=year_code[code_addr+temp1]&temp;
  86.     if(temp==0){return(0);}else{return(1);}
  87. }
  88. unsigned int rotate_right(unsigned int x, int n)
  89. {
  90.  int save;
  91.  int i;
  92.  for(i=0;i<n;i++)
  93.  {
  94.  save=x&0x00000001;
  95.  x=x>>1;
  96.  save=save<<7;
  97.  x+=save;
  98.  }
  99.  return x;
  100. }
  101. void GetLunar(UINT16 year_src,UINT8 month,UINT8 day,UINT16 *Year,UINT8 *Month,UINT8 *Day)//,UINT8 *MonthDay)
  102. {
  103.    
  104.     UINT8 xdata temp1,temp2,temp3,month_p,year;
  105.     UINT16 xdata temp4,code_addr,year_tmp;
  106.     bit flag2,flag_y;
  107.     UINT8 xdata year_h,year_l;

  108.     year_tmp=year_src;
  109.     year_h=year_src/100; year_l=year_src%100; //求出高位和低位
  110.     year=year_l;
  111.     code_addr=year-1; //定位数据表地址
  112.     if(year_h>19)code_addr+=0x64;
  113.     code_addr*=3;


  114.     temp1=year_code[code_addr+2]&0x60; //取当年春节所在的公历月份
  115.     temp1=rotate_right(temp1,5);
  116.    
  117.     temp2=year_code[code_addr+2]&0x1f; //取当年春节所在的公历日
  118.    
  119.     temp3=temp2-1; //计算当年春节离当年元旦的天数,春节只会在公历1月或2月
  120.     if(temp1!=1)temp3+=0x1f;

  121.     if(month<10)
  122.         {
  123.                 temp4=day_code1[month-1]+day-1;
  124.         }
  125.     else
  126.         {
  127.                 temp4=day_code2[month-10]+day-1;
  128.         }

  129.     if((month>2)&&(year%0x04==0))temp4+=1; //如果公历月小于2月或者该年的2月非闰月,天数减1
  130.      
  131.     if (temp4>=temp3) //判断公历日在春节前还是春节后
  132.     {
  133.         //公历日在春节后或就是春节当日使用下面代码进行运算
  134.         temp4 -=temp3;
  135.         month = 1;
  136.         flag_y = 0;
  137.         month_p= 1; //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月

  138.         flag2=Get_Moon_Day(month_p,code_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0
  139.                
  140.         if(flag2==0){temp1=29;}else{temp1=30;} //小月29天、大月30天
  141.                
  142.            
  143.         temp2=year_code[code_addr]&0xf0;
  144.         temp2=rotate_right(temp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月
  145.         while(temp4>=temp1)
  146.        {
  147.             temp4-=temp1;
  148.             month_p+=1;
  149.             if(month==temp2)
  150.             {
  151.                 flag_y=~flag_y;
  152.                 if(flag_y==0)month+=1;
  153.             }
  154.             else month+=1;
  155.             flag2=Get_Moon_Day(month_p,code_addr);
  156.             if(flag2==0)temp1=0x1d;
  157.             else temp1=0x1e;
  158.                        
  159.         }
  160.         day=temp4+1;

  161.     }
  162.     else
  163.     {
  164.         //公历日在春节前使用下面代码进行运算
  165.         temp3-=temp4;
  166.         if(year==0){year=99;year_h=19;}else{year-=1;}
  167.         code_addr-=3;
  168.         month = 0x0c;
  169.         temp2 = year_code[code_addr]&0xf0;
  170.         temp2 = rotate_right(temp2,4);
  171.         flag_y = 0;
  172.         if(temp2==0){month_p=12;}else{month_p=13;} //如果当年有闰月,一年有十三个月,月指向13,无闰月指向12
  173.         
  174.         flag2=Get_Moon_Day(month_p,code_addr);
  175.         if(flag2==0){temp1=29;}else{temp1=30;}


  176.         while(temp3>temp1)
  177.        {
  178.             temp3-=temp1;
  179.             month_p-=1;
  180.             if(flag_y==0)month-=1;
  181.             if(month==temp2)flag_y=~flag_y;
  182.             flag2=Get_Moon_Day(month_p,code_addr);
  183.             if(flag2==0){temp1=0x1d;}else{temp1=0x1e;}
  184.         }
  185.         day=temp1-temp3+1;
  186.     }
  187.    //*MonthDay=temp1;//农历的天数
  188.    *Year =((UINT16)year_h*100)+(UINT16)year; //将农历信息写进指定变量
  189.    *Month = month;
  190.    *Day = day;
  191. }
  192. int calender_test(int argc, char* argv[])
  193. {
  194.     UINT16 year;
  195.     UINT8 mon,day,monday;
  196.     UINT16 y;
  197.     UINT8 m,d;

  198.     while(1)
  199.     {
  200.         //printf("please input date\r\n");
  201.         //scanf("%d%d%d",&y,&m,&d);
  202.         //printf("intput date is %d-%d-%d\r\n",y,m,d);

  203.         GetLunar(y,m,d,&year,&mon,&day);//,&monday);

  204.         //printf("output date is %d-%d-%d,%d\r\n",year,mon,day,monday);

  205.     }
  206.     
  207.     return 0;
  208. }


上位机部分:
timeDlg.cpp

点击(此处)折叠或打开

  1. // timeDlg.cpp : implementation file
  2. //

  3. #include "stdafx.h"
  4. #include "ComConfig.h"
  5. #include "timeDlg.h"
  6. #include "Proctol.h"
  7. #include "ComConfigDlg.h"

  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif

  13. /////////////////////////////////////////////////////////////////////////////
  14. // timeDlg dialog


  15. timeDlg::timeDlg(CWnd* pParent /*=NULL*/)
  16.     : CDialog(timeDlg::IDD, pParent)
  17. {
  18.     //{{AFX_DATA_INIT(timeDlg)
  19.     m_edit_year = 2015;
  20.     m_edit_month = 2;
  21.     m_edit_day = 11;
  22.     m_edit_hour = 16;
  23.     m_edit_minute = 55;
  24.     m_edit_second = 33;
  25.     
  26.     //}}AFX_DATA_INIT
  27. }


  28. void timeDlg::DoDataExchange(CDataExchange* pDX)
  29. {
  30.     CDialog::DoDataExchange(pDX);
  31.     //{{AFX_DATA_MAP(timeDlg)
  32.     DDX_Text(pDX, IDC_EDIT_YEAR, m_edit_year);
  33.     DDX_Text(pDX, IDC_EDIT_MONTH, m_edit_month);
  34.     DDX_Text(pDX, IDC_EDIT_DAY, m_edit_day);
  35.     DDX_Text(pDX, IDC_EDIT_HOUR, m_edit_hour);
  36.     DDX_Text(pDX, IDC_EDIT_MINUTE, m_edit_minute);
  37.     DDX_Text(pDX, IDC_EDIT_SECOND, m_edit_second);
  38.     //}}AFX_DATA_MAP
  39. }


  40. BEGIN_MESSAGE_MAP(timeDlg, CDialog)
  41.     //{{AFX_MSG_MAP(timeDlg)
  42.     ON_BN_CLICKED(IDC_BUTTON_USE, OnButtonUse)
  43.     ON_BN_CLICKED(IDC_BUTTON_WRITE, OnButtonWrite)
  44.     ON_BN_CLICKED(IDC_BUTTON_DIRECTWRITE, OnButtonDirectwrite)
  45.     ON_BN_CLICKED(IDC_BUTTON_RING_TM, OnButtonRingTm)
  46.     ON_BN_CLICKED(IDC_BUTTON_RING_DT, OnButtonRingDt)
  47.     //}}AFX_MSG_MAP
  48. END_MESSAGE_MAP()

  49. /////////////////////////////////////////////////////////////////////////////
  50. // timeDlg message handlers

  51. void timeDlg::OnButtonUse()
  52. {
  53.     // TODO: Add your control notification handler code here
  54.     CTime mytime=CTime::GetCurrentTime();

  55.     date_time_t date;
  56.     
  57.     date.date.year=mytime.GetYear();
  58.     date.date.month    =mytime.GetMonth();
  59.     date.date.day    =mytime.GetDay();

  60.     date.time.hour    =mytime.GetHour();
  61.     date.time.minute=mytime.GetMinute();
  62.     date.time.second=mytime.GetSecond();

  63.     char temp[5]={0x67,0x01,0x00,0x22,0x00};
  64.     

  65.     printf("%d %d\r\n",sizeof(temp),strlen(temp));
  66.     
  67.     m_port.WriteToPort(temp,5);

  68. }



  69. bool timeDlg::OpenLastPort()
  70. {
  71.     CString strCom[5];
  72.     //InitSlider(1,80,10);
  73.     int exitingSerialNumber=m_port.EnumAllComPort(strCom);
  74.     char szBuf[100];
  75.     
  76.     if ( exitingSerialNumber>0 )
  77.     {
  78.     
  79.             DWORD dwComPort;    
  80.             char szTmp[10];
  81.             strcpy(szTmp,strCom[exitingSerialNumber-1]);
  82.             dwComPort=(DWORD)atoi(szTmp+3);
  83.             for(int i=0;i<exitingSerialNumber;i++)    
  84.                 printf("%s\r\n",strCom[i]);
  85.             if(    m_port.InitPort(this,dwComPort, 4800) )
  86.             {
  87.                     printf("use %s\r\n",strCom[exitingSerialNumber-1]);
  88.                     sprintf(szBuf,"use %s\r\n",strCom[exitingSerialNumber-1]);
  89.                     WriteinfoDisplay(szBuf,TP_NEW);

  90.                     m_port.StartMonitoring();
  91.                     m_port.m_bSerialPortIsOpen=TRUE;
  92.             }
  93.             else
  94.             {
  95.                 printf("open %s baud 4800 error\r\n",strCom[exitingSerialNumber-1]);
  96.                 sprintf("open %s baud 4800 error\r\n",strCom[exitingSerialNumber-1]);
  97.                 WriteinfoDisplay(szBuf,TP_NEW);

  98.             }
  99.     }
  100.     else
  101.     {
  102.         printf("没有有效可以打开的串口\r\n");
  103.         WriteinfoDisplay("没有有效可以打开的串口\r\n",TP_NEW);
  104.     }
  105.     return TRUE;
  106. }

  107. BOOL timeDlg::OnInitDialog()
  108. {
  109.     CDialog::OnInitDialog();
  110.     
  111.     // TODO: Add extra initialization here
  112.     OpenLastPort();
  113.     return TRUE; // return TRUE unless you set the focus to a control
  114.      // EXCEPTION: OCX Property Pages should return FALSE
  115. }
  116. //根据年月日计算星期
  117. BYTE GetWeekday(DWORD year,BYTE mon,BYTE day)
  118. {
  119.     DWORD r[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};
  120.     year %= 400;
  121.     if((year==0||year%4==0&&year%100!=0)&&mon<3)
  122.         return BYTE((year+year/4-year/100+r[mon]+day+5)%7);
  123.     else
  124.         return BYTE((year+year/4-year/100+r[mon]+day+6)%7);
  125. }
  126. //与电脑系统时间对时,系统对时
  127. void timeDlg::OnButtonWrite()
  128. {
  129.     // TODO: Add your control notification handler code here
  130.     date_time_t mdate;
  131.     CTime mytime=CTime::GetCurrentTime();
  132.     WORD wLen;
  133.     char szBuf[100];
  134.     mdate.date.year=mytime.GetYear();
  135.     mdate.date.month    =mytime.GetMonth();
  136.     mdate.date.day    =mytime.GetDay();

  137.     mdate.time.hour    =mytime.GetHour();
  138.     mdate.time.minute=mytime.GetMinute();
  139.     mdate.time.second=mytime.GetSecond();
  140.     mdate.time.week=GetWeekday(mdate.date.year,    mdate.date.month,    mdate.date.day);
  141.     printf("系统设定时间为:%04d-%02d-%02d,%02d:%02d,%d:%02d\r\n",
  142.     mdate.date.year,mdate.date.month,mdate.date.day,
  143.     mdate.time.hour,mdate.time.minute,mdate.time.second,
  144.     mdate.time.week);
  145.     wLen=sizeof(mdate);

  146.     sprintf(szBuf,"系统设定时间为:%04d-%02d-%02d,%02d:%02d,%d:%02d\r\n",
  147.     mdate.date.year,mdate.date.month,mdate.date.day,
  148.     mdate.time.hour,mdate.time.minute,mdate.time.second,
  149.     mdate.time.week);
  150.     wLen=sizeof(mdate);
  151.     
  152.     WriteinfoDisplay(szBuf,TP_ADD);
  153.     m_port.ClearComRecvFifo();//很重要,下位机发送串口数据可能存在多余乱码
  154.     try
  155.     {
  156.         m_port.WriteToPort( (char *)&mdate,sizeof(mdate) );
  157.     }
  158.     catch (...)
  159.     {
  160.         AfxMessageBox("串口无效");
  161.     }
  162. }
  163. //将界面设置时间对时,手动对时
  164. void timeDlg::OnButtonDirectwrite()
  165. {
  166.     // TODO: Add your control notification handler code here
  167.     char szBuf[100];
  168.     CComConfigDlg *dlg=(CComConfigDlg *)AfxGetMainWnd();

  169.     UpdateData(TRUE);
  170.     date_time_t date;
  171.     date.date.year=m_edit_year;
  172.     date.date.month    =m_edit_month;
  173.     date.date.day    =m_edit_day;
  174.     date.time.hour    =m_edit_hour;
  175.     date.time.minute=m_edit_minute;
  176.     date.time.second=m_edit_second;
  177.     date.time.week    =0;//无效,单片机根据写入的年月日计算出星期
  178.     printf("手动设定时间为:%04d-%02d-%02d,%02d:%02d,%d:%02d\r\n",
  179.     date.date.year,date.date.month,date.date.day,
  180.     date.time.hour,date.time.minute,date.time.second,
  181.     date.time.week);
  182.     sprintf(szBuf,"手动设定时间为:%04d-%02d-%02d,%02d:%02d,%d:%02d\r\n",
  183.     date.date.year,date.date.month,date.date.day,
  184.     date.time.hour,date.time.minute,date.time.second,
  185.     date.time.week);
  186.     WriteinfoDisplay(szBuf,TP_ADD);
  187.     m_port.ClearComRecvFifo();//很重要,下位机发送串口数据可能存在多余乱码
  188.     try
  189.     {
  190.         m_port.WriteToPort( (char *)&date,sizeof(date) );
  191.     }
  192.     catch (...)
  193.     {
  194.         AfxMessageBox("串口无效");
  195.     }


  196. //    dlg->m_cmod.SavePLC( &(dlg->m_cmod) );
  197. }

  198. void timeDlg::OnButtonRingTm()
  199. {
  200.     // TODO: Add your control notification handler code here
  201.     date_time_t mdate;
  202.         CTime mytime=CTime::GetCurrentTime();

  203.     mdate.date.year=mytime.GetYear();
  204.     mdate.date.month    =mytime.GetMonth();
  205.     mdate.date.day    =mytime.GetDay();

  206.     mdate.time.hour    =mytime.GetHour();
  207.     mdate.time.minute=mytime.GetMinute();
  208.     mdate.time.second=mytime.GetSecond();
  209.     mdate.time.week    =CMD_RING_TIME;
  210.     m_port.ClearComRecvFifo();//很重要,下位机发送串口数据可能存在多余乱码
  211.     try
  212.     {
  213.         m_port.WriteToPort( (char *)&mdate,sizeof(mdate) );
  214.     }
  215.     catch (...)
  216.     {
  217.         AfxMessageBox("串口无效");
  218.     }
  219. }

  220. void timeDlg::OnButtonRingDt()
  221. {
  222.     // TODO: Add your control notification handler code here
  223.     date_time_t mdate;
  224.     CTime mytime=CTime::GetCurrentTime();
  225.     mdate.date.year=mytime.GetYear();
  226.     mdate.date.month    =mytime.GetMonth();
  227.     mdate.date.day    =mytime.GetDay();

  228.     mdate.time.hour    =mytime.GetHour();
  229.     mdate.time.minute=mytime.GetMinute();
  230.     mdate.time.second=mytime.GetSecond();
  231.     mdate.time.week    =CMD_RING_DATE;
  232.     m_port.ClearComRecvFifo();//很重要,下位机发送串口数据可能存在多余乱码
  233.     try
  234.     {
  235.         m_port.WriteToPort( (char *)&mdate,sizeof(mdate) );
  236.     }
  237.     catch (...)
  238.     {
  239.         AfxMessageBox("串口无效");
  240.     }
  241. }

  242. void timeDlg::WriteinfoDisplay(CString strInfo,BYTE byType)
  243. {
  244.     static CString strDis;
  245.     CString strTmp;
  246.     static char szLine =0;
  247.     switch(byType)
  248.     {
  249.         case TP_ADD:
  250.         strDis +=strInfo;
  251.         break;
  252.         case TP_NEW:
  253.         strDis = strInfo;
  254.         break;
  255.         case TP_CLEAR:
  256.         strDis="";
  257.         break;
  258.     }
  259.     szLine ++;
  260.     GetDlgItem(IDC_STATIC_INFO)->SetWindowText(strDis);
  261.     if(szLine >=11)
  262.     {
  263.         szLine =0;
  264.         strDis ="";
  265.     }
  266. }
CSerial.cpp

点击(此处)折叠或打开

  1. /*
  2. **    FILENAME            CSerialPort.cpp
  3. **
  4. **    PURPOSE                This class can read, write and watch one serial port.
  5. **                        It sends messages to its owner when something happends on the port
  6. **                        The class creates a thread for reading and writing so the main
  7. **                        program is not blocked.
  8. **
  9. **    CREATION DATE        15-09-1997
  10. **    LAST MODIFICATION    12-11-1997
  11. **
  12. **    AUTHOR                Remon Spekreijse
  13. **
  14. **
  15. */

  16. #include "stdafx.h"
  17. #include "SerialPort.h"
  18. //#include "timeDlg.h"

  19. #include "mtype.h"
  20. #include "mqueue.h"

  21. #include <assert.h>
  22. #include "Proctol.h"

  23. #include "ComConfig.h"
  24. #include "ComConfigDlg.h"
  25. #include "timeDlg.h"

  26. uint8 rcv_buf[1000];
  27. //uint8 snd_buf[1000];


  28. //
  29. // Constructor
  30. //
  31. CSerialPort::CSerialPort()
  32. {
  33.     m_hComm = NULL;

  34.     // initialize overlapped structure members to zero
  35.     m_ov.Offset = 0;
  36.     m_ov.OffsetHigh = 0;

  37.     // create events
  38.     m_ov.hEvent = NULL;
  39.     m_hWriteEvent = NULL;
  40.     m_hShutdownEvent = NULL;

  41.     m_szWriteBuffer = NULL;

  42.     m_bThreadAlive = FALSE;
  43.     m_bSerialPortIsOpen=FALSE;
  44. }

  45. //
  46. // Delete dynamic memory
  47. //
  48. CSerialPort::~CSerialPort()
  49. {
  50.     do
  51.     {
  52.         SetEvent(m_hShutdownEvent);
  53.     } while (m_bThreadAlive);

  54.     TRACE("Thread ended\n");

  55.     delete [] m_szWriteBuffer;
  56. }

  57. uint8 ReadFull(void)
  58. {

  59.     return 0;
  60. }

  61. uint8 ReadEmpty(void)
  62. {

  63.     return 0;
  64. }
  65. //
  66. // Initialize the port. This can be port 1 to 4.
  67. //
  68. BOOL CSerialPort::InitPort(CWnd* pPortOwner,    // the owner (CWnd) of the port (receives message)
  69.                          UINT portnr,        // portnumber (1..4)
  70.                          UINT baud,            // baudrate
  71.                          char parity,        // parity
  72.                          UINT databits,        // databits
  73.                          UINT stopbits,        // stopbits
  74.                          DWORD dwCommEvents,    // EV_RXCHAR, EV_CTS etc
  75.                          UINT writebuffersize)    // size to the writebuffer
  76. {
  77.     assert(portnr > 0 && portnr < 55);
  78.     assert(pPortOwner != NULL);

  79.     // if the thread is alive: Kill
  80.     if (m_bThreadAlive)
  81.     {
  82.         do
  83.         {
  84.             SetEvent(m_hShutdownEvent);
  85.         } while (m_bThreadAlive);
  86.         TRACE("Thread ended\n");
  87.     }
  88.     
  89.     //InitQueue(void)
  90.     

  91.     QueueCreate( (uint8 *)rcv_buf,sizeof(rcv_buf),sizeof(uint8),NULL,NULL);
  92. //    QueueCreate( (uint8 *)snd_buf,sizeof(snd_buf),sizeof(uint8),NULL,NULL);
  93.     
  94.     // create events
  95.     if (m_ov.hEvent != NULL)
  96.         ResetEvent(m_ov.hEvent);
  97.     m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  98.     if (m_hWriteEvent != NULL)
  99.         ResetEvent(m_hWriteEvent);
  100.     m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  101.     
  102.     if (m_hShutdownEvent != NULL)
  103.         ResetEvent(m_hShutdownEvent);
  104.     m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  105.     // initialize the event objects
  106.     m_hEventArray[0] = m_hShutdownEvent;    // highest priority
  107.     m_hEventArray[1] = m_ov.hEvent;
  108.     m_hEventArray[2] = m_hWriteEvent;

  109.     // initialize critical section
  110.     InitializeCriticalSection(&m_csCommunicationSync);
  111.     
  112.     // set buffersize for writing and save the owner
  113.     m_pOwner = pPortOwner;

  114.     if (m_szWriteBuffer != NULL)
  115.         delete [] m_szWriteBuffer;
  116.     m_szWriteBuffer = new char[writebuffersize];

  117.     m_nPortNr = portnr;

  118.     m_nWriteBufferSize = writebuffersize;
  119.     m_dwCommEvents = dwCommEvents;

  120.     BOOL bResult = FALSE;
  121.     char *szPort = new char[50];
  122.     char *szBaud = new char[50];

  123.     // now it
  124.     EnterCriticalSection(&m_csCommunicationSync);

  125.     // if the port is already opened: close it
  126.     if (m_hComm != NULL)
  127.     {
  128.         CloseHandle(m_hComm);
  129.         m_hComm = NULL;
  130.     }

  131.     // prepare port strings
  132.     sprintf(szPort, "COM%d", portnr);
  133.     sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);

  134.     // get a handle to the port
  135.     m_hComm = CreateFile(szPort,                        // communication port string (COMX)
  136.                      GENERIC_READ | GENERIC_WRITE,    // read/write types
  137.                      0,                                // comm devices must be opened with exclusive access
  138.                      NULL,                            // no security attributes
  139.                      OPEN_EXISTING,                    // comm devices must use OPEN_EXISTING
  140.                      FILE_FLAG_OVERLAPPED,            // Async I/O
  141.                      0);                            // template must be 0 for comm devices

  142.     if (m_hComm == INVALID_HANDLE_VALUE)
  143.     {
  144.         // port not found
  145.         delete [] szPort;
  146.         delete [] szBaud;

  147.         return FALSE;
  148.     }

  149.     // set the timeout values
  150.     m_CommTimeouts.ReadIntervalTimeout = 1000;
  151.     m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
  152.     m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
  153.     m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
  154.     m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

  155.     // configure
  156.     if (SetCommTimeouts(m_hComm, &m_CommTimeouts))
  157.     {                        
  158.         if (SetCommMask(m_hComm, dwCommEvents))
  159.         {
  160.             if (GetCommState(m_hComm, &m_dcb))
  161.             {
  162.                 m_dcb.fRtsControl = RTS_CONTROL_ENABLE;        // set RTS bit
  163.                 if (BuildCommDCB(szBaud, &m_dcb))
  164.                 {
  165.                     if (SetCommState(m_hComm, &m_dcb))
  166.                         ; // normal operation... continue
  167.                     else
  168.                         ProcessErrorMessage("SetCommState()");
  169.                 }
  170.                 else
  171.                     ProcessErrorMessage("BuildCommDCB()");
  172.             }
  173.             else
  174.                 ProcessErrorMessage("GetCommState()");
  175.         }
  176.         else
  177.             ProcessErrorMessage("SetCommMask()");
  178.     }
  179.     else
  180.         ProcessErrorMessage("SetCommTimeouts()");

  181.     delete [] szPort;
  182.     delete [] szBaud;

  183.     // flush the port
  184.     PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  185.     // release critical section
  186.     LeaveCriticalSection(&m_csCommunicationSync);

  187.     TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);

  188.     return TRUE;
  189. }

  190. //
  191. // The CommThread Function.
  192. //
  193. UINT CSerialPort::CommThread(LPVOID pParam)
  194. {
  195.     // Cast the void pointer passed to the thread back to
  196.     // a pointer of CSerialPort class
  197.     CSerialPort *port = (CSerialPort*)pParam;
  198.     
  199.     // Set the status variable in the dialog class to
  200.     // TRUE to indicate the thread is running.
  201.     port->m_bThreadAlive = TRUE;    
  202.         
  203.     // Misc. variables
  204.     DWORD BytesTransfered = 0;
  205.     DWORD Event = 0;
  206.     DWORD CommEvent = 0;
  207.     DWORD dwError = 0;
  208.     COMSTAT comstat;
  209.     BOOL bResult = TRUE;
  210.         
  211.     // Clear comm buffers at startup
  212.     if (port->m_hComm)        // check if the port is opened
  213.         PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  214.     // begin forever loop. This loop will run as long as the thread is alive.
  215.     for (;;)
  216.     {

  217.         // Make a call to WaitCommEvent(). This call will return immediatly
  218.         // because our port was created as an async port (FILE_FLAG_OVERLAPPED
  219.         // and an m_OverlappedStructerlapped structure specified). This call will cause the
  220.         // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to
  221.         // be placed in a non-signeled state if there are no bytes available to be read,
  222.         // or to a signeled state if there are bytes available. If this event handle
  223.         // is set to the non-signeled state, it will be set to signeled when a
  224.         // character arrives at the port.

  225.         // we do this for each

  226.         bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);

  227.         if (!bResult)
  228.         {
  229.             // If WaitCommEvent() returns FALSE, process the last error to determin
  230.             // the reason..
  231.             switch (dwError = GetLastError())
  232.             {
  233.             case ERROR_IO_PENDING:     
  234.                 {
  235.                     // This is a normal return value if there are no bytes
  236.                     // to read at the port.
  237.                     // Do nothing and continue
  238.                     break;
  239.                 }
  240.             case 87:
  241.                 {
  242.                     // Under Windows NT, this value is returned for some reason.
  243.                     // I have not investigated why, but it is also a valid reply
  244.                     // Also do nothing and continue.
  245.                     break;
  246.                 }
  247.             default:
  248.                 {
  249.                     // All other error codes indicate a serious error has
  250.                     // occured. Process this error.
  251.                     port->ProcessErrorMessage("WaitCommEvent()");
  252.                     break;
  253.                 }
  254.             }
  255.         }
  256.         else
  257.         {
  258.             // If WaitCommEvent() returns TRUE, check to be sure there are
  259.             // actually bytes in the buffer to read.
  260.             //
  261.             // If you are reading more than one byte at a time from the buffer
  262.             // (which this program does not do) you will have the situation occur
  263.             // where the first byte to arrive will cause the WaitForMultipleObjects()
  264.             // function to stop waiting. The WaitForMultipleObjects() function
  265.             // resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state
  266.             // as it returns.
  267.             //
  268.             // If in the time between the reset of this event and the call to
  269.             // ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again
  270.             // to the signeled state. When the call to ReadFile() occurs, it will
  271.             // read all of the bytes from the buffer, and the program will
  272.             // loop back around to WaitCommEvent().
  273.             //
  274.             // At this point you will be in the situation where m_OverlappedStruct.hEvent is set,
  275.             // but there are no bytes available to read. If you proceed and call
  276.             // ReadFile(), it will return immediatly due to the async port setup, but
  277.             // GetOverlappedResults() will not return until the next character arrives.
  278.             //
  279.             // It is not desirable for the GetOverlappedResults() function to be in
  280.             // this state. The thread shutdown event (event 0) and the WriteFile()
  281.             // event (Event2) will not work if the thread is blocked by GetOverlappedResults().
  282.             //
  283.             // The solution to this is to check the buffer with a call to ClearCommError().
  284.             // This call will reset the event handle, and if there are no bytes to read
  285.             // we can loop back through WaitCommEvent() again, then proceed.
  286.             // If there are really bytes to read, do nothing and proceed.
  287.         
  288.             bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

  289.             if (comstat.cbInQue == 0)
  290.                 continue;
  291.         }    // end if bResult

  292.         // Main wait function. This function will normally block the thread
  293.         // until one of nine events occur that require action.
  294.         Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);

  295.         switch (Event)
  296.         {
  297.         case 0:
  298.             {
  299.                 // Shutdown event. This is event zero so it will be
  300.                 // the higest priority and be serviced first.

  301.                  port->m_bThreadAlive = FALSE;
  302.                 
  303.                 // Kill this thread. break is not needed, but makes me feel better.
  304.                 AfxEndThread(100);
  305.                 break;
  306.             }
  307.         case 1:    // read event
  308.             {
  309.                 GetCommMask(port->m_hComm, &CommEvent);
  310.                 if (CommEvent & EV_CTS)
  311.                     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
  312.                 if (CommEvent & EV_RXFLAG)
  313.                     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
  314.                 if (CommEvent & EV_BREAK)
  315.                     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
  316.                 if (CommEvent & EV_ERR)
  317.                     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
  318.                 if (CommEvent & EV_RING)
  319.                     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
  320.                 
  321.                 if (CommEvent & EV_RXCHAR)
  322.                     // Receive character event from port.
  323.                     ReceiveChar(port, comstat);
  324.                     
  325.                 break;
  326.             }
  327.         case 2: // write event,串口发送事件响应
  328.             {
  329.                 // Write character event from port
  330.                 WriteChar(port);
  331.                 break;
  332.             }

  333.         } // end switch

  334.     } // close forever loop

  335.     return 0;
  336. }

  337. //
  338. // start comm watching
  339. //
  340. BOOL CSerialPort::StartMonitoring()
  341. {
  342.     if (!(m_Thread = AfxBeginThread(CommThread, this)))
  343.         return FALSE;
  344.     TRACE("Thread started\n");
  345.     AfxBeginThread(SerialParseThread,this);
  346.     return TRUE;    
  347. }

  348. //
  349. // Restart the comm thread
  350. //
  351. BOOL CSerialPort::RestartMonitoring()
  352. {
  353.     TRACE("Thread resumed\n");
  354.     m_Thread->ResumeThread();
  355.     return TRUE;    
  356. }


  357. //
  358. // Suspend the comm thread
  359. //
  360. BOOL CSerialPort::StopMonitoring()
  361. {
  362.     TRACE("Thread suspended\n");
  363.     m_Thread->SuspendThread();
  364.     return TRUE;    
  365. }


  366. //
  367. // If there is a error, give the right message
  368. //
  369. void CSerialPort::ProcessErrorMessage(char* ErrorText)
  370. {
  371.     char *Temp = new char[200];
  372.     
  373.     LPVOID lpMsgBuf;

  374.     FormatMessage(
  375.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  376.         NULL,
  377.         GetLastError(),
  378.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  379.         (LPTSTR) &lpMsgBuf,
  380.         0,
  381.         NULL
  382.     );

  383.     sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr);
  384.     MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
  385.     printf("%s\r\n",Temp);

  386.     LocalFree(lpMsgBuf);
  387.     delete[] Temp;
  388. }

  389. //
  390. // Write a character.
  391. //
  392. void CSerialPort::WriteChar(CSerialPort* port)
  393. {
  394.     BOOL bWrite = TRUE;
  395.     BOOL bResult = TRUE;

  396.     DWORD BytesSent = 0;

  397.     ResetEvent(port->m_hWriteEvent);

  398.     // Gain ownership of the critical section
  399.     EnterCriticalSection(&port->m_csCommunicationSync);

  400.     if (bWrite)
  401.     {
  402.         // Initailize variables
  403.         port->m_ov.Offset = 0;
  404.         port->m_ov.OffsetHigh = 0;

  405.         // Clear buffer
  406.         PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
  407.         DWORD dwLen=port->m_dwWriteBufferLen;

  408.         bResult = WriteFile(port->m_hComm,                            // Handle to COMM Port
  409.                             port->m_szWriteBuffer,                    // Pointer to message buffer in calling finction
  410.                             dwLen,                                    // Length of message to send
  411.                             &BytesSent,                                // Where to store the number of bytes sent
  412.                             &port->m_ov);                            // Overlapped structure

  413.         // deal with any error codes
  414.         if (!bResult)
  415.         {
  416.             DWORD dwError = GetLastError();
  417.             switch (dwError)
  418.             {
  419.                 case ERROR_IO_PENDING:
  420.                     {
  421.                         // continue to GetOverlappedResults()
  422.                         BytesSent = 0;
  423.                         bWrite = FALSE;
  424.                         break;
  425.                     }
  426.                 default:
  427.                     {
  428.                         // all other error codes
  429.                         port->ProcessErrorMessage("WriteFile()");
  430.                     }
  431.             }
  432.         }
  433.         else
  434.         {
  435.             LeaveCriticalSection(&port->m_csCommunicationSync);
  436.         }
  437.     } // end if(bWrite)

  438.     if (!bWrite)
  439.     {
  440.         bWrite = TRUE;
  441.     
  442.         bResult = GetOverlappedResult(port->m_hComm,    // Handle to COMM port
  443.                                      &port->m_ov,        // Overlapped structure
  444.                                      &BytesSent,        // Stores number of bytes sent
  445.                                      TRUE);             // Wait flag

  446.         LeaveCriticalSection(&port->m_csCommunicationSync);

  447.         // deal with the error code
  448.         if (!bResult)
  449.         {
  450.             port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
  451.         }    
  452.     } // end if (!bWrite)

  453.     // Verify that the data size send equals what we tried to send
  454.     if (BytesSent != strlen((char*)port->m_szWriteBuffer))
  455.     {
  456.         TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
  457.     }
  458. }

  459. //
  460. // Character received. Inform the owner
  461. //
  462. void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
  463. {
  464.     BOOL bRead = TRUE;
  465.     BOOL bResult = TRUE;
  466.     DWORD dwError = 0;
  467.     DWORD BytesRead = 0;
  468.     unsigned char RXBuff;

  469.     for (;;)
  470.     {
  471.         // Gain ownership of the comm port critical section.
  472.         // This process guarantees no other part of this program
  473.         // is using the port object.
  474.         
  475.         EnterCriticalSection(&port->m_csCommunicationSync);

  476.         // ClearCommError() will update the COMSTAT structure and
  477.         // clear any other errors.
  478.         
  479.         bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

  480.         LeaveCriticalSection(&port->m_csCommunicationSync);

  481.         // start forever loop. I use this type of loop because I
  482.         // do not know at runtime how many loops this will have to
  483.         // run. My solution is to start a forever loop and to
  484.         // break out of it when I have processed all of the
  485.         // data available. Be careful with this approach and
  486.         // be sure your loop will exit.
  487.         // My reasons for this are not as clear in this sample
  488.         // as it is in my production code, but I have found this
  489.         // solutiion to be the most efficient way to do this.
  490.         
  491.         if (comstat.cbInQue == 0)
  492.         {
  493.             // break out when all bytes have been read
  494.             break;
  495.         }
  496.                         
  497.         EnterCriticalSection(&port->m_csCommunicationSync);

  498.         if (bRead)
  499.         {

  500.             try
  501.             {
  502.                 bResult = ReadFile(port->m_hComm,        // Handle to COMM port
  503.                              &RXBuff,                // RX Buffer Pointer
  504.                              1,                    // Read one byte
  505.                              &BytesRead,            // Stores number of bytes read
  506.                              &port->m_ov);        // pointer to the m_ov structure
  507.             }
  508.             catch (...)
  509.             {
  510.                 //bResult        
  511.             }
  512.         
  513.             // deal with the error code
  514.             if (!bResult)
  515.             {
  516.                 switch (dwError = GetLastError())
  517.                 {
  518.                     case ERROR_IO_PENDING:     
  519.                         {
  520.                             // asynchronous i/o is still in progress
  521.                             // Proceed on to GetOverlappedResults();
  522.                             bRead = FALSE;
  523.                             break;
  524.                         }
  525.                     default:
  526.                         {
  527.                             // Another error has occured. Process this error.
  528.                             port->ProcessErrorMessage("ReadFile()");
  529.                             break;
  530.                         }
  531.                 }
  532.             }
  533.             else
  534.             {
  535.                 // ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
  536.                 bRead = TRUE;
  537.             }
  538.         } // close if (bRead)

  539.         if (!bRead)
  540.         {
  541.             bRead = TRUE;
  542.             bResult = GetOverlappedResult(port->m_hComm,    // Handle to COMM port
  543.                                          &port->m_ov,        // Overlapped structure
  544.                                          &BytesRead,        // Stores number of bytes read
  545.                                          TRUE);             // Wait flag

  546.             // deal with the error code
  547.             if (!bResult)
  548.             {
  549.                 port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
  550.             }    
  551.         } // close if (!bRead)
  552.                 
  553.         LeaveCriticalSection(&port->m_csCommunicationSync);

  554.         // notify parent that a byte was received
  555.         ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);

  556.         QueueWrite(rcv_buf,&RXBuff,1);

  557.         //printf("%02x\r\n",RXBuff);
  558.     } // end forever loop

  559. }

  560. //
  561. // Write a string to the port
  562. //
  563. void CSerialPort::WriteToPort(char* string)
  564. {        
  565.     assert(m_hComm != 0);
  566.     m_dwWriteBufferLen=sizeof(m_szWriteBuffer);
  567.     memset(m_szWriteBuffer, 0, m_dwWriteBufferLen);
  568.     strcpy(m_szWriteBuffer, string);
  569.     
  570.     // set event for write
  571.     SetEvent(m_hWriteEvent);
  572. }

  573. void CSerialPort::WriteToPort(char *string, WORD wLen)
  574. {
  575.     assert(m_hComm != 0);
  576.     m_dwWriteBufferLen=wLen;
  577.     memset(m_szWriteBuffer, 0, wLen);
  578.     memcpy(m_szWriteBuffer,string,wLen);
  579.     // set event for write
  580.     SetEvent(m_hWriteEvent);
  581. }


  582. //
  583. // Return the device control block
  584. //
  585. DCB CSerialPort::GetDCB()
  586. {
  587.     return m_dcb;
  588. }

  589. //
  590. // Return the communication event masks
  591. //
  592. DWORD CSerialPort::GetCommEvents()
  593. {
  594.     return m_dwCommEvents;
  595. }

  596. //
  597. // Return the output buffer size
  598. //
  599. DWORD CSerialPort::GetWriteBufferSize()
  600. {
  601.     return m_nWriteBufferSize;
  602. }



  603. extern ComConfigApp theApp;

  604. //串口接收解析线程
  605. UINT CSerialPort::SerialParseThread(void *param)
  606. {
  607.     BYTE byrecv[100];
  608.     char szBuf[1000];
  609.     CComConfigDlg *dlg =(CComConfigDlg *)theApp.m_pMainWnd;
  610.     while (1)
  611.     {
  612.         DWORD dwLen;
  613.         dwLen=QueueNData(rcv_buf,1);
  614.         if(dwLen>=7)
  615.         {
  616.         
  617.             for (UINT32 ilp=0;ilp<dwLen;ilp++)
  618.             {
  619.                 if ( QueueRead(byrecv + ilp ,rcv_buf,1)!=QUEUE_OK )
  620.                 {
  621.                     break;
  622.                 }
  623.             //    printf("%d\t",byrecv[ilp]);
  624.             
  625.             }
  626.             //printf("\r\n");lz20150801

  627.             date_time_t *dt;
  628.             dt=(date_time_t *)byrecv;
  629.             printf("万年历反馈时间:%04d-%02d-%02d,%02d:%02d:%02d,%d\r\n",
  630.                 dt->date.year,dt->date.month,dt->date.day,
  631.                 dt->time.hour,dt->time.minute,dt->time.second,
  632.                 dt->time.week);

  633.             sprintf(szBuf,"万年历反馈时间:%04d-%02d-%02d,%02d:%02d:%02d,%d\r\n",
  634.                 dt->date.year,dt->date.month,dt->date.day,
  635.                 dt->time.hour,dt->time.minute,dt->time.second,
  636.                 dt->time.week);
  637.             dlg->m_timeDlg.WriteinfoDisplay(szBuf,TP_ADD);

  638.             QueueFlush(rcv_buf);
  639.             
  640.         }
  641.         Sleep(1);
  642.     }

  643.     return TRUE;
  644. }

  645. int CSerialPort::EnumAllComPort(CString *pStr)
  646. {
  647.     int i = 0;
  648.     CHAR Name[25];
  649.     UCHAR szPortName[25];
  650.     LONG Status;
  651.     DWORD dwIndex = 0;
  652.     DWORD dwName;
  653.     DWORD dwSizeofPortName;
  654.     DWORD Type;
  655.     HKEY hKey;
  656.     LPCTSTR data_Set = "HARDWARE\\DEVICEMAP\\SERIALCOMM\\";
  657.     long ret0 = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey));

  658.     do
  659.     {
  660.             dwName = sizeof(Name);
  661.             dwSizeofPortName = sizeof(szPortName);
  662.             Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type,
  663.                     szPortName, &dwSizeofPortName);

  664.             if ((Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA))
  665.             {
  666.                     pStr[i] = CString(szPortName); // 串口字符串保存
  667.                     i++;// 串口计数
  668.             }
  669.     }
  670.     while ((Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA));

  671.     RegCloseKey(hKey);
  672.     return i;

  673. }

  674. BOOL CSerialPort::ClearComRecvFifo()
  675. {
  676.     QueueFlush(rcv_buf);

  677.     return TRUE;
  678. }





阅读(2433) | 评论(0) | 转发(0) |
0

上一篇:电子指南针

下一篇:ubuntu14.10 修改源

给主人留下些什么吧!~~