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通讯
//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()/;
/* 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 == )
{
/* 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 = ;
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 = , NumOfSingle = , Addr = , count = ; 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 == )
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage == )
{
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!=)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
/* If WriteAddr is not I2C_PageSize aligned */
else
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage== )
{
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 != )
{
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 != )
{
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/)*+(val%); return temp;
} u8 DEC2BCD(u8 val) //DEC码转换为BCD码
{
u8 k;
k=(val%)+((val/)<<);
return k;
} void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
{
u8 temp=; 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[],i; //save time I2C_EE_BufferRead(data,,);//S->Y 0->6
data[]&=0x3f;//get true hour
//bcd to dec
for (i=;i<;i++)
data[i]=BCD2DEC(data[i]);
dspseg[]=data[]%;
dspseg[]=data[]/;
dspseg[]=data[]%;
dspseg[]=data[]/;
dspseg[]=data[]%;
dspseg[]=data[]/;
} void get_show_Temperature(void)
{
u8 temp[];
//temph _(sign) _ _ _, _ _ _ _
//templ (point)_ _0 0, 0 0 0 0
I2C_EE_BufferRead(temp,DS3231_TEMPERATUREH,); temp[]=BCD2DEC(temp[]);//int,default in positive temperature
temp[]=(temp[]>>)*;//decimal dspseg[]=temp[]%;
dspseg[]=temp[]/; }
懒得上main.c了,有心人一下子就搞出来了,我api都写的差不多了,剩下按键改时间,以及闹钟设置,可选的gps校时
注意stm8s_i2c.h这个头应该是11年那个比较大的头,起初那个不行,后来根据风驰的eeprom教程移植,它用的也是我说的这个新点的库
晒图:
手工版做了估计有六七块,主要是打印机喷的墨不够,而且油笔不给力,描了也没有用。这几张图是后期版本的,没有大面积铺铜,简直不堪入目233333