2018-01-14 22:50:26
之前写了pt6311的驱动,要做时钟考虑使用stm8做主控,于是乎将之前的驱动移植到stm8上。
顺带熟悉了stm8的操作2333.
上源码:
1 #ifndef PT6311_H 2 #define PT6311_H 3 4 #include "stm8s.h" 5 #include "delay.h" 6 #include "iostm8s103f3.h" //inc the .h to use bit control 7 8 9 extern u8 dspbuf[30],dspseg[13]; 10 extern const u8 ADDR[30]; //addr 11 extern const u16 font[37]; //font 12 13 #define GPS 0x08 14 #define ALARM 0x10 15 #define ALL 0x20 16 #define CONT 0x40 17 #define LP 0x80 18 19 #define COLON 0x80 //personal protocal 20 #define CLR 36 21 //pin definition 22 #define DI PC_ODR_ODR5 //@vfd board //for stm32 test//PCout(2) 23 #define DO PC_IDR_IDR6 //PCin(3) 24 #define CK PC_ODR_ODR4 //PCout(0) 25 #define STB PC_ODR_ODR3 //PCout(13) 26 27 void InitIo_PT6311(void); 28 void Init_PT6311(void); 29 void OpenStrobe_PT6311(void); 30 void WriteByte_PT6311(u8 dat); 31 u8 ReadByte_PT6311(void); 32 void TransCoding(void);//transcoding 33 unsigned int Pow2(u8 y); 34 #define CMD_ModeSetting 0x00 35 #define CMD_DataSetting 0x40 36 #define CMD_AddressSetting 0xc0 37 #define CMD_DisplaySetting 0x80 38 39 #endif
1 #include "pt6311.h" 2 #include "stdio.h" 3 4 //auth:katachi 5 //time:2017-12-30 6 //func:driver for pt6311 7 //transplant to stm8 time:2018-1-14 17: 8 const u8 ADDR[]={0x00,0x01,//digit 1 9 0x03,0x04,//digit 2 10 0x06,0x07,//digit 3 11 0x09,0x0a,//digit 4 12 0x0c,0x0d,//digit 5 13 0x0f,0x10,//digit 6 14 0x12,0x13,//digit 7 15 0x15,0x16,//digit 8 16 0x18,0x19,//digit 9 17 0x1B,0x1C,//digit 10 18 0x1E,0x1F,//digit 11 19 0x21,0x22,//digit 12 20 0x24,0x25,//digit 13 21 0x27,0x28,//digit 14 22 0x2a,0x2b};//digit 15 23 const u16 font[37]={ 24 0x7266,0x2040,0x6186,0x61c2,0x23c0,0x43c2,0x43c6,0x5020,0x63c6,0x63c2,//0-9 25 0x30e0,0x68d2,0x4206,0x6852,0x4386,0x4384,0x42ce,0x23c4,0x4812,0x2048, 26 0x130c,0x206,0x3644,0x264c,0x6246,0x6384,0x624e,0x638c,0x43c2,0x4810, 27 0x2246,0x1224,0x226c,0x1428,0x1410,0x5022,//a-z 28 0};//: 29 u8 dspbuf[30],dspseg[13]; 30 unsigned int Pow2(u8 y) 31 { 32 u16 x=1; 33 if (y) 34 { 35 while (y--) 36 x*=2; 37 } 38 else 39 x=1; 40 return x; 41 } 42 void TransCoding(void)//recongnize num or char or with colon and transcoding the dspseg to pt6311 ram 43 { 44 u8 i=0,j=0;u16 tmp=0; 45 46 for (i=0;i<30;i++)dspbuf[i]=0;//clrclr!!!! 47 for (i=0;i<13;i++)//seg==i 48 { 49 if (i==0) //for segment 0 display temp lvl 50 { 51 tmp=Pow2(dspseg[0]) - 1; 52 tmp<<=4; 53 } 54 else if (i==12)//for ui 55 { 56 //dspseg[12] 8bit 57 // _ _ _ _ , _ _ _ _ 58 // LOWPOWER CONTINUPAUSE ALL ALARM GPS WEEK 59 j=dspseg[12]; 60 61 if (j&0x08)//GPS 62 tmp=0x80; //= 63 if (j&0x10)//ALARM 64 tmp|=0x20; //|= 65 if (j&0x20)//ALL 66 tmp|=0x300; 67 if (j&0x40)//CT 68 tmp|=0xc00; 69 if (j&0x80)//LP 70 tmp|=0x7000; 71 j&=0x07;//get week 72 j--; 73 if (j>4)//sat sun 74 tmp|=j+1; 75 else //mon to fri 76 tmp|=1<<j; 77 } 78 else 79 { 80 //tmp=font['p'-87+i];//ascii to personal font 81 if (dspseg[i]>0x80)//num with colon 82 { 83 dspseg[i]-=0x80; 84 tmp=font[dspseg[i]]+1; 85 } 86 else if (dspseg[i]>90 && dspseg[i]<0x80)//charac 87 tmp=font[dspseg[i]-87]; 88 else 89 tmp=font[dspseg[i]];//plain num 90 } 91 //transcoding 92 if(i<8) 93 { 94 for (j=0;j<15;j++) 95 { 96 dspbuf[2*j]|=(tmp&0x1)<<i; 97 tmp>>=1; 98 } 99 } 100 else 101 { 102 for (j=1;j<16;j++) 103 { 104 dspbuf[2*j-1]|=(tmp&0x1)<<(i-8); 105 tmp>>=1; 106 } 107 } 108 } 109 } 110 void OpenStrobe_PT6311(void) 111 { 112 STB=1; 113 delay_us(1); 114 STB=0; 115 } 116 void InitIo_PT6311() 117 {//from stm32 118 // GPIO_InitTypeDef GPIO_InitStructure; 119 // 120 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //enable portc 121 // 122 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_13; 123 // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ppout 124 // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 125 // GPIO_Init(GPIOC, &GPIO_InitStructure); 126 // 127 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 128 // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 129 // GPIO_Init(GPIOC, &GPIO_InitStructure); 130 //move to stm8 131 GPIO_Init(GPIOC,(GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5),GPIO_MODE_OUT_PP_HIGH_FAST);//portC 345 pp mode 132 GPIO_Init(GPIOC,(GPIO_PIN_6),GPIO_MODE_IN_FL_NO_IT);//portC 6 FLin 133 } 134 void Init_PT6311(void) 135 { 136 u8 i; 137 138 InitIo_PT6311(); 139 140 OpenStrobe_PT6311(); 141 WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg 142 143 OpenStrobe_PT6311(); 144 WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr 145 146 for (i=0;i<30;i++) 147 { 148 OpenStrobe_PT6311(); 149 WriteByte_PT6311(CMD_AddressSetting|ADDR[i]); 150 WriteByte_PT6311(0x00); 151 } 152 153 OpenStrobe_PT6311(); 154 WriteByte_PT6311(CMD_DisplaySetting|0x0f);//on 14/16 155 } 156 void WriteByte_PT6311(u8 dat) 157 { 158 u8 i; 159 160 CK=1;//de-pulldown 161 for (i=0;i<8;i++) 162 { 163 CK=0; //>>200ns 164 DI=dat&0x01; //send a bit to pt6311's data in pin 165 dat>>=1; //lsb first 166 CK=1; 167 } 168 } 169 u8 ReadByte_PT6311(void) 170 { 171 u8 dat,i; 172 CK=1; 173 delay_us(2); 174 for (i=0;i<8;i++) 175 { 176 CK=0;//while (j++<10); 177 delay_us(1);//tplz tpzl 178 dat>>=1; //lsb first 179 if (DO) 180 dat|=0x80; //catch a bit from pt6311's data out pin 181 CK=1; 182 } 183 delay_us(1);//tclk stb 184 return dat; 185 }
用到了原子哥写的stm8精确软件延时,感谢!!!
1 #ifndef __DELAY_H 2 #define __DELAY_H 3 4 //////////////////////////////////////////////////////////////////////////////// 5 //使用汇编代码进行精确延时处理 6 //包括delay_us,delay_ms 7 #include "stm8s.h" 8 9 void delay_init(u8 clk); //延时函数初始化 10 void delay_us(u16 nus); //us级延时函数,最大65536us. 11 void delay_ms(u32 nms); //ms级延时函数 12 #endif
1 #include "delay.h" 2 3 4 5 volatile u8 fac_us=0; //us延时倍乘数 6 7 //延时函数初始化 8 //为确保准确度,请保证时钟频率最好为4的倍数,最低8Mhz 9 //clk:时钟频率(24/16/12/8等) 10 void delay_init(u8 clk) 11 { 12 if(clk>16)fac_us=(16-4)/4;//24Mhz时,stm8大概19个周期为1us 13 else if(clk>4)fac_us=(clk-4)/4; 14 else fac_us=1; 15 } 16 //延时nus 17 //延时时间=(fac_us*4+4)*nus*(T) 18 //其中,T为CPU运行频率(Mhz)的倒数,单位为us. 19 //准确度: 20 //92% @24Mhz 21 //98% @16Mhz 22 //98% @12Mhz 23 //86% @8Mhz 24 void delay_us(u16 nus) 25 { 26 __asm( 27 "PUSH A " //1T,压栈 28 "DELAY_XUS: " 29 "LD A,fac_us " //1T,fac_us加载到累加器A 30 "DELAY_US_1: " 31 "NOP " //1T,nop延时 32 "DEC A " //1T,A-- 33 "JRNE DELAY_US_1 " //不等于0,则跳转(2T)到DELAY_US_1继续执行,若等于0,则不跳转(1T). 34 "NOP " //1T,nop延时 35 "DECW X " //1T,x-- 36 "JRNE DELAY_XUS " //不等于0,则跳转(2T)到DELAY_XUS继续执行,若等于0,则不跳转(1T). 37 "POP A " //1T,出栈 38 ); 39 } 40 //延时nms 41 //为保证准确度,nms不要大于16640. 42 void delay_ms(u32 nms) 43 { 44 u8 t; 45 if(nms>65) 46 { 47 t=nms/65; 48 while(t--)delay_us(65000); 49 nms=nms%65; 50 } 51 delay_us(nms*1000); 52 }
最后上主函数,这是调试的程序,乱的一笔233333
#include "stm8s.h" #include "stm8s_clk.h" #include "intrinsics.h" #include "stm8s_uart1.h" #include "uart.h" #include "sysclock.h" #include "delay.h" #include "pt6311.h" #include "led.h" #include "string.h" void Delay(u32 nCount); extern u8 RxBuffer[RxBufferSize]; extern u8 UART_RX_NUM; int main(void) { u8 len,i,t; //use this fuction to choose a clock SystemClock_Init(HSI_Clock); //hsi //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /*!<Set High speed internal clock */ Uart_Init(); //added delay_init(16);//@delay.c LED_Init();//@gpio.c __enable_interrupt(); printf(" System Clock Frequency is:%ld Hz ",CLK_GetClockFreq());//print the clock printf("vfd test "); Init_PT6311(); dspseg[0]=10;//temp dspseg[1]='h'; dspseg[2]='e';dspseg[3]='l'; dspseg[4]='l';dspseg[5]='o'; dspseg[6]='i';dspseg[7]='t'; dspseg[8]='s';dspseg[9]='m'; dspseg[10]='e';dspseg[11]='w'; dspseg[12]=CONT|ALL|2;//ui TransCoding(); OpenStrobe_PT6311(); WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (len=0;len<30;len++) { OpenStrobe_PT6311(); WriteByte_PT6311(CMD_AddressSetting|ADDR[len]); WriteByte_PT6311(dspbuf[len]); } OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DisplaySetting|0x08|0x07);//on 14/16 STB=1; while (1) { dspseg[1]=i/100; dspseg[2]=i/10%10; dspseg[3]=i%10; delay_ms(1000); TransCoding(); OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (len=0;len<30;len++) { OpenStrobe_PT6311(); WriteByte_PT6311(CMD_AddressSetting|ADDR[len]); WriteByte_PT6311(dspbuf[len]); } i++; if(UART_RX_NUM&0x80) { led=!led; len=UART_RX_NUM&0x3f;/*得到此次接收到的数据长度*/ printf(" What you have in put is: "); UART1_SendString(RxBuffer,len); UART1_SendByte(' '); if (strcmp("led",RxBuffer)==0) {printf("open led"); OpenStrobe_PT6311(); for (i=0;i<4;i++) { WriteByte_PT6311(CMD_DataSetting|0x01); WriteByte_PT6311(~(1<<i));//open led delay_ms(100); } for (i=0;i<4;i++) { WriteByte_PT6311(CMD_DataSetting|0x01); WriteByte_PT6311(~(0x4>>i));//open led delay_ms(100); } }else if (strcmp("ds",RxBuffer)==0) { OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (i=0;i<30;i++) { OpenStrobe_PT6311(); WriteByte_PT6311(CMD_AddressSetting|ADDR[i]); WriteByte_PT6311(dspbuf[i]); } OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DisplaySetting|0x08|0x07);//on 14/16 STB=1; }else if (strcmp("key",RxBuffer)==0) { OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DisplaySetting|0x07);//on 14/16 OpenStrobe_PT6311(); WriteByte_PT6311(CMD_DataSetting|0x02); t=ReadByte_PT6311(), printf("keyval %d",t); } //clr for (t=0;t<len;t++) RxBuffer[t]=0; UART_RX_NUM=0;//clr } } } void Delay(u32 nCount) { /* Decrement nCount value */ while (nCount != 0) { nCount--; } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval : None */ void assert_failed(u8* file, u32 line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d ", file, line) */ /* Infinite loop */ while (1) { } } #endif
没啥可说的,
用到我写的驱动,修改版的头文件实现按位操作io,原子哥的精确软件延时,串口调程序
详细驱动讲解,见另一篇博文 vfd(二)