17年也没干个啥,年后就去折腾着玩意儿了,也不知道我折腾它还是它折腾我。反正总之现在勉强可以交作业了,呵呵

硬件:

1.罗耶振荡电路输出一路4v交流,一路25v交流

  其中4v直接驱动灯丝,另一路经电桥整流提供负压给pt6311

2.主控用stm8s003f3

  成本低廉,而且我这几块stm8是x宝掌柜送的,本身性价比也很高,8kflash先在用串口调试附带其他驱动大致用了
1020179-20180121143358131-377208505.png
 也就是大概用完了。其实去掉uart估计要少4k,我寻思加个gps解码的程序应该够用吧。。。23333
3.vfd驱动用前面提到的pt6311
  我买的好像很便宜,1.85一片。但是现在用了三片,其中一片死活有个seg不输出。索性它便宜就不计较了2333
原理图
1020179-20180121143813099-541571474.png
pcb:
1020179-20180121143919099-1714392138.png
按键那部分单独做了块小板子,一来空间不够了,而来后期设计外壳更方便,总之有打印机是方便的很

源码:

沿用我之前写的驱动,并移植了st官方的eeprom的库来驱动硬件iic与ds3231通讯
//transplanted for ds3231
  • /* Define to prevent recursive inclusion ------------------------------------ */
  • #ifndef __I2C_EE_H
  • #define __I2C_EE_H
  • /* Includes ------------------------------------------------------------------*/
  • #include "stm8s.h"
  • #include "ds3231.h"    //@ds3231.h for macro
  • /* Private typedef -----------------------------------------------------------*/
  • /* Private define ------------------------------------------------------------*/
  • #define I2C_Speed              100000
  • #define I2C1_SLAVE_ADDRESS7    DS3231_WriteAddress //0xd0
  • #define EEPROM_BASE_ADDRESS    0x0000
  • #define Page_Byte_Size    ((u8)8)   /*EEPROM 每页最多写8Byte*/
  • #define EEPROM_ADDRESS         DS3231_WriteAddress//0xd0
  • /* Private macro -------------------------------------------------------------*/
  • /* Private variables ---------------------------------------------------------*/
  • /* Private function prototypes -----------------------------------------------*/
  • /* Private functions ---------------------------------------------------------*/
  • /* Exported macro ------------------------------------------------------------*/
  • /* Exported functions ------------------------------------------------------- */
  • void I2C_EEInit(void);
  • void I2C_EE_ByteWrite(u8* pBuffer, u16 WriteAddr);
  • //void I2C_EE_PageWrite(u8* pBuffer, u16 WriteAddr, u8 NumByteToWrite);
  • void I2C_EE_BufferRead(u8* pBuffer, u16 ReadAddr, u8 NumByteToRead);
  • uint8_t I2C_ReadRegister_SR1();
  • void I2C_EE_WaitEepromStandbyState(void);
  • void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite);
  • #endif /* __I2C_EE_H */
  • 复制代码
    #include "i2c_ee.h"
  • #include "stm8s_i2c.h"
  • //transplanted to dsd3231
  • //modyfied:
  • //1.only leave 8 bit to work
  • //2.change the related macro definition
  • //3.use newer stm8s_i2c.h
  • //By katachi time:2018-1-20
  • /*******************************************************************************
  • * Function Name  : I2C_EE_Init
  • * Description    : Initializes peripherals used by the I2C EEPROM driver.
  • * Input          : None
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void I2C_EEInit(void)
  • {
  •    u8 Input_Clock = 0x0;
  •   /* Get system clock frequency */
  •   Input_Clock = CLK_GetClockFreq()/1000000;
  •   /* I2C Peripheral Enable */
  •   I2C_Cmd(ENABLE);
  •   /* Apply I2C configuration after enabling it */
  •   I2C_Init(I2C_Speed, 0xaa, I2C_DUTYCYCLE_2,\
  •             I2C_ACK_CURR, I2C_ADDMODE_7BIT, Input_Clock);//use 0xaa as master(mcu)'s addr
  • }
  • /*******************************************************************************
  • * Function Name  : I2C_EE_ByteWrite
  • * Description    : Writes one byte to the I2C EEPROM.
  • * Input          : - pBuffer : pointer to the buffer  containing the data to be
  • *                    written to the EEPROM.
  • *                  - WriteAddr : EEPROM's internal address to write to.
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void I2C_EE_ByteWrite(u8* pBuffer, u16 WriteAddr)
  • {
  •   //wait for idle
  •   while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  •   /* Send STRAT condition */
  •   I2C_GenerateSTART(ENABLE);
  •   /* Test on EV5 and clear it */
  •     while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
  •   /* Send EEPROM address for write */
  •   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
  •   /* Test on EV6 and clear it */
  •    while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  •   //for 16 bit
  • //  /* Send Address (on 2 bytes) of first byte to be written & wait event detection */
  • //  I2C_SendData((u8)(WriteAddr >> 8)); /* MSB */
  • //  /* Test on EV8 and clear it */
  • //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  •   I2C_SendData((u8)(WriteAddr)); /* LSB */
  •   /* Test on EV8 and clear it */
  •   while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  •   /* Send the byte to be written */
  •   I2C_SendData(*pBuffer);
  •   /* Test on EV8 and clear it */
  •   while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  •   /* Send STOP condition */
  •   I2C_GenerateSTOP(ENABLE);
  • }
  • /*******************************************************************************
  • * Function Name  : I2C_EE_PageWrite
  • * Description    : Writes more than one byte to the EEPROM with a single WRITE
  • *                  cycle. The number of byte can't exceed the EEPROM page size.
  • * Input          : - pBuffer : pointer to the buffer containing the data to be
  • *                    written to the EEPROM.
  • *                  - WriteAddr : EEPROM's internal address to write to.
  • *                  - NumByteToWrite : number of bytes to write to the EEPROM.
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • //void I2C_EE_PageWrite(u8* pBuffer, u16 WriteAddr, u8 NumByteToWrite)
  • //{
  • //  /* While the bus is busy */
  • //  while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  • //
  • //  /* Send START condition */
  • //  I2C_GenerateSTART(ENABLE);
  • //
  • //  /* Test on EV5 and clear it */
  • //  while(!I2C_CheckEvent(I2C_EVENT_MASTER_START_SENT));
  • //
  • //  /* Send EEPROM address for write */
  • //  I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
  • //
  • //  /* Test on EV6 and clear it */
  • //  while(!I2C_CheckEvent(I2C_EVENT_MASTER_ADDRESS_ACKED));
  • //  I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
  • //
  • //  /* Send Address (on 2 bytes) of first byte to be written & wait event detection */
  • //  I2C_SendData((u8)(WriteAddr >> 8)); /* MSB */
  • //  /* Test on EV8 and clear it */
  • //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  • //  I2C_SendData((u8)(WriteAddr)); /* LSB */
  • //  /* Test on EV8 and clear it */
  • //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  • //
  • //
  • //  /* While there is data to be written */
  • //  while(NumByteToWrite--)
  • //  {
  • //    /* Send the current byte */
  • //    I2C_SendData(*pBuffer);
  • //
  • //    /* Point to the next byte to be written */
  • //    pBuffer++;
  • //
  • //    /* Test on EV8 and clear it */
  • //    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  • //  }
  • //
  • //  /* Send STOP condition */
  • //  I2C_GenerateSTOP(ENABLE);
  • //}
  • /*******************************************************************************
  • * Function Name  : I2C_EE_BufferRead
  • * Description    : Reads a block of data from the EEPROM.
  • * Input          : - pBuffer : pointer to the buffer that receives the data read
  • *                    from the EEPROM.
  • *                  - ReadAddr : EEPROM's internal address to read from.
  • *                  - NumByteToRead : number of bytes to read from the EEPROM.
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void I2C_EE_BufferRead(u8* pBuffer, u16 ReadAddr, u8 NumByteToRead)
  • {
  •     /* While the bus is busy */
  •   while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  •   /* Generate start & wait event detection */
  •     I2C_GenerateSTART(ENABLE);
  •   /* Test on EV5 and clear it */
  •     while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
  •   /* Send slave Address in write direction & wait detection event */
  •     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
  •    /* Test on EV6 and clear it */
  •     while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  •     //for 10bit addr
  •    /* Send Address of first byte to be read & wait event detection */
  • //    I2C_SendData((u8)(ReadAddr >> 8)); /* MSB */
  • //    /* Test on EV8 and clear it */
  • //    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  •     I2C_SendData((u8)(ReadAddr)); /* LSB */
  •   /* Test on EV8 and clear it */
  •     while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  •   /* Send STRAT condition a second time */
  •   I2C_GenerateSTART(ENABLE);
  •     /* Test on EV5 and clear it */
  •   while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
  •   /* Send slave Address in read direction & wait event */
  •     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);
  •    /* Test on EV6 and clear it */
  •      while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  •   /* While there is data to be read */
  •   while(NumByteToRead)
  •   {
  •     if(NumByteToRead == 1)
  •     {
  •       /* Disable Acknowledgement */
  •       I2C_AcknowledgeConfig(I2C_ACK_NONE);
  •       /* Send STOP Condition */
  •       I2C_GenerateSTOP(ENABLE);
  •     }
  •     /* Test on EV7 and clear it */
  •     if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
  •     {
  •       /* Read a byte from the EEPROM */
  •       *pBuffer = I2C_ReceiveData();
  •       /* Point to the next location where the byte read will be saved */
  •       pBuffer++;
  •       /* Decrement the read bytes counter */
  •       NumByteToRead--;
  •     }
  •   }
  •   /* Enable Acknowledgement to be ready for another reception */
  •   I2C_AcknowledgeConfig(I2C_ACK_CURR);
  • }
  • uint8_t I2C_ReadRegister_SR1()
  • {
  •   uint8_t temp;
  •   temp=I2C->SR1;
  •   return temp;
  • }
  • void I2C_EE_WaitEepromStandbyState(void)
  • {
  •   u8 SR1_Tmp = 0;
  •   do
  •   {
  •     /* Send START condition */
  •     I2C_GenerateSTART(ENABLE);
  •     /* Read I2C1 SR1 register */
  •     SR1_Tmp =I2C_ReadRegister_SR1();
  •     /* Send EEPROM address for write */
  •     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);;
  •   }while(!(I2C_ReadRegister_SR1()&0x02));
  •   /* Clear AF flag */
  •   I2C_ClearFlag(I2C_FLAG_ACKNOWLEDGEFAILURE);
  • }
  • /*******************************************************************************
  • * Function Name  : I2C_EE_BufferWrite
  • * Description    : Writes buffer of data to the I2C EEPROM.
  • * Input          : - pBuffer : pointer to the buffer  containing the data to be
  • *                    written to the EEPROM.
  • *                  - WriteAddr : EEPROM's internal address to write to.
  • *                  - NumByteToWrite : number of bytes to write to the EEPROM.
  • * Output         : None
  • * Return         : None
  • *******************************************************************************/
  • void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  • {
  •   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
  •   Addr = WriteAddr % Page_Byte_Size ;
  •   count = Page_Byte_Size  - Addr;
  •   NumOfPage =  NumByteToWrite / Page_Byte_Size ;
  •   NumOfSingle = NumByteToWrite % Page_Byte_Size ;
  •   /* If WriteAddr is I2C_PageSize aligned  */
  •   if(Addr == 0)
  •   {
  •     /* If NumByteToWrite < I2C_PageSize */
  •     if(NumOfPage == 0)
  •     {
  •       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  •       I2C_EE_WaitEepromStandbyState();
  •     }
  •     /* If NumByteToWrite > I2C_PageSize */
  •     else
  •     {
  •       while(NumOfPage--)
  •       {
  •         I2C_EE_PageWrite(pBuffer, WriteAddr, Page_Byte_Size );
  •         I2C_EE_WaitEepromStandbyState();
  •         WriteAddr +=  Page_Byte_Size ;
  •         pBuffer += Page_Byte_Size ;
  •       }
  •       if(NumOfSingle!=0)
  •       {
  •         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  •         I2C_EE_WaitEepromStandbyState();
  •       }
  •     }
  •   }
  •   /* If WriteAddr is not I2C_PageSize aligned  */
  •   else
  •   {
  •     /* If NumByteToWrite < I2C_PageSize */
  •     if(NumOfPage== 0)
  •     {
  •       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  •       I2C_EE_WaitEepromStandbyState();
  •     }
  •     /* If NumByteToWrite > I2C_PageSize */
  •     else
  •     {
  •       NumByteToWrite -= count;
  •       NumOfPage =  NumByteToWrite / Page_Byte_Size ;
  •       NumOfSingle = NumByteToWrite % Page_Byte_Size ;
  •       if(count != 0)
  •       {
  •         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  •         I2C_EE_WaitEepromStandbyState();
  •         WriteAddr += count;
  •         pBuffer += count;
  •       }
  •       while(NumOfPage--)
  •       {
  •         I2C_EE_PageWrite(pBuffer, WriteAddr, Page_Byte_Size );
  •         I2C_EE_WaitEepromStandbyState();
  •         WriteAddr += Page_Byte_Size ;
  •         pBuffer += Page_Byte_Size ;
  •       }
  •       if(NumOfSingle != 0)
  •       {
  •         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  •         I2C_EE_WaitEepromStandbyState();
  •       }
  •     }
  •   }
  • }
  • 复制代码
    目前测试过的,初始化肯定不用说,字节写测试通过,连续读测试通过,连续写还未测试,照理也可以的23333
    #ifndef DS3231_H
  • #define DS3231_H
  • #include "pt6311.h"
  • #include "i2c_ee.h"
  • #define DS3231_WriteAddress 0xD0    //器件写地址
  • #define DS3231_ReadAddress  0xD1    //器件读地址
  • #define DS3231_SECOND       0x00    //秒
  • #define DS3231_MINUTE       0x01    //分
  • #define DS3231_HOUR         0x02    //时
  • #define DS3231_WEEK         0x03    //星期
  • #define DS3231_DAY          0x04    //日
  • #define DS3231_MONTH        0x05    //月
  • #define DS3231_YEAR         0x06    //年
  • //闹铃1
  • #define DS3231_SALARM1ECOND 0x07    //秒
  • #define DS3231_ALARM1MINUTE 0x08    //分
  • #define DS3231_ALARM1HOUR   0x09    //时
  • #define DS3231_ALARM1WEEK   0x0A    //星期/日
  • //闹铃2
  • #define DS3231_ALARM2MINUTE 0x0b    //分
  • #define DS3231_ALARM2HOUR   0x0c    //时
  • #define DS3231_ALARM2WEEK   0x0d    //星期/日
  • #define DS3231_CONTROL      0x0e    //控制寄存器
  • #define DS3231_STATUS       0x0f    //状态寄存器
  • #define BSY                 2       //忙
  • #define OSF                 7       //振荡器停止标志
  • #define DS3231_XTAL         0x10    //晶体老化寄存器
  • #define DS3231_TEMPERATUREH 0x11    //温度寄存器高字节(8位)
  • #define DS3231_TEMPERATUREL 0x12    //温度寄存器低字节(高2位)
  • u8 BCD2DEC(u8 val);    //BCD转换为Byte
  • u8 DEC2BCD(u8 val);    //B码转换为BCD码
  • void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec);
  • void get_show_time(void);
  • void get_show_Temperature(void);
  • #endif
  • 复制代码

    #include "ds3231.h"
  • u8 BCD2DEC(u8 val)    //BCD转换为DEC
  • {
  •     u8 temp;
  •     temp=(val/16)*10+(val%16);
  •     return temp;
  • }
  • u8 DEC2BCD(u8 val)    //DEC码转换为BCD码
  • {
  •     u8 k;
  •     k=(val%10)+((val/10)<<4);
  •     return k;
  • }
  • void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
  • {
  •     u8 temp=0;
  •     temp=DEC2BCD(yea);
  •     I2C_EE_ByteWrite(&temp,DS3231_YEAR);   //修改年
  •     temp=DEC2BCD(mon);
  •     I2C_EE_ByteWrite(&temp,DS3231_MONTH);  //修改月
  •     temp=DEC2BCD(da);
  •     I2C_EE_ByteWrite(&temp,DS3231_DAY);    //修改日
  •     temp=DEC2BCD(hou);
  •     I2C_EE_ByteWrite(&temp,DS3231_HOUR);   //修改时
  •     temp=DEC2BCD(min);
  •     I2C_EE_ByteWrite(&temp,DS3231_MINUTE); //修改分
  •     temp=DEC2BCD(sec);
  •     I2C_EE_ByteWrite(&temp,DS3231_SECOND); //修改秒
  • }
  • void get_show_time(void)
  • {
  •     u8 data[7],i; //save time
  •     I2C_EE_BufferRead(data,0,7);//S->Y 0->6
  •     data[2]&=0x3f;//get true hour
  •     //bcd to dec
  •     for (i=0;i<7;i++)
  •         data[i]=BCD2DEC(data[i]);
  •     dspseg[11]=data[0]%10;
  •     dspseg[10]=data[0]/10;
  •     dspseg[9]=data[1]%10;
  •     dspseg[8]=data[1]/10;
  •     dspseg[7]=data[2]%10;
  •     dspseg[6]=data[2]/10;
  • }
  • void get_show_Temperature(void)
  • {
  •     u8 temp[2];
  •    //temph  _(sign) _ _ _, _ _ _ _
  •     //templ (point)_ _0 0, 0 0 0 0
  •     I2C_EE_BufferRead(temp,DS3231_TEMPERATUREH,2);
  •     temp[0]=BCD2DEC(temp[0]);//int,default in positive temperature
  •     temp[1]=(temp[1]>>6)*25;//decimal
  •     dspseg[5]=temp[0]%10;
  •     dspseg[4]=temp[0]/10;
  • }
  • 复制代码
    懒得上main.c了,有心人一下子就搞出来了,我api都写的差不多了,剩下按键改时间,以及闹钟设置,可选的gps校时

    注意stm8s_i2c.h这个头应该是11年那个比较大的头,起初那个不行,后来根据风驰的eeprom教程移植,它用的也是我说的这个新点的库

    晒图:
    1020179-20180121145531381-335971610.png
    1020179-20180121145558178-1394809927.png
    1020179-20180121145618474-1337796425.png
    1020179-20180121145637131-2081479573.png
    手工版做了估计有六七块,主要是打印机喷的墨不够,而且油笔不给力,描了也没有用。这几张图是后期版本的,没有大面积铺铜,简直不堪入目233333