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
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 }
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
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 }
主程序流程就是定时器中断产生节拍,然后去读3231,显示,以及串口命令解析
效果图:
这个屏比较长,pcb只画了10cm,设计时忘记考虑usb口了,短在里面难受!
安鑫那边应该还在卖。
这个月点了3个VFD屏,还屯了不少。中间快递丢了,重新花50+RMB重新买,都是泪,哭。
以上是关于VFD Clock with STM8 v2.0的主要内容,如果未能解决你的问题,请参考以下文章
LC 1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows