• VFD 时钟(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!!!
    ");
     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
    ", 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("
    What you have in put is:
    ");
     32   UART1_SendString(RxBuffer,len);
     33   printf("
    ");
     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!
    ");
     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!
    ");
     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重新买,都是泪,哭。

  • 相关阅读:
    IntelliJ IDEA maven库下载依赖包速度慢的问题
    安装 PHP
    秒杀怎么样才可以防止超卖?基于mysql的事务和锁实现
    MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
    架构师之路16年精选50篇
    基于ELK和Python搭建简单的监控告警系统
    MySQL5.7 利用keepalived来实现mysql双主高可用方案的详细过程
    在线数据迁移
    jedisLock—redis分布式锁实现
    Intellij IDEA 最新旗舰版注册激活破解(2018亲测,可用)
  • 原文地址:https://www.cnblogs.com/katachi/p/10804056.html
Copyright © 2020-2023  润新知