VFD Clock with STM8 v2.0

Posted katachi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VFD Clock with STM8 v2.0相关的知识,希望对你有一定的参考价值。

算是填了最先挖的VFD坑

最近pcb厂家神仙打架,为PCB普及做出了巨大贡献,到这事儿发生我也就开了两三次板,都赶上这个时间了,不开白不开!

 


 不说了,上图!

sch:

技术图片

pcb:

技术图片

方案和之前的除了驱动电路都一样,以前那个自己绕变压器的方案发热量太大了。但是那组电路参数照样可以用的。

这次pcb除了几处纰漏,灯丝高压应该直接改为负高压,还有就是pmos不知道为啥错位了,可能是拼版的时候不小心移动了。

至于程序方面大部分直接用,由于不想改显示驱动,grid和digit还是将错就错,加一步call transcode() 罢了。

改动比较大的就是ds3231的驱动,原来使用stm8硬件iic。这次一开始调试的时候总是卡在忙,以前也有这个现象,一怒之下直接改成软件iic。

把以前的驱动拿过来改改方法就成了。

iic.h

技术图片
 1 #ifndef __MYIICDS3231_H
 2 #define __MYIICDS3231_H
 3 #include "stm8s.h"
 4 #include "delay.h"
 5 #include "iostm8s103f3.h"        //inc the .h to use bit control
 6 
 7 //transplanted to dsd3231
 8 //modyfied:
 9 //1.only leave 8 bit to work
10 //2.change the related macro definition
11 //3.use newer stm8s_i2c.h
12 //By katachi time:2018-1-20
13 //new added 19-3-14:
14 //DS3231IIC_BufferRead() 
15 //new modify 19-4-12 fot stc15
16 //new modify 4-2x for stm8 software iic
17 
18 ////IO方向设置
19 //#define DS3231IIC_SDA_IN()  {GPIOB->CRL&=0XFFFFF0FF;GPIOB->CRL|=8<<8;}
20 //#define DS3231IIC_SDA_OUT() {GPIOB->CRL&=0XFFFFF0FF;GPIOB->CRL|=3<<8;}
21 
22 ////IO操作函数     
23 //#define DS3231IIC_SCL    PBout(3) //SCL
24 //#define DS3231IIC_SDA    PBout(2) //SDA     
25 //#define DS3231IIC_READ_SDA   PBin(2)  //输入SDA 
26 
27 ////IO方向设置
28 #define DS3231IIC_SDA_IN()  {GPIO_Init(GPIOB,(GPIO_PIN_5),GPIO_MODE_IN_PU_NO_IT);}
29 #define DS3231IIC_SDA_OUT() {GPIO_Init(GPIOB,(GPIO_PIN_5),GPIO_MODE_OUT_PP_HIGH_FAST);}
30 
31 ////IO操作函数     
32 #define DS3231IIC_SCL    PB_ODR_ODR4 //SCL
33 #define DS3231IIC_SDA    PB_ODR_ODR5 //SDA     
34 #define DS3231IIC_READ_SDA   PB_IDR_IDR5  //输入SDA 
35 
36 //IIC所有操作函数
37 void DS3231IIC_Init(void);                //初始化IIC的IO口                 
38 void DS3231IIC_Start(void);                //发送IIC开始信号
39 void DS3231IIC_Stop(void);                  //发送IIC停止信号
40 void DS3231IIC_Send_Byte(u8 txd);            //IIC发送一个字节
41 u8 DS3231IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
42 u8 DS3231IIC_Wait_Ack(void);                 //IIC等待ACK信号
43 void DS3231IIC_Ack(void);                    //IIC发送ACK信号
44 void DS3231IIC_NAck(void);                //IIC不发送ACK信号
45 
46 void DS3231IIC_Write_One_Byte(u8 addr,u8 dat);
47 u8 DS3231IIC_Read_One_Byte(u8 addr);      
48 void DS3231IIC_BufferRead(u8 *buffer,u8 startAddr,u8 bufferLen);
49 void DS3231IIC_ReverseDirBufferRead(u8 *buffer,u8 startAddr,u8 bufferLen);
50 #endif
View Code

iic.c

技术图片
  1 #include "myiicForDs3231.h"
  2 #include "ds3231.h"            //only for iic addr
  3 #include "delay.h"
  4 
  5 
  6 //初始化IIC
  7 void DS3231IIC_Init(void)
  8 {                         
  9 ////    GPIO_InitTypeDef GPIO_InitStructure;
 10 ////    RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );    
 11 ////    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  //remapping pb4,3 from jtag to general gpio
 12 ////    
 13 ////    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
 14 ////    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
 15 ////    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 16 ////    GPIO_Init(GPIOB, &GPIO_InitStructure);
 17 
 18         GPIO_Init(GPIOB,(GPIO_PIN_5|GPIO_PIN_4),GPIO_MODE_OUT_PP_HIGH_FAST); //scl pb4;sda pb5
 19     DS3231IIC_SCL=1;
 20     DS3231IIC_SDA=1;
 21     delay_ms(50);
 22 }
 23 //产生IIC起始信号
 24 void DS3231IIC_Start(void)
 25 {
 26     DS3231IIC_SDA_OUT();     //sda线输出
 27     DS3231IIC_SDA=1;            
 28     DS3231IIC_SCL=1;
 29     delay_us(4);
 30      DS3231IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
 31     delay_us(4);
 32     DS3231IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
 33 }      
 34 //产生IIC停止信号
 35 void DS3231IIC_Stop(void)
 36 {
 37     DS3231IIC_SDA_OUT();//sda线输出
 38     DS3231IIC_SCL=0;
 39     DS3231IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 40      delay_us(4);
 41     DS3231IIC_SCL=1; 
 42     DS3231IIC_SDA=1;//发送I2C总线结束信号
 43     delay_us(4);                                   
 44 }
 45 //等待应答信号到来
 46 //返回值:1,接收应答失败
 47 //        0,接收应答成功
 48 u8 DS3231IIC_Wait_Ack(void)
 49 {
 50     u8 ucErrTime=0;
 51     DS3231IIC_SDA_IN();      //SDA设置为输入  
 52     DS3231IIC_SDA=1;delay_us(1);       
 53     DS3231IIC_SCL=1;delay_us(1);     
 54     while(DS3231IIC_READ_SDA)
 55     {
 56         ucErrTime++;
 57         if(ucErrTime>250)
 58         {
 59             DS3231IIC_Stop();
 60             return 1;
 61         }
 62     }
 63     DS3231IIC_SCL=0;//时钟输出0        
 64     return 0;  
 65 } 
 66 //产生ACK应答
 67 void DS3231IIC_Ack(void)
 68 {
 69     DS3231IIC_SCL=0;
 70     DS3231IIC_SDA_OUT();
 71     DS3231IIC_SDA=0;
 72     delay_us(2);
 73     DS3231IIC_SCL=1;
 74     delay_us(2);
 75     DS3231IIC_SCL=0;
 76 }
 77 //不产生ACK应答            
 78 void DS3231IIC_NAck(void)
 79 {
 80     DS3231IIC_SCL=0;
 81     DS3231IIC_SDA_OUT();
 82     DS3231IIC_SDA=1;
 83     delay_us(2);
 84     DS3231IIC_SCL=1;
 85     delay_us(2);
 86     DS3231IIC_SCL=0;
 87 }                                          
 88 //IIC发送一个字节
 89 //返回从机有无应答
 90 //1,有应答
 91 //0,无应答              
 92 void DS3231IIC_Send_Byte(u8 txd)
 93 {                        
 94     u8 t;   
 95     DS3231IIC_SDA_OUT();         
 96     DS3231IIC_SCL=0;//拉低时钟开始数据传输
 97     for(t=0;t<8;t++)
 98     {              
 99         DS3231IIC_SDA=(txd&0x80)>>7;
100         txd<<=1;       
101         delay_us(2);   //对TEA5767这三个延时都是必须的
102         DS3231IIC_SCL=1;
103         delay_us(2); 
104         DS3231IIC_SCL=0;    
105         delay_us(2);
106     }     
107 }         
108 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
109 u8 DS3231IIC_Read_Byte(unsigned char ack)
110 {
111     unsigned char i,receive=0;
112     DS3231IIC_SDA_IN();//SDA设置为输入
113     for(i=0;i<8;i++ )
114     {
115         DS3231IIC_SCL=0; 
116         delay_us(2);
117         DS3231IIC_SCL=1;
118         receive<<=1;
119         if(DS3231IIC_READ_SDA)receive++;   
120         delay_us(1); 
121     }                     
122     if (!ack)
123         DS3231IIC_NAck();//发送nACK
124     else
125         DS3231IIC_Ack(); //发送ACK   
126     return receive;
127 }
128 void DS3231IIC_Write_One_Byte(u8 addr,u8 dat){
129     DS3231IIC_Start();
130     DS3231IIC_Send_Byte(DS3231_WriteAddress);
131     DS3231IIC_Wait_Ack();
132     DS3231IIC_Send_Byte(addr);
133     DS3231IIC_Wait_Ack();
134     DS3231IIC_Send_Byte(dat);
135     DS3231IIC_Wait_Ack();
136     DS3231IIC_Stop();    
137 }
138 u8 DS3231IIC_Read_One_Byte(u8 addr){
139         u8 tmp;
140 
141     DS3231IIC_Start();
142     DS3231IIC_Send_Byte(DS3231_WriteAddress);
143     DS3231IIC_Wait_Ack();
144     DS3231IIC_Send_Byte(addr);
145     DS3231IIC_Wait_Ack();
146     
147     DS3231IIC_Start();
148     DS3231IIC_Send_Byte(DS3231_ReadAddress);
149     DS3231IIC_Wait_Ack();
150     tmp = DS3231IIC_Read_Byte(0);
151     DS3231IIC_Stop();    
152   
153     return tmp;
154 }
155 void DS3231IIC_BufferRead(u8 *buffer, u8 startAddr, u8 bufferLen)
156 {      
157     u8 t,add=startAddr;
158     
159     for(t=0;t<bufferLen;t++)
160     {
161             *buffer=DS3231IIC_Read_One_Byte(add++);
162             buffer++;
163     }
164 }
165 void DS3231IIC_ReverseDirBufferRead(u8 *buffer, u8 startAddr, u8 bufferLen)
166 {      
167     u8 t,add=startAddr;
168     
169     for(t=0;t<bufferLen;t++)
170     {
171             *buffer=DS3231IIC_Read_One_Byte(add--);
172             buffer++;
173     }
174 }
View Code

main.c

技术图片
  1 #include "stm8s.h"
  2 #include "stm8s_clk.h"
  3 #include "intrinsics.h"
  4 #include "stm8s_uart1.h"
  5 #include "uart.h"
  6 #include "sysclock.h"
  7 #include "delay.h"
  8 #include "stm8s_i2c.h"
  9 #include "pt6311.h"
 10 #include "ds3231.h"
 11 #include "myiicForDs3231.h"
 12 #include "stm8s_tim1.h"
 13 
 14 
 15 void Tim1_Init(void)
 16 {
 17   TIM1_TimeBaseInit(15,TIM1_COUNTERMODE_UP,10000,0);//10ms
 18   TIM1_ARRPreloadConfig(ENABLE);
 19   TIM1_ITConfig(TIM1_IT_UPDATE , ENABLE);
 20   TIM1_Cmd(ENABLE);
 21 }
 22 
 23 u8 t_flag,tempOrDate_flag,cnt_5s;
 24 
 25 int main(void)
 26 {
 27     u8 dat[6];
 28     //use this fuction to choose a clock
 29     SystemClock_Init(HSI_Clock);    //hsi
 30 
 31     //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
 32 
 33     /*!<Set High speed internal clock  */
 34     Uart_Init();
 35         delay_init(16);//@delay.c
 36         
 37         DS3231IIC_Init();
 38     delay_ms(100); 
 39     //ModifyTime(4,30,2,0,16,0);//set a default time to avoid error!!!
 40     __enable_interrupt();//enable it
 41     printf("now system start!!!\\r\\n");
 42      Init_PT6311();//initialize pt6311 
 43     //DeDisplayVfd();//dedisplay vfd screen
 44         Tim1_Init();
 45    while (1)
 46    {
 47      if (t_flag){
 48       t_flag=0;
 49       if (++cnt_5s>=10)
 50       {
 51         cnt_5s=0;
 52         if (++tempOrDate_flag>=3)tempOrDate_flag=0;//0->date 1->temperature 2->week
 53 
 54         if (tempOrDate_flag==0){
 55           get_date(dat);
 56           dspseg[1]=dat[0]/10;
 57           dspseg[2]=dat[0]%10;//mon
 58                  
 59           dspseg[3]=(dat[1]/10);
 60           dspseg[4]=dat[1]%10;//day
 61           
 62           dspseg[5]=dat[2];//wk
 63           dspseg[12]=dat[2];//dspseg[12] 0-3:wk 4-7:sec
 64         }
 65         else if (tempOrDate_flag==1){
 66           get_Temperature(dat);
 67           dspseg[0]=dat[0]/3;
 68           dspseg[1]=t;
 69           dspseg[2]=36|COLON;
 70                  
 71           dspseg[3]=(dat[0]/10);
 72           dspseg[4]=dat[0]%10;
 73           dspseg[5]=c;
 74         }
 75         else{
 76           get_date(dat);
 77           WeekDisplay(dat[2]);
 78           dspseg[4]=36;
 79           dspseg[5]=36;//clr
 80         }
 81       }
 82       get_time(&dat[3]);//get h m s
 83       dspseg[6]=dat[3]/10;  //h
 84       dspseg[7]=dat[3]%10|COLON;
 85       
 86       dspseg[8]=dat[4]/10;    //min
 87       dspseg[9]=(dat[4]%10)|COLON;
 88       
 89       dspseg[10]=dat[5]/10;
 90       dspseg[11]=(dat[5]%10);//sec
 91       dspseg[12]=(dspseg[12]&0x0f)|(dspseg[11]<<4);//dspseg[12] 0-3:wk 4-7:sec//ui moving
 92       if ((dat[3]<=23) && (dat[3]>=5)){
 93       OpenStrobe_PT6311();
 94       WriteByte_PT6311(CMD_DisplaySetting|0x08|4);    
 95       STB=1;
 96       }else
 97       {
 98       OpenStrobe_PT6311();
 99       WriteByte_PT6311(CMD_DisplaySetting|0x08|2);    
100       STB=1;      
101       }
102       DisplayVfd();//reflash vfd   
103      }
104       if(UART_RX_NUM&0x80)//uart catch
105       {
106         CMD_Compare();
107       }
108     }
109 }
110 
111 
112 //#ifdef USE_FULL_ASSERT    //@stm8s_conf.h commented the macro
113 //
114 ///**
115 //  * @brief  Reports the name of the source file and the source line number
116 //  *   where the assert_param error has occurred.
117 //  * @param file: pointer to the source file name
118 //  * @param line: assert_param error line source number
119 //  * @retval : None
120 //  */
121 //void assert_failed(u8* file, u32 line)
122 //{ 
123 //  /* User can add his own implementation to report the file name and line number,
124 //     ex: printf("Wrong parameters value: file %s on line %d\\r\\n", file, line) */
125 //
126 //  /* Infinite loop */
127 //  while (1)
128 //  {
129 //  }
130 //}
131 //#endif
View Code

uart.c

技术图片
  1 #include "uart.h"
  2 #include "stm8s.h"
  3 #include "stm8s_clk.h"
  4 #include <stdarg.h>
  5 #include "string.h"
  6 #include "pt6311.h"
  7 #include "ds3231.h"
  8 
  9 /* ********************************************
 10 UART1  configured as follow:
 11   - BaudRate = 115200 baud  
 12   - Word Length = 8 Bits
 13   - One Stop Bit
 14   - No parity
 15   - Receive and transmit enabled
 16  -  Receive interrupt
 17   - UART1 Clock disabled
 18 *********************************************/
 19 void DataDel(u8 *str,u8 len)
 20 {
 21     u8 i;
 22     for (i=0;i<len-8;i++)
 23         str[i]=str[i+8];
 24 }
 25 void CMD_Compare(void)    //
 26 {
 27   u8 tmp[9]={0};
 28   u8 i,len;
 29   
 30   len=UART_RX_NUM&0x3f;//get the length
 31   printf("\\r\\nWhat you have in put is:\\r\\n");
 32   UART1_SendString(RxBuffer,len);
 33   printf("\\r\\n");
 34   //get cmd
 35 //  for (i=0;i<8;i++)    
 36 //    tmp[i]=RxBuffer[i];
 37   strncpy(tmp,(const char*)RxBuffer,8);
 38   //cmd explaine
 39   if (strcmp("cmd_time",(const char*)tmp)==0)
 40   {
 41     printf("now modify time!\\r\\n");
 42     DataDel(RxBuffer,len);//del cmd to get data
 43     //combine the data && transport from ascii to value
 44     //ModifyTime(4,12,5,11,21,0);// 4-12 w5 tm11-21-00
 45     ModifyTime((RxBuffer[0]-0)*10 + RxBuffer[1]-0,    //month
 46                                                     (RxBuffer[2]-0)*10 + RxBuffer[3]-0,//day
 47                                                     (RxBuffer[4]-0),                                            //week
 48                                                     (RxBuffer[5]-0)*10 + RxBuffer[6]-0,//hr
 49                                                     (RxBuffer[7]-0)*10 + RxBuffer[8]-0,//min
 50                                                     (RxBuffer[9]-0)*10 + RxBuffer[10]-0);//sec
 51   }
 52   else if (strcmp("cmd_ala1",(const char*)tmp)==0)
 53   {
 54     
 55   }
 56   else if(strcmp("cmd_ligh",(const char*)tmp)==0)
 57   {
 58     printf("now modify light!\\r\\n");
 59     DataDel(RxBuffer,len);//del cmd to get data      
 60     RxBuffer[0]-=0;
 61     
 62     printf("to level :%d", RxBuffer[0]);
 63       OpenStrobe_PT6311();
 64       WriteByte_PT6311(CMD_DisplaySetting|0x08|RxBuffer[0]);//on 14/16    
 65       STB=1;
 66   }
 67     //clr
 68     for (i=0;i<len;i++)
 69         RxBuffer[i]=0;
 70     UART_RX_NUM=0;//clr
 71 }
 72 void Uart_Init(void)
 73 {
 74     UART1_DeInit();
 75     UART1_Init((u32)115200, UART1_WORDLENGTH_8D, UART1_STOPBITS_1,  76     UART1_PARITY_NO , UART1_SYNCMODE_CLOCK_DISABLE , UART1_MODE_TXRX_ENABLE);
 77     UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE  );
 78     UART1_Cmd(ENABLE );
 79   
 80 }
 81 
 82 void UART1_SendByte(u8 data)
 83 {
 84     UART1_SendData8((unsigned char)data);
 85   /* Loop until the end of transmission */
 86   while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 87 }
 88 
 89 void UART1_SendString(u8* Data,u16 len)
 90 {
 91   u16 i=0;
 92   for(;i<len;i++)
 93     UART1_SendByte(Data[i]);
 94   
 95 }
 96 
 97 u8 UART1_ReceiveByte(void)
 98 {
 99      u8 USART1_RX_BUF; 
100      while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET);
101      USART1_RX_BUF=UART1_ReceiveData8();
102      return  USART1_RX_BUF;
103     
104 }
105 
106 /*
107  * 函数名:fputc
108  * 描述  :重定向c库函数printf到USART1
109  * 输入  :无
110  * 输出  :无
111  * 调用  :由printf调用
112  */
113 int fputc(int ch, FILE *f)
114 {  
115 /* 将Printf内容发往串口 */
116   UART1_SendData8((unsigned char) ch);
117   while (!(UART1->SR & UART1_FLAG_TXE));
118  
119   return (ch);
120 }
View Code

 

主程序流程就是定时器中断产生节拍,然后去读3231,显示,以及串口命令解析

 效果图:

技术图片

技术图片

这个屏比较长,pcb只画了10cm,设计时忘记考虑usb口了,短在里面难受!

安鑫那边应该还在卖。

技术图片

这个月点了3个VFD屏,还屯了不少。中间快递丢了,重新花50+RMB重新买,都是泪,哭。

 

以上是关于VFD Clock with STM8 v2.0的主要内容,如果未能解决你的问题,请参考以下文章

STM8串口初始化寄存器配置

STM8S UART串口发送程序问题.

VFD显示编程

PostgreSQL VFD机制

制作openstack镜像win7.qcow2

LC 1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows