vfd电子时钟制作

 

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


硬件:

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

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

2.主控用stm8s003f3 

  成本低廉,而且我这几块stm8是x宝掌柜送的,本身性价比也很高,8kflash先在用串口调试附带其他驱动大致用了

 也就是大概用完了。其实去掉uart估计要少4k,我寻思加个gps解码的程序应该够用吧。。。23333

3.vfd驱动用前面提到的pt6311

  我买的好像很便宜,1.85一片。但是现在用了三片,其中一片死活有个seg不输出。索性它便宜就不计较了2333


 

原理图

 

pcb:

按键那部分单独做了块小板子,一来空间不够了,而来后期设计外壳更方便,总之有打印机是方便的很


源码:

沿用我之前写的驱动,并移植了st官方的eeprom的库来驱动硬件iic与ds3231通讯

 1 //transplanted for ds3231
 2 /* Define to prevent recursive inclusion ------------------------------------ */
 3 #ifndef __I2C_EE_H
 4 #define __I2C_EE_H
 5 
 6 /* Includes ------------------------------------------------------------------*/
 7 #include "stm8s.h"
 8 #include "ds3231.h"    //@ds3231.h for macro
 9 
10 /* Private typedef -----------------------------------------------------------*/
11 /* Private define ------------------------------------------------------------*/
12 #define I2C_Speed              100000
13 #define I2C1_SLAVE_ADDRESS7    DS3231_WriteAddress //0xd0
14 #define EEPROM_BASE_ADDRESS    0x0000
15 #define Page_Byte_Size    ((u8)8)   /*EEPROM 每页最多写8Byte*/
16 #define EEPROM_ADDRESS         DS3231_WriteAddress//0xd0
17 /* Private macro -------------------------------------------------------------*/
18 /* Private variables ---------------------------------------------------------*/
19 
20 /* Private function prototypes -----------------------------------------------*/
21 /* Private functions ---------------------------------------------------------*/
22 
23 /* Exported macro ------------------------------------------------------------*/
24 /* Exported functions ------------------------------------------------------- */
25 void I2C_EEInit(void);
26 void I2C_EE_ByteWrite(u8* pBuffer, u16 WriteAddr);
27 //void I2C_EE_PageWrite(u8* pBuffer, u16 WriteAddr, u8 NumByteToWrite);
28 void I2C_EE_BufferRead(u8* pBuffer, u16 ReadAddr, u8 NumByteToRead);
29 uint8_t I2C_ReadRegister_SR1();
30 void I2C_EE_WaitEepromStandbyState(void);
31 void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite);
32 #endif /* __I2C_EE_H */
  1 #include "i2c_ee.h"
  2 #include "stm8s_i2c.h"
  3 //transplanted to dsd3231
  4 //modyfied:
  5 //1.only leave 8 bit to work
  6 //2.change the related macro definition
  7 //3.use newer stm8s_i2c.h
  8 //By katachi time:2018-1-20
  9 
 10 /*******************************************************************************
 11 * Function Name  : I2C_EE_Init
 12 * Description    : Initializes peripherals used by the I2C EEPROM driver.
 13 * Input          : None
 14 * Output         : None
 15 * Return         : None
 16 *******************************************************************************/
 17 void I2C_EEInit(void)
 18 {
 19    u8 Input_Clock = 0x0;
 20   /* Get system clock frequency */
 21   Input_Clock = CLK_GetClockFreq()/1000000;    
 22   /* I2C Peripheral Enable */
 23   I2C_Cmd(ENABLE);
 24   /* Apply I2C configuration after enabling it */
 25   I2C_Init(I2C_Speed, 0xaa, I2C_DUTYCYCLE_2,\
 26             I2C_ACK_CURR, I2C_ADDMODE_7BIT, Input_Clock);//use 0xaa as master(mcu)'s addr
 27 }
 28 
 29  /*******************************************************************************
 30 * Function Name  : I2C_EE_ByteWrite
 31 * Description    : Writes one byte to the I2C EEPROM.
 32 * Input          : - pBuffer : pointer to the buffer  containing the data to be 
 33 *                    written to the EEPROM.
 34 *                  - WriteAddr : EEPROM's internal address to write to.
 35 * Output         : None
 36 * Return         : None
 37 *******************************************************************************/
 38 void I2C_EE_ByteWrite(u8* pBuffer, u16 WriteAddr)
 39 {
 40   //wait for idle
 41   while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
 42   /* Send STRAT condition */
 43   I2C_GenerateSTART(ENABLE);
 44 
 45   /* Test on EV5 and clear it */
 46     while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));  
 47   /* Send EEPROM address for write */
 48   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
 49   
 50   /* Test on EV6 and clear it */
 51    while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
 52   //for 16 bit    
 53 //  /* Send Address (on 2 bytes) of first byte to be written & wait event detection */
 54 //  I2C_SendData((u8)(WriteAddr >> 8)); /* MSB */
 55 //  /* Test on EV8 and clear it */
 56 //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
 57   I2C_SendData((u8)(WriteAddr)); /* LSB */
 58   /* Test on EV8 and clear it */
 59   while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
 60  
 61   /* Send the byte to be written */
 62   I2C_SendData(*pBuffer); 
 63    
 64   /* Test on EV8 and clear it */
 65   while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
 66   
 67   /* Send STOP condition */
 68   I2C_GenerateSTOP(ENABLE);
 69 }
 70 
 71 /*******************************************************************************
 72 * Function Name  : I2C_EE_PageWrite
 73 * Description    : Writes more than one byte to the EEPROM with a single WRITE
 74 *                  cycle. The number of byte can't exceed the EEPROM page size.
 75 * Input          : - pBuffer : pointer to the buffer containing the data to be 
 76 *                    written to the EEPROM.
 77 *                  - WriteAddr : EEPROM's internal address to write to.
 78 *                  - NumByteToWrite : number of bytes to write to the EEPROM.
 79 * Output         : None
 80 * Return         : None
 81 *******************************************************************************/
 82 //void I2C_EE_PageWrite(u8* pBuffer, u16 WriteAddr, u8 NumByteToWrite)
 83 //{
 84 //  /* While the bus is busy */
 85 //  while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
 86 //  
 87 //  /* Send START condition */
 88 //  I2C_GenerateSTART(ENABLE);
 89 //  
 90 //  /* Test on EV5 and clear it */
 91 //  while(!I2C_CheckEvent(I2C_EVENT_MASTER_START_SENT)); 
 92 //  
 93 //  /* Send EEPROM address for write */
 94 //  I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
 95 //
 96 //  /* Test on EV6 and clear it */
 97 //  while(!I2C_CheckEvent(I2C_EVENT_MASTER_ADDRESS_ACKED));
 98 //  I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);  
 99 //
100 //  /* Send Address (on 2 bytes) of first byte to be written & wait event detection */
101 //  I2C_SendData((u8)(WriteAddr >> 8)); /* MSB */
102 //  /* Test on EV8 and clear it */
103 //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
104 //  I2C_SendData((u8)(WriteAddr)); /* LSB */
105 //  /* Test on EV8 and clear it */
106 //  while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));  
107 //
108 //
109 //  /* While there is data to be written */
110 //  while(NumByteToWrite--)  
111 //  {
112 //    /* Send the current byte */
113 //    I2C_SendData(*pBuffer); 
114 //
115 //    /* Point to the next byte to be written */
116 //    pBuffer++; 
117 //  
118 //    /* Test on EV8 and clear it */
119 //    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
120 //  }
121 //
122 //  /* Send STOP condition */
123 //  I2C_GenerateSTOP(ENABLE);
124 //}
125 
126 /*******************************************************************************
127 * Function Name  : I2C_EE_BufferRead
128 * Description    : Reads a block of data from the EEPROM.
129 * Input          : - pBuffer : pointer to the buffer that receives the data read 
130 *                    from the EEPROM.
131 *                  - ReadAddr : EEPROM's internal address to read from.
132 *                  - NumByteToRead : number of bytes to read from the EEPROM.
133 * Output         : None
134 * Return         : None
135 *******************************************************************************/
136 void I2C_EE_BufferRead(u8* pBuffer, u16 ReadAddr, u8 NumByteToRead)
137 {  
138     /* While the bus is busy */
139   while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
140   
141   /* Generate start & wait event detection */
142     I2C_GenerateSTART(ENABLE);
143   /* Test on EV5 and clear it */
144     while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
145   
146   /* Send slave Address in write direction & wait detection event */
147     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
148    /* Test on EV6 and clear it */
149     while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
150     //for 10bit addr
151    /* Send Address of first byte to be read & wait event detection */
152 //    I2C_SendData((u8)(ReadAddr >> 8)); /* MSB */
153 //    /* Test on EV8 and clear it */
154 //    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
155     I2C_SendData((u8)(ReadAddr)); /* LSB */
156   /* Test on EV8 and clear it */
157     while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
158   
159   /* Send STRAT condition a second time */  
160   I2C_GenerateSTART(ENABLE);
161     /* Test on EV5 and clear it */
162   while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
163   /* Send slave Address in read direction & wait event */
164     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);
165    /* Test on EV6 and clear it */
166      while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
167   
168   /* While there is data to be read */
169   while(NumByteToRead)  
170   {
171     if(NumByteToRead == 1)
172     {
173       /* Disable Acknowledgement */
174       I2C_AcknowledgeConfig(I2C_ACK_NONE);
175       
176       /* Send STOP Condition */
177       I2C_GenerateSTOP(ENABLE);
178     }
179 
180     /* Test on EV7 and clear it */
181     if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))  
182     {      
183       /* Read a byte from the EEPROM */
184       *pBuffer = I2C_ReceiveData();
185 
186       /* Point to the next location where the byte read will be saved */
187       pBuffer++; 
188       
189       /* Decrement the read bytes counter */
190       NumByteToRead--;        
191     }   
192   }
193 
194   /* Enable Acknowledgement to be ready for another reception */
195   I2C_AcknowledgeConfig(I2C_ACK_CURR);
196 }
197 
198 uint8_t I2C_ReadRegister_SR1()
199 {
200   uint8_t temp;
201   temp=I2C->SR1;
202   return temp;
203 }
204 
205 void I2C_EE_WaitEepromStandbyState(void)      
206 {
207   u8 SR1_Tmp = 0;
208   do
209   {
210     /* Send START condition */
211     I2C_GenerateSTART(ENABLE);
212     /* Read I2C1 SR1 register */
213     SR1_Tmp =I2C_ReadRegister_SR1();
214     /* Send EEPROM address for write */
215     I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);;
216   }while(!(I2C_ReadRegister_SR1()&0x02));
217   
218   /* Clear AF flag */
219   I2C_ClearFlag(I2C_FLAG_ACKNOWLEDGEFAILURE);
220 }
221 
222 /*******************************************************************************
223 * Function Name  : I2C_EE_BufferWrite
224 * Description    : Writes buffer of data to the I2C EEPROM.
225 * Input          : - pBuffer : pointer to the buffer  containing the data to be 
226 *                    written to the EEPROM.
227 *                  - WriteAddr : EEPROM's internal address to write to.
228 *                  - NumByteToWrite : number of bytes to write to the EEPROM.
229 * Output         : None
230 * Return         : None
231 *******************************************************************************/
232 void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
233 {
234   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
235 
236   Addr = WriteAddr % Page_Byte_Size ; 
237   count = Page_Byte_Size  - Addr;
238   NumOfPage =  NumByteToWrite / Page_Byte_Size ;
239   NumOfSingle = NumByteToWrite % Page_Byte_Size ;
240  
241   /* If WriteAddr is I2C_PageSize aligned  */
242   if(Addr == 0) 
243   {
244     /* If NumByteToWrite < I2C_PageSize */
245     if(NumOfPage == 0) 
246     {
247       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
248       I2C_EE_WaitEepromStandbyState();
249     }
250     /* If NumByteToWrite > I2C_PageSize */
251     else  
252     {
253       while(NumOfPage--)
254       {
255         I2C_EE_PageWrite(pBuffer, WriteAddr, Page_Byte_Size ); 
256         I2C_EE_WaitEepromStandbyState();
257         WriteAddr +=  Page_Byte_Size ;
258         pBuffer += Page_Byte_Size ;
259       }
260 
261       if(NumOfSingle!=0)
262       {
263         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
264         I2C_EE_WaitEepromStandbyState();
265       }
266     }
267   }
268   /* If WriteAddr is not I2C_PageSize aligned  */
269   else 
270   {
271     /* If NumByteToWrite < I2C_PageSize */
272     if(NumOfPage== 0) 
273     {
274       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
275       I2C_EE_WaitEepromStandbyState();
276     }
277     /* If NumByteToWrite > I2C_PageSize */
278     else
279     {
280       NumByteToWrite -= count;
281       NumOfPage =  NumByteToWrite / Page_Byte_Size ;
282       NumOfSingle = NumByteToWrite % Page_Byte_Size ;    
283       
284       if(count != 0)
285       {  
286         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
287         I2C_EE_WaitEepromStandbyState();
288         WriteAddr += count;
289         pBuffer += count;
290       } 
291       
292       while(NumOfPage--)
293       {
294         I2C_EE_PageWrite(pBuffer, WriteAddr, Page_Byte_Size );
295         I2C_EE_WaitEepromStandbyState();
296         WriteAddr += Page_Byte_Size ;
297         pBuffer += Page_Byte_Size ;  
298       }
299       if(NumOfSingle != 0)
300       {
301         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); 
302         I2C_EE_WaitEepromStandbyState();
303       }
304     }
305   }  
306 }

目前测试过的,初始化肯定不用说,字节写测试通过,连续读测试通过,连续写还未测试,照理也可以的23333

 1 #ifndef DS3231_H
 2 #define DS3231_H
 3 
 4   
 5 #include "pt6311.h"
 6 #include "i2c_ee.h"
 7 
 8 #define DS3231_WriteAddress 0xD0    //器件写地址 
 9 #define DS3231_ReadAddress  0xD1    //器件读地址
10 
11 #define DS3231_SECOND       0x00    //
12 #define DS3231_MINUTE       0x01    //
13 #define DS3231_HOUR         0x02    //
14 #define DS3231_WEEK         0x03    //星期
15 #define DS3231_DAY          0x04    //
16 #define DS3231_MONTH        0x05    //
17 #define DS3231_YEAR         0x06    //
18 //闹铃1            
19 #define DS3231_SALARM1ECOND 0x07    //
20 #define DS3231_ALARM1MINUTE 0x08    //
21 #define DS3231_ALARM1HOUR   0x09    //
22 #define DS3231_ALARM1WEEK   0x0A    //星期/日
23 //闹铃2
24 #define DS3231_ALARM2MINUTE 0x0b    //
25 #define DS3231_ALARM2HOUR   0x0c    //
26 #define DS3231_ALARM2WEEK   0x0d    //星期/日
27 #define DS3231_CONTROL      0x0e    //控制寄存器
28 #define DS3231_STATUS       0x0f    //状态寄存器
29 #define BSY                 2       //
30 #define OSF                 7       //振荡器停止标志
31 #define DS3231_XTAL         0x10    //晶体老化寄存器
32 #define DS3231_TEMPERATUREH 0x11    //温度寄存器高字节(8位)
33 #define DS3231_TEMPERATUREL 0x12    //温度寄存器低字节(高2位)  
34 
35 u8 BCD2DEC(u8 val);    //BCD转换为Byte
36 u8 DEC2BCD(u8 val);    //B码转换为BCD码
37 
38 void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec);
39 void get_show_time(void);
40 void get_show_Temperature(void);
41 #endif
 1 #include "ds3231.h"
 2 
 3 
 4  
 5 u8 BCD2DEC(u8 val)    //BCD转换为DEC
 6 {
 7     u8 temp;
 8     temp=(val/16)*10+(val%16);
 9    
10     return temp;
11 }
12 
13 u8 DEC2BCD(u8 val)    //DEC码转换为BCD码
14 {
15     u8 k;
16     k=(val%10)+((val/10)<<4);
17     return k;
18 }
19 
20 void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
21 {
22     u8 temp=0;
23    
24     temp=DEC2BCD(yea);
25     I2C_EE_ByteWrite(&temp,DS3231_YEAR);   //修改年
26    
27     temp=DEC2BCD(mon);
28     I2C_EE_ByteWrite(&temp,DS3231_MONTH);  //修改月
29    
30     temp=DEC2BCD(da);
31     I2C_EE_ByteWrite(&temp,DS3231_DAY);    //修改日
32    
33     temp=DEC2BCD(hou);
34     I2C_EE_ByteWrite(&temp,DS3231_HOUR);   //修改时
35    
36     temp=DEC2BCD(min);
37     I2C_EE_ByteWrite(&temp,DS3231_MINUTE); //修改分
38    
39     temp=DEC2BCD(sec);
40     I2C_EE_ByteWrite(&temp,DS3231_SECOND); //修改秒
41     
42 }
43 
44 void get_show_time(void)
45 {
46     u8 data[7],i; //save time
47  
48     I2C_EE_BufferRead(data,0,7);//S->Y 0->6
49     data[2]&=0x3f;//get true hour
50     //bcd to dec
51     for (i=0;i<7;i++)
52         data[i]=BCD2DEC(data[i]);
53     dspseg[11]=data[0]%10;
54     dspseg[10]=data[0]/10;    
55     dspseg[9]=data[1]%10;
56     dspseg[8]=data[1]/10;
57     dspseg[7]=data[2]%10;
58     dspseg[6]=data[2]/10;
59 }
60 
61 void get_show_Temperature(void)
62 {
63     u8 temp[2]; 
64    //temph  _(sign) _ _ _, _ _ _ _
65     //templ (point)_ _0 0, 0 0 0 0 
66     I2C_EE_BufferRead(temp,DS3231_TEMPERATUREH,2);  
67    
68     temp[0]=BCD2DEC(temp[0]);//int,default in positive temperature
69     temp[1]=(temp[1]>>6)*25;//decimal 
70     
71     dspseg[5]=temp[0]%10;
72     dspseg[4]=temp[0]/10;
73     
74 }

懒得上main.c了,有心人一下子就搞出来了,我api都写的差不多了,剩下按键改时间,以及闹钟设置,可选的gps校时

 


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

晒图:

 

 

 

手工版做了估计有六七块,主要是打印机喷的墨不够,而且油笔不给力,描了也没有用。这几张图是后期版本的,没有大面积铺铜,简直不堪入目233333


 

posted @ 2018-01-21 14:47  katachi  阅读(3974)  评论(0编辑  收藏  举报