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
路漫漫其修远兮,吾将上下而求索